/* * 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.modelgenerator.wsdl.ui.wizards.soap; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.Properties; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.datatools.connectivity.IConnectionProfile; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.teiid.core.designer.ModelerCoreException; import org.teiid.core.designer.util.StringUtilities; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.query.QueryValidator; import org.teiid.designer.core.types.DatatypeManager; import org.teiid.designer.core.util.NewModelObjectHelperManager; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.core.workspace.ModelWorkspaceItem; import org.teiid.designer.core.workspace.ModelWorkspaceManager; import org.teiid.designer.datatools.connection.ConnectionInfoHelper; import org.teiid.designer.datatools.connection.DataSourceConnectionHelper; import org.teiid.designer.datatools.connection.IConnectionInfoProvider; import org.teiid.designer.datatools.profiles.ws.IWSProfileConstants; import org.teiid.designer.datatools.ui.DatatoolsUiConstants; import org.teiid.designer.metamodels.relational.Column; import org.teiid.designer.metamodels.relational.Procedure; import org.teiid.designer.metamodels.relational.ProcedureParameter; import org.teiid.designer.metamodels.relational.ProcedureResult; import org.teiid.designer.metamodels.relational.RelationalFactory; import org.teiid.designer.metamodels.transformation.SqlTransformationMappingRoot; import org.teiid.designer.modelgenerator.wsdl.WSSoapConnectionInfoProvider; import org.teiid.designer.modelgenerator.wsdl.model.Operation; import org.teiid.designer.modelgenerator.wsdl.model.Port; import org.teiid.designer.modelgenerator.wsdl.ui.Messages; import org.teiid.designer.modelgenerator.wsdl.ui.ModelGeneratorWsdlUiConstants; import org.teiid.designer.modelgenerator.wsdl.ui.wizards.WSDLImportWizardManager; import org.teiid.designer.query.proc.wsdl.IWsdlAttributeInfo; import org.teiid.designer.runtime.spi.ITeiidServer; import org.teiid.designer.transformation.model.RelationalViewModelFactory; import org.teiid.designer.transformation.ui.wizards.file.FlatFileRelationalModelFactory; import org.teiid.designer.transformation.util.SqlMappingRootCache; import org.teiid.designer.transformation.util.TransformationHelper; import org.teiid.designer.transformation.util.TransformationMappingHelper; import org.teiid.designer.transformation.validation.TransformationValidator; import org.teiid.designer.ui.common.util.WidgetUtil; import org.teiid.designer.ui.editors.ModelEditorManager; import org.teiid.designer.ui.viewsupport.ModelUtilities; /** * @since 8.0 */ public class ImportWsdlProcessor { public static final RelationalFactory factory = RelationalFactory.eINSTANCE; public static final DatatypeManager datatypeManager = ModelerCore.getWorkspaceDatatypeManager(); public static final int DEFAULT_STRING_LENGTH = 4000; WSDLImportWizardManager importManager; ModelResource sourceModel; ModelResource viewModel; IStatus createStatus; Shell shell; RelationalViewModelFactory relationalFactory; FlatFileRelationalModelFactory relationalProcedureFactory; private static boolean isTransactionable = ModelerCore.getPlugin() != null; public ImportWsdlProcessor(WSDLImportWizardManager importManager, Shell shell) { super(); this.importManager = importManager; this.shell = shell; createStatus = Status.OK_STATUS; this.relationalFactory = new RelationalViewModelFactory(); this.relationalProcedureFactory = new FlatFileRelationalModelFactory(); } private void log(IStatus status) { ModelGeneratorWsdlUiConstants.UTIL.log(status); } public IStatus execute() { final WorkspaceModifyOperation op = new WorkspaceModifyOperation() { @Override public void execute( final IProgressMonitor theMonitor ) { theMonitor.beginTask(("Creating source model" + importManager.getSourceModelName()), 100); //$NON-NLS-1$ // Make sure models are found or created if they don't exist yet createStatus = initializeModels(theMonitor); if( createStatus.isOK() ) { createStatus = createSourceProcedures(theMonitor); } if( createStatus.isOK()) { createViewProcedures(theMonitor); } theMonitor.worked(50); if( createStatus.isOK() ) { handleCreateDataSource(); } theMonitor.done(); } }; try { new ProgressMonitorDialog(shell).run(false, true, op); } catch (final InterruptedException e) { } catch (final InvocationTargetException e) { log( new Status(IStatus.ERROR, ModelGeneratorWsdlUiConstants.PLUGIN_ID, e.getTargetException().getMessage(), e)); } catch (final Exception err) { Throwable t = err; if (err instanceof InvocationTargetException) { t = err.getCause(); } WidgetUtil.showError(t); } return createStatus; } private IStatus initializeModels(IProgressMonitor theMonitor) { // Check if source and view models exist try { if( importManager.sourceModelExists() ) { // find and set source model resource IPath modelPath = this.importManager.getSourceModelLocation().getFullPath() .append(this.importManager.getSourceModelName()); ModelWorkspaceItem item = ModelWorkspaceManager.getModelWorkspaceManager().findModelWorkspaceItem(modelPath, IResource.FILE); IFile modelFile = (IFile)item.getCorrespondingResource(); this.sourceModel = ModelUtilities.getModelResourceForIFile(modelFile, false); addConnectionProfileInfoToSourceModel(theMonitor, true); } else { // Create Source Model createSourceModelInTxn(theMonitor); } if( importManager.viewModelExists() ) { // Find and set view model resource IPath modelPath = this.importManager.getViewModelLocation().getFullPath().append(this.importManager.getViewModelName()); ModelWorkspaceItem item = ModelWorkspaceManager.getModelWorkspaceManager().findModelWorkspaceItem(modelPath, IResource.FILE); IFile modelFile = (IFile)item.getCorrespondingResource(); this.viewModel = ModelUtilities.getModelResourceForIFile(modelFile, false); } else { // Create view model createViewModelInTxn(theMonitor); } } catch (ModelWorkspaceException ex) { return new Status(IStatus.ERROR, ModelGeneratorWsdlUiConstants.PLUGIN_ID, ex.getMessage()); } catch (InvocationTargetException ex) { return new Status(IStatus.ERROR, ModelGeneratorWsdlUiConstants.PLUGIN_ID, ex.getMessage()); } return Status.OK_STATUS; } private IStatus createSourceModelInTxn(IProgressMonitor theMonitor) { boolean requiredStart = ModelerCore.startTxn(true, true, "Import Teiid Metadata Create Source Model", this); //$NON-NLS-1$ boolean succeeded = false; try { sourceModel = relationalFactory.createRelationalModel( this.importManager.getSourceModelLocation(), this.importManager.getSourceModelName() ); theMonitor.worked(10); addConnectionProfileInfoToSourceModel(theMonitor, false); String jndiName = importManager.getJBossJndiName(); if( !StringUtilities.isEmpty(jndiName) ) { ConnectionInfoHelper helper = new ConnectionInfoHelper(); helper.setJNDIName(sourceModel, jndiName); } theMonitor.subTask("Saving Source Model" + sourceModel.getItemName()); //$NON-NLS-1$ try { ModelUtilities.saveModelResource(sourceModel, theMonitor, false, this); } catch (Exception e) { throw new InvocationTargetException(e); } theMonitor.worked(10); if( createStatus.isOK() && sourceModel != null ) { ModelEditorManager.openInEditMode(sourceModel, true, org.teiid.designer.ui.UiConstants.ObjectEditor.IGNORE_OPEN_EDITOR); } succeeded = true; } catch (Exception e) { String message = NLS.bind(Messages.Error_Creating_0_Model_1_FromWsdl, "view", this.importManager.getSourceModelName()); //$NON-NLS-1$ IStatus status = new Status(IStatus.ERROR, ModelGeneratorWsdlUiConstants.PLUGIN_ID, message, e); log(status); MessageDialog.openError(shell, message, e.getMessage()); return status; } finally { // if we started the txn, commit it. if (requiredStart) { if (succeeded) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } } theMonitor.worked(10); return Status.OK_STATUS; } protected void addConnectionProfileInfoToSourceModel(IProgressMonitor monitor, boolean doSave) throws InvocationTargetException { IConnectionProfile profile = this.importManager.getConnectionProfile(); if( monitor == null ) { return; } // Inject the connection profile info into the model if (profile != null) { try { Properties props = profile.getBaseProperties(); String defaultServiceMode = this.importManager.getTranslatorDefaultServiceMode(); if( defaultServiceMode.equalsIgnoreCase(WSDLImportWizardManager.MESSAGE ) ) { props.put(IWSProfileConstants.SOAP_SERVICE_MODE, WSDLImportWizardManager.MESSAGE); } else { props.put(IWSProfileConstants.SOAP_SERVICE_MODE, WSDLImportWizardManager.PAYLOAD); } //The CP doesn't allow changing the BINDING, so the default will always return SOAP11 // If this wizard returns SOAP12, then we need to replace the binding String defaultBinding = this.importManager.getTranslatorDefaultBinding(); if( defaultBinding.equalsIgnoreCase(Port.SOAP12) ) { props.put(IWSProfileConstants.SOAP_BINDING, Port.SOAP12); } profile.setBaseProperties(props); IConnectionInfoProvider provider = new WSSoapConnectionInfoProvider(); provider.setConnectionInfo(sourceModel, profile); } catch (ModelerCoreException ex) { log(new Status(IStatus.ERROR, ModelGeneratorWsdlUiConstants.PLUGIN_ID, ex.getMessage(), ex)); } if( doSave ) { try { ModelUtilities.saveModelResource(sourceModel, monitor, false, this); } catch (Exception e) { throw new InvocationTargetException(e); } } } } private IStatus createSourceProcedures(IProgressMonitor monitor) { try { relationalProcedureFactory.addMissingProcedure(this.sourceModel, FlatFileRelationalModelFactory.INVOKE); } catch (ModelerCoreException ex) { IStatus status = new Status(IStatus.ERROR, ModelGeneratorWsdlUiConstants.PLUGIN_ID, ex.getMessage(), ex); log(status); return status; } return Status.OK_STATUS; } private IStatus createViewModelInTxn(IProgressMonitor monitor) { boolean requiredStart = ModelerCore.startTxn(true, true, "Create WSDL Import View Model", this); //$NON-NLS-1$ boolean succeeded = false; try { monitor.subTask("Creating View Procedures" + this.importManager.getViewModelName()); //$NON-NLS-1$ this.viewModel = relationalFactory.createRelationalViewModel( this.importManager.getViewModelLocation(), this.importManager.getViewModelName() ); monitor.worked(40); if( createStatus.isOK() && sourceModel != null ) { try { ModelUtilities.saveModelResource(viewModel, monitor, false, this); } catch (Exception e) { throw new InvocationTargetException(e); } } monitor.worked(10); if( createStatus.isOK() && viewModel != null ) { ModelEditorManager.openInEditMode(viewModel, true, org.teiid.designer.ui.UiConstants.ObjectEditor.IGNORE_OPEN_EDITOR); } succeeded = true; } catch (Exception e) { String message = NLS.bind(Messages.Error_Creating_0_Model_1_FromWsdl, "view", this.importManager.getViewModelName()); //$NON-NLS-1$ IStatus status = new Status(IStatus.ERROR, ModelGeneratorWsdlUiConstants.PLUGIN_ID, message, e); log(status); MessageDialog.openError(shell, message, e.getMessage()); return status; } finally { // if we started the txn, commit it. if (requiredStart) { if (succeeded) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } } return Status.OK_STATUS; } private void createViewProcedures(IProgressMonitor monitor) { // Assume the source and view models are created removeOverriddenProcedures(); for( Operation operation : this.importManager.getSelectedOperations()) { ProcedureGenerator generator = this.importManager.getProcedureGenerator(operation); processGenerator(generator); } } /* * Deletes all existing procedures tagged for being overridden */ private void removeOverriddenProcedures() { for( Operation operation : this.importManager.getSelectedOperations()) { ProcedureGenerator generator = this.importManager.getProcedureGenerator(operation); if( generator.doOverwriteExistingProcedures() ) { Collection<EObject> deleteList = new ArrayList<EObject>(); if( generator.wrapperExists() ) { EObject wrapper = ModelUtilities.getExistingEObject( this.importManager.getViewModelLocation().getFullPath().toString(), this.importManager.getViewModelName(), generator.getWrapperProcedureName()); if( wrapper != null ) { deleteList.add(wrapper); } } EObject request = ModelUtilities.getExistingEObject( this.importManager.getViewModelLocation().getFullPath().toString(), this.importManager.getViewModelName(), generator.getRequestProcedureName()); if( request != null ) { deleteList.add(request); } EObject response = ModelUtilities.getExistingEObject( this.importManager.getViewModelLocation().getFullPath().toString(), this.importManager.getViewModelName(), generator.getResponseProcedureName()); if( response != null ) { deleteList.add(response); } if( !deleteList.isEmpty() ) { try { ModelerCore.getModelEditor().delete(deleteList); } catch (ModelerCoreException ex) { ModelGeneratorWsdlUiConstants.UTIL.log(ex); } } } } } private void processGenerator(ProcedureGenerator generator) { try { // Create the Request Procedure createViewRequestProcedure(this.viewModel, (RequestInfo)generator.getRequestInfo()); // Create the Response ProceduregetWrapperProcedureSqlString createViewResponseProcedure(this.viewModel, (ResponseInfo)generator.getResponseInfo()); // Create the wrapper procedure createViewWrapperProcedure(this.viewModel, generator); } catch (ModelWorkspaceException ex) { ModelGeneratorWsdlUiConstants.UTIL.log(ex); } catch (ModelerCoreException ex) { ModelGeneratorWsdlUiConstants.UTIL.log(ex); } } public void createViewRequestProcedure(ModelResource modelResource, RequestInfo info) throws ModelerCoreException { final EObject STRING_DATATYPE = datatypeManager.findDatatype("string"); //$NON-NLS-1$ // Create a Procedure using the text file name Procedure procedure = factory.createProcedure(); procedure.setName(info.getProcedureName()); addValue(modelResource, procedure, modelResource.getEmfResource().getContents()); NewModelObjectHelperManager.helpCreate(procedure, null); for(ColumnInfo columnInfo : info.getHeaderColumnInfoList()) { ProcedureParameter parameter = factory.createProcedureParameter(); parameter.setName(columnInfo.getName()); EObject type = datatypeManager.findDatatype(columnInfo.getDatatype()); if( type != null ) { parameter.setType(type); } if( columnInfo.getDatatype().equalsIgnoreCase("string")) { //$NON-NLS-1$ parameter.setLength(DEFAULT_STRING_LENGTH); } parameter.setProcedure(procedure); } for(ColumnInfo columnInfo : info.getBodyColumnInfoList() ) { ProcedureParameter parameter = factory.createProcedureParameter(); parameter.setName(columnInfo.getName()); EObject type = datatypeManager.findDatatype(columnInfo.getDatatype()); if( type != null ) { parameter.setType(type); } if( columnInfo.getDatatype().equalsIgnoreCase("string")) { //$NON-NLS-1$ parameter.setLength(DEFAULT_STRING_LENGTH); } parameter.setProcedure(procedure); for( IWsdlAttributeInfo attrInfo : columnInfo.getAttributeInfoArray() ) { ProcedureParameter attributeParam = factory.createProcedureParameter(); attributeParam.setName(attrInfo.getName()); attributeParam.setType(STRING_DATATYPE); attributeParam.setLength(DEFAULT_STRING_LENGTH); attributeParam.setProcedure(procedure); } } ProcedureResult result = factory.createProcedureResult(); result.setName("Result"); //$NON-NLS-1$ result.setProcedure(procedure); Column column_1 = factory.createColumn(); column_1.setName("xml_out"); //$NON-NLS-1$ EObject blobType = datatypeManager.findDatatype("XMLLiteral"); //$NON-NLS-1$ if( blobType != null) { column_1.setType(blobType); } addValue(result, column_1, result.getColumns()); String sqlString = info.getSqlString(new Properties()); SqlTransformationMappingRoot tRoot = (SqlTransformationMappingRoot)TransformationHelper.getTransformationMappingRoot(procedure); TransformationHelper.setSelectSqlString(tRoot, sqlString, false, this); TransformationMappingHelper.reconcileMappingsOnSqlChange(tRoot, this); QueryValidator validator = new TransformationValidator(tRoot); validator.validateSql(sqlString, QueryValidator.SELECT_TRNS, true); } public void createViewResponseProcedure(ModelResource modelResource, ResponseInfo info) throws ModelerCoreException { // Create a Procedure using the text file name Procedure procedure = factory.createProcedure(); procedure.setName(info.getProcedureName()); addValue(modelResource, procedure, modelResource.getEmfResource().getContents()); ProcedureParameter parameter = factory.createProcedureParameter(); parameter.setName("xml_in"); //$NON-NLS-1$ EObject stringType = datatypeManager.findDatatype("XMLLiteral"); //$NON-NLS-1$ parameter.setType(stringType); parameter.setProcedure(procedure); ProcedureResult result = factory.createProcedureResult(); result.setName("Result"); //$NON-NLS-1$ result.setProcedure(procedure); for(ColumnInfo columnInfo : info.getBodyColumnInfoList() ) { Column column = factory.createColumn(); column.setName(columnInfo.getName()); EObject type = datatypeManager.findDatatype(columnInfo.getDatatype()); if( type != null) { column.setType(type); if( columnInfo.getDatatype().equalsIgnoreCase("string")) { //$NON-NLS-1$ column.setLength(DEFAULT_STRING_LENGTH); } } addValue(result, column, result.getColumns()); } NewModelObjectHelperManager.helpCreate(procedure, null); String sqlString = info.getSqlString(new Properties()); SqlTransformationMappingRoot tRoot = (SqlTransformationMappingRoot)TransformationHelper.getTransformationMappingRoot(procedure); TransformationHelper.setSelectSqlString(tRoot, sqlString, false, this); TransformationMappingHelper.reconcileMappingsOnSqlChange(tRoot, this); QueryValidator validator = new TransformationValidator(tRoot); validator.validateSql(sqlString, QueryValidator.SELECT_TRNS, true); } private void createViewWrapperProcedure(ModelResource modelResource, ProcedureGenerator generator) throws ModelerCoreException { final EObject STRING_DATATYPE = datatypeManager.findDatatype("string"); //$NON-NLS-1$ // Create a Procedure using the text file name Procedure procedure = factory.createProcedure(); procedure.setName(generator.getWrapperProcedureName()); addValue(modelResource, procedure, modelResource.getEmfResource().getContents()); for(ColumnInfo columnInfo : generator.getRequestInfo().getHeaderColumnInfoList() ) { ProcedureParameter parameter = factory.createProcedureParameter(); parameter.setName(columnInfo.getName()); EObject type = datatypeManager.findDatatype(columnInfo.getDatatype()); if( type != null ) { parameter.setType(type); if( columnInfo.getDatatype().equalsIgnoreCase("string")) { //$NON-NLS-1$ parameter.setLength(DEFAULT_STRING_LENGTH); } } parameter.setProcedure(procedure); } for(ColumnInfo columnInfo : generator.getRequestInfo().getBodyColumnInfoList() ) { ProcedureParameter parameter = factory.createProcedureParameter(); parameter.setName(columnInfo.getName()); EObject type = datatypeManager.findDatatype(columnInfo.getDatatype()); if( type != null ) { parameter.setType(type); if( columnInfo.getDatatype().equalsIgnoreCase("string")) { //$NON-NLS-1$ parameter.setLength(DEFAULT_STRING_LENGTH); } } parameter.setProcedure(procedure); for( IWsdlAttributeInfo attrInfo : columnInfo.getAttributeInfoArray() ) { ProcedureParameter attributeParam = factory.createProcedureParameter(); attributeParam.setName(attrInfo.getName()); attributeParam.setType(STRING_DATATYPE); attributeParam.setLength(DEFAULT_STRING_LENGTH); attributeParam.setProcedure(procedure); } } // Create Result set with same columns and types as Response procedure ProcedureResult result = factory.createProcedureResult(); result.setName("Result"); //$NON-NLS-1$ result.setProcedure(procedure); for(ColumnInfo columnInfo : generator.getResponseInfo().getBodyColumnInfoList() ) { Column column = factory.createColumn(); column.setName(columnInfo.getName()); EObject type = datatypeManager.findDatatype(columnInfo.getDatatype()); if( type != null) { column.setType(type); if( columnInfo.getDatatype().equalsIgnoreCase("string")) { //$NON-NLS-1$ column.setLength(DEFAULT_STRING_LENGTH); } } addValue(result, column, result.getColumns()); } NewModelObjectHelperManager.helpCreate(procedure, null); String sqlString = generator.getWrapperProcedureSqlString(new Properties()); SqlTransformationMappingRoot tRoot = (SqlTransformationMappingRoot)TransformationHelper.getTransformationMappingRoot(procedure); TransformationHelper.setSelectSqlString(tRoot, sqlString, false, this); SqlMappingRootCache.setStatus(tRoot, QueryValidator.SELECT_TRNS, null); TransformationMappingHelper.reconcileMappingsOnSqlChange(tRoot, this); QueryValidator validator = new TransformationValidator(tRoot); validator.validateSql(sqlString, QueryValidator.SELECT_TRNS, true); } protected void addValue(final Object owner, final Object value, EList feature) throws ModelerCoreException { if( isTransactionable ) { ModelerCore.getModelEditor().addValue(owner, value, feature); } else { feature.add(value); } } protected void handleCreateDataSource() { if( importManager.doCreateDataSource() && DataSourceConnectionHelper.isServerConnected() ) { ITeiidServer teiidServer = DataSourceConnectionHelper.getServer(); String dsName = importManager.getJBossJndiName(); String jndiName = importManager.getJBossJndiName(); DataSourceConnectionHelper helper = new DataSourceConnectionHelper(this.sourceModel, importManager.getConnectionProfile()); Properties connProps = helper.getModelConnectionProperties(); String dsType = helper.getDataSourceType(); try { teiidServer.getOrCreateDataSource(dsName, jndiName, dsType, connProps); } catch (Exception e) { DatatoolsUiConstants.UTIL.log(e); } } } }