/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.transformation.ui.wizards.functions; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Display; import org.teiid.core.designer.ModelerCoreException; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.extension.properties.ModelExtensionPropertyDefinition; import org.teiid.designer.metamodels.function.FunctionParameter; import org.teiid.designer.metamodels.function.FunctionPlugin; import org.teiid.designer.metamodels.function.ReturnParameter; import org.teiid.designer.metamodels.function.ScalarFunction; import org.teiid.designer.metamodels.function.extension.FunctionModelExtensionConstants; import org.teiid.designer.relational.RelationalConstants; import org.teiid.designer.relational.model.RelationalModel; import org.teiid.designer.relational.model.RelationalParameter; import org.teiid.designer.relational.model.RelationalViewProcedure; import org.teiid.designer.transformation.model.RelationalViewModelFactory; import org.teiid.designer.transformation.ui.UiConstants; import org.teiid.designer.ui.editors.ModelEditor; import org.teiid.designer.ui.editors.ModelEditorManager; public class ConvertFunctionModelHelper { private static String UDF_JAR_PROP_KEY = "udfJarPath"; //$NON-NLS-1$ private static String RETURN_PARAM_STR = "return_parameter"; //$NON-NLS-1$ private static Status OK_TO_FINISH_STATUS = new Status(IStatus.OK, UiConstants.PLUGIN_ID, UiConstants.Util.getString("ConvertFunctionModelHelper.okToFinishMessage")); //$NON-NLS-1$ private ModelResource functionModel; private List<ScalarFunction> scalarFunctions; private RelationalViewProcedure[] virtualFunctions; private Set<RelationalViewProcedure> selectedProcedures; private ModelResource targetModel; private IStatus currentStatus; public ConvertFunctionModelHelper(ModelResource functionModel) { this(); this.functionModel = functionModel; loadFunctions(); validate(); } public ConvertFunctionModelHelper() { this.scalarFunctions = new ArrayList<ScalarFunction>(); selectedProcedures = new HashSet<RelationalViewProcedure>(); } public ModelResource getFunctionModel() { return functionModel; } public List<ScalarFunction> getScalarFunctions() { return scalarFunctions; } public RelationalViewProcedure[] getVirtualFunctions() { return virtualFunctions; } public ModelResource getTargetModel() { return targetModel; } public void setTargetModel(ModelResource targetModel) { this.targetModel = targetModel; validate(); } private void loadFunctions() { // get scalar functions try { @SuppressWarnings("unchecked") List<EObject> modelChildren = functionModel.getAllRootEObjects(); scalarFunctions = new ArrayList<ScalarFunction>(); for( EObject child : modelChildren ) { if( child instanceof ScalarFunction ) { scalarFunctions.add((ScalarFunction)child); } } } catch (ModelWorkspaceException e) { // TODO Auto-generated catch block e.printStackTrace(); } List<RelationalViewProcedure> viewProcedures = new ArrayList<RelationalViewProcedure>(); for( ScalarFunction sf : scalarFunctions ) { RelationalViewProcedure relationalProcedure = new RelationalViewProcedure(sf.getName()); relationalProcedure.setFunction(true); relationalProcedure.setFunctionCategory(sf.getCategory()); relationalProcedure.setJavaClassName(sf.getInvocationClass()); relationalProcedure.setJavaMethodName(sf.getInvocationMethod()); String jarPathPropId = ModelExtensionPropertyDefinition.Utils.getPropertyId(FunctionModelExtensionConstants.NAMESPACE_PROVIDER, UDF_JAR_PROP_KEY); String jarPath = FunctionPlugin.getExtensionProperty(sf, jarPathPropId); relationalProcedure.setUdfJarPath(jarPath); // look for description/annotation String desc = getDescription(sf); if( desc != null ) { relationalProcedure.setDescription(desc); } for (Object param : sf.getInputParameters() ) { FunctionParameter fp = (FunctionParameter)param; RelationalParameter udfParam = new RelationalParameter(fp.getName()); udfParam.setDirection(RelationalConstants.DIRECTION.IN); udfParam.setDatatype(fp.getType()); desc = getDescription(fp); if( desc != null ) { udfParam.setDescription(desc); } relationalProcedure.addParameter(udfParam); } ReturnParameter returnParam = sf.getReturnParameter(); if( returnParam != null ) { RelationalParameter param = new RelationalParameter(RETURN_PARAM_STR); //$NON-NLS-1$ param.setDatatype(returnParam.getType()); param.setDirection(RelationalConstants.DIRECTION.RETURN); desc = getDescription(returnParam); if( desc != null ) { param.setDescription(desc); } relationalProcedure.addParameter(param); } viewProcedures.add(relationalProcedure); } virtualFunctions = viewProcedures.toArray( new RelationalViewProcedure[viewProcedures.size()]); } public void selectFunction(RelationalViewProcedure procedure) { // Add to hash set selectedProcedures.add(procedure); validate(); } public void deselectFunction(RelationalViewProcedure procedure) { // Add to hash set selectedProcedures.remove(procedure); validate(); } public void clearFunctions() { selectedProcedures.clear(); validate(); } public IStatus generateProcedures() { IStatus status = Status.OK_STATUS; status = createProceduresInTxn(); return status; } private IStatus createProceduresInTxn() { RelationalModel relModel = new RelationalModel("dummy"); //$NON-NLS-1$ for( RelationalViewProcedure proc : selectedProcedures) { relModel.addChild(proc); } boolean requiredStart = ModelerCore.startTxn(true, true, "Create Virtual Procedures From Legacy Functions", this); //$NON-NLS-1$ boolean succeeded = false; try { ModelEditor editor = ModelEditorManager.getModelEditorForFile((IFile)targetModel.getCorrespondingResource(), true); if (editor != null) { boolean isDirty = editor.isDirty(); RelationalViewModelFactory factory = new RelationalViewModelFactory(); factory.setAllowsZeroStringLength(true); factory.build(targetModel, relModel, new NullProgressMonitor()); if (!isDirty && editor.isDirty()) { editor.doSave(new NullProgressMonitor()); } succeeded = true; } } catch (Exception e) { MessageDialog.openError(Display.getCurrent().getActiveShell(), UiConstants.Util.getString("ConvertFunctionModelHelper.buildErrorTitle"), e.getMessage()); //$NON-NLS-1$ IStatus errorStatus = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, UiConstants.Util.getString("ConvertFunctionModelHelper.buildErrorMessage"), e); //$NON-NLS-1$ UiConstants.Util.log(errorStatus); return errorStatus; } finally { // if we started the txn, commit it. if (requiredStart) { if (succeeded) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } } return Status.OK_STATUS; } private void validate() { // Check to see if // 1) One ore more functions exist in the function model if( scalarFunctions.isEmpty() ) { currentStatus = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, UiConstants.Util.getString("ConvertFunctionModelHelper.noFunctionsMessage")); //$NON-NLS-1$ return; } // 2) Target model is defined and exists if( targetModel == null ) { currentStatus = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, UiConstants.Util.getString("ConvertFunctionModelHelper.targetModelUndefined")); //$NON-NLS-1$ return; } // 3) one or more procedures are selected for export if( selectedProcedures.isEmpty() ) { currentStatus = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, UiConstants.Util.getString("ConvertFunctionModelHelper.noFunctionsSelected")); //$NON-NLS-1$ return; } currentStatus = OK_TO_FINISH_STATUS; } public IStatus getStatus() { return currentStatus; } private String getDescription(EObject eObj) { String desc = null; try { desc = ModelerCore.getModelEditor().getDescription(eObj); } catch (ModelerCoreException e) { UiConstants.Util.log(IStatus.ERROR, e, e.getMessage()); } return desc; } }