/* * 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.ddl; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.resource.Resource; import org.jdom.Document; import org.jdom.output.XMLOutputter; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.common.xml.JdomHelper; import org.teiid.designer.core.ModelEditor; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.resource.EmfResource; import org.teiid.designer.core.util.ModelContents; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.core.workspace.ModelWorkspaceSelections; import org.teiid.designer.core.xslt.Style; import org.teiid.designer.core.xslt.XsltTransform; /** * DdlWriterImpl * * @since 8.0 */ public class DdlWriterImpl implements DdlWriter { public static final int WRITTEN_WITH_NO_PROBLEMS = 4001; public static final int UNABLE_TO_GET_EMF_RESOURCE = 4002; public static final int WRITE_WITH_WARNINGS = 4003; public static final int WRITE_WITH_ERRORS = 4004; public static final int WRITE_WITH_WARNINGS_AND_ERRORS = 4005; public static final int WRITE_WITH_NO_WARNINGS_AND_ERRORS = 4006; public static final int UNEXPECTED_EXCEPTION = 4007; public static final int XSLT_PROBLEMS = 4008; public static final int UNEXPECTED_IO_EXCEPTION = 4009; public static final int TRANSFORMER_CONFIGURATION_EXCEPTION = 4010; public static final int ERROR_COMPUTING_RESOURCES_TO_BE_EXPORTED = 4011; /** The options; never null */ private final DdlOptions options; /** * Construct an instance of DdlWriterImpl. */ public DdlWriterImpl() { super(); this.options = new DdlOptionsImpl(); } /** * Get the options that this writer is currently using * * @return the options; never null * @see DdlWriter#getOptions() */ @Override public DdlOptions getOptions() { return options; } // /** // * Set the options that this writer should use // * @param options the new options; may not be null // * @see DdlWriter#setOptions(DdlOptions) // */ // public void setOptions(final DdlOptions options) { // CoreArgCheck.isNotNull(options); // this.options = options; // } /** * @see DdlWriter#write(Resource, OutputStream, IProgressMonitor) */ @Override public IStatus write( final Resource emfResource, final String modelName, final String modelFilename, final OutputStream stream, final IProgressMonitor monitor ) { CoreArgCheck.isNotNull(emfResource); CoreArgCheck.isNotNull(stream); CoreArgCheck.isNotNull(modelName); final ModelContents contents = emfResource instanceof EmfResource ? ((EmfResource)emfResource).getModelContents() : new ModelContents( emfResource); final ModelWrapper wrapper = new ModelWrapper(emfResource, contents, null, modelName, modelFilename); final IntermediateFormat formatter = new IntermediateFormat(wrapper, this.options, monitor); return doWrite(formatter, stream, monitor != null ? monitor : new NullProgressMonitor()); } /** * @see DdlWriter#write(ModelResource, OutputStream, IProgressMonitor) */ @Override public IStatus write( final ModelResource model, final OutputStream stream, final IProgressMonitor monitor ) { CoreArgCheck.isNotNull(model); CoreArgCheck.isNotNull(stream); // Get the emf resource from the model ... try { final Resource emfResource = model.getEmfResource(); final ModelEditor editor = ModelerCore.getModelEditor(); final String modelName = editor.getModelName(model); final String modelFilename = model.getPath().toString(); final ModelContents contents = ModelContents.getModelContents(model); final ModelWrapper wrapper = new ModelWrapper(emfResource, contents, null, modelName, modelFilename); final IntermediateFormat formatter = new IntermediateFormat(wrapper, this.options, monitor); return doWrite(formatter, stream, monitor != null ? monitor : new NullProgressMonitor()); } catch (ModelWorkspaceException e) { final int code = UNABLE_TO_GET_EMF_RESOURCE; final Object[] params = new Object[] {model.getPath()}; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.Error_getting_EMF_resource", params); //$NON-NLS-1$ return new Status(IStatus.ERROR, DdlPlugin.PLUGIN_ID, code, msg, e); } } /** * @see DdlWriter#write(ModelWorkspaceSelections, OutputStream, IProgressMonitor) */ @Override public IStatus write( final ModelWorkspaceSelections selections, final OutputStream stream, final IProgressMonitor monitor ) { CoreArgCheck.isNotNull(selections); CoreArgCheck.isNotNull(selections.getModelWorkspaceView()); CoreArgCheck.isNotNull(stream); // Get the selected objects ... List modelResources = null; try { modelResources = selections.getSelectedOrPartiallySelectedModelResources(); } catch (ModelWorkspaceException e) { final int code = ERROR_COMPUTING_RESOURCES_TO_BE_EXPORTED; return new Status(IStatus.ERROR, DdlPlugin.PLUGIN_ID, code, e.getMessage(), e); } // Create a ModelWrapper for each resource ... final List wrappers = new LinkedList(); final Iterator iter = modelResources.iterator(); while (iter.hasNext()) { final ModelResource modelResource = (ModelResource)iter.next(); final IPath modelPath = modelResource.getPath(); try { final Resource emfResource = modelResource.getEmfResource(); final ModelEditor editor = ModelerCore.getModelEditor(); final String modelName = editor.getModelName(modelResource); final String modelFilename = modelPath.toString(); final ModelContents contents = ModelContents.getModelContents(modelResource); final ModelWrapper wrapper = new ModelWrapper(emfResource, contents, selections, modelName, modelFilename); wrappers.add(wrapper); } catch (ModelWorkspaceException e) { final int code = UNABLE_TO_GET_EMF_RESOURCE; final Object[] params = new Object[] {modelPath}; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.Error_getting_EMF_resource", params); //$NON-NLS-1$ return new Status(IStatus.ERROR, DdlPlugin.PLUGIN_ID, code, msg, e); } } // Construct the formatter and write the document ... final IntermediateFormat formatter = new IntermediateFormat(wrappers, this.options, monitor); return doWrite(formatter, stream, monitor != null ? monitor : new NullProgressMonitor()); } /** * Method that actually performs the DDL writing. * * @param emfResource the {@link org.teiid.designer.metamodels.relational.RelationalPackage relational} EMF resource that contains * the model to be written out; may not be null * @param modelContents the ModelContents object to use; may not be null * @param stream the stream to which the DDL is to be written; may not be null * @param problems the list to which problems (e.g., {@link IStatus} instances) should be written * @param monitor the monitor the should be used; never null * @return a status of the process with any {@link IStatus#WARNING warnings}, {@link IStatus#ERROR errors} or * {@link IStatus#INFO information messages}, or which will be {@link IStatus#isOK() marked as OK} if there were no * warnings, errors or other messages. */ protected IStatus doWrite( final IntermediateFormat formatter, final OutputStream stream, final IProgressMonitor monitor ) { CoreArgCheck.isNotNull(formatter); CoreArgCheck.isNotNull(stream); // Start the progress monitor tasks ... final String taskName = DdlPlugin.Util.getString("DdlWriterImpl.ProgressMonitor_main_task_name"); //$NON-NLS-1$ final int unitsPerPhase = 100; final int numUnits = 6 * unitsPerPhase; // 6 phases, 100 units each monitor.beginTask(null, numUnits); monitor.setTaskName(taskName); final List problems = new ArrayList(); final String PLUGINID = DdlPlugin.PLUGIN_ID; // Write the DDL ... try { // Phase 1: Create the intermediate XML document ... final Document intDoc = formatter.createDocument(); // Phase 2: Transform the intermediate XML document using the stylesheet ... final Style style = this.options.getStyle(); if (style != null) { final XsltTransform xform = new XsltTransform(style); xform.transform(intDoc, stream); } else { // Write the intermediate form out to the stream ... XMLOutputter outputter = new XMLOutputter(JdomHelper.getFormat(" ", true)); //$NON-NLS-1$ outputter.output(intDoc, stream); } } catch (TransformerConfigurationException e) { final int code = TRANSFORMER_CONFIGURATION_EXCEPTION; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.Error_while_initializing_and_configuring_XSLT_transformer"); //$NON-NLS-1$ final Status status = new Status(IStatus.ERROR, PLUGINID, code, msg, e); problems.add(status); } catch (IOException e) { final int code = UNEXPECTED_IO_EXCEPTION; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.Unexpected_I/O_exception"); //$NON-NLS-1$ final Status status = new Status(IStatus.ERROR, PLUGINID, code, msg, e); problems.add(status); } catch (TransformerException e) { final int code = XSLT_PROBLEMS; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.Error_while_transforming_the_model_into_DDL"); //$NON-NLS-1$ final Status status = new Status(IStatus.ERROR, PLUGINID, code, msg, e); problems.add(status); } catch (Throwable e) { final int code = UNEXPECTED_EXCEPTION; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.Unexpected_exception"); //$NON-NLS-1$ final Status status = new Status(IStatus.ERROR, PLUGINID, code, msg, e); problems.add(status); } finally { monitor.done(); } // Put all of the problems into a single IStatus ... IStatus resultStatus = null; if (problems.isEmpty()) { final int code = WRITTEN_WITH_NO_PROBLEMS; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.completed"); //$NON-NLS-1$ final IStatus status = new Status(IStatus.OK, PLUGINID, code, msg, null); resultStatus = status; } else if (problems.size() == 1) { resultStatus = (IStatus)problems.get(0); } else { // There were problems, so determine whether there were warnings and errors ... int numErrors = 0; int numWarnings = 0; final Iterator iter = problems.iterator(); while (iter.hasNext()) { final IStatus aStatus = (IStatus)iter.next(); if (aStatus.getSeverity() == IStatus.WARNING) { ++numWarnings; } else if (aStatus.getSeverity() == IStatus.ERROR) { ++numErrors; } } // Create the final status ... final IStatus[] statusArray = (IStatus[])problems.toArray(new IStatus[problems.size()]); if (numWarnings != 0 && numErrors == 0) { final int code = WRITE_WITH_WARNINGS; final Object[] params = new Object[] {new Integer(numWarnings)}; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.warnings", params); //$NON-NLS-1$ resultStatus = new MultiStatus(PLUGINID, code, statusArray, msg, null); } else if (numWarnings == 0 && numErrors != 0) { final int code = WRITE_WITH_ERRORS; final Object[] params = new Object[] {new Integer(numErrors)}; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.errors", params); //$NON-NLS-1$ resultStatus = new MultiStatus(PLUGINID, code, statusArray, msg, null); } else if (numWarnings != 0 && numErrors != 0) { final int code = WRITE_WITH_WARNINGS_AND_ERRORS; final Object[] params = new Object[] {new Integer(numWarnings), new Integer(numErrors)}; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.warnings_and_errors", params); //$NON-NLS-1$ resultStatus = new MultiStatus(PLUGINID, code, statusArray, msg, null); } else { final int code = WRITE_WITH_NO_WARNINGS_AND_ERRORS; final String msg = DdlPlugin.Util.getString("DdlWriterImpl.no_warnings_or_errors"); //$NON-NLS-1$ resultStatus = new MultiStatus(PLUGINID, code, statusArray, msg, null); } } return resultStatus; } }