package org.teiid.designer.transformation.ui.teiidddl; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.widgets.Display; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.core.ModelEditor; import org.teiid.designer.core.ModelerCore; 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.transformation.ddl.TeiidModelToDdlGenerator; import org.teiid.designer.transformation.ui.UiConstants; import org.teiid.designer.transformation.ui.UiPlugin; import org.teiid.designer.ui.common.util.WidgetUtil; public class TeiidDdlExporter { 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; public static boolean DEFAULT_USE_NAME_IN_SOURCE = true; public static boolean DEFAULT_USE_NATIVE_TYPE = false; public static ExportChoice CLIPBOARD_TYPE = ExportChoice.CLIPBOARD; public static ExportChoice FILE_TYPE = ExportChoice.FILE; public static enum ExportChoice { CLIPBOARD("Clipboard"), //$NON-NLS-1$ FILE("To File"); //$NON-NLS-1$ private final String label; private ExportChoice(String label) { this.label = label; } public String getLabel() { return label; } } private boolean nameInSourceUsed; private boolean nativeTypeUsed; private ModelResource modelResource; private File ddlFile; private ExportChoice exportType = ExportChoice.CLIPBOARD; private static Clipboard CLIPBOARD; private IStatus writeStatus; private IStatus OK_STATUS = new Status(IStatus.OK, UiPlugin.PLUGIN_ID, "Click Finish to export"); /** * Construct an instance of DdlOptionsImpl. * */ public TeiidDdlExporter() { super(); this.nameInSourceUsed = DEFAULT_USE_NAME_IN_SOURCE; this.nativeTypeUsed = DEFAULT_USE_NATIVE_TYPE; if (CLIPBOARD == null) { CLIPBOARD = new Clipboard(UiPlugin.getDefault().getWorkbench().getDisplay()); } } /** * Determine whether names in source should be used in the DDL, or whether only names should be used. * This option does not apply when there are no names in source. * @return true if entities' name in source rather than their name should be used for the object * names in the DDL, or false if only their names should be used. */ public boolean isNameInSourceUsed() { return this.nameInSourceUsed; } /** * Set whether names in source should be used in the DDL, or whether only names should be used. * This option does not apply when there are no names in source. * @param useNameInSource true if entities' name in source rather than their name should be used for the object * names in the DDL, or false if only their names should be used. */ public void setNameInSourceUsed( final boolean useNameInSource) { this.nameInSourceUsed = useNameInSource; } /** */ public boolean isNativeTypeUsed() { return this.nativeTypeUsed; } /** */ public void setNativeTypeUsed(boolean useNativeType) { this.nativeTypeUsed = useNativeType; } public ModelResource getModelResource() { return modelResource; } public void setModelResource(ModelResource modelResource) { this.modelResource = modelResource; } public File getDdlFile() { return ddlFile; } public void setDdlFile(File ddlFile) { this.ddlFile = ddlFile; } public ExportChoice getExportType() { return exportType; } public void setExportType(ExportChoice exportType) { this.exportType = exportType; } public IStatus validate() { if( modelResource == null ) { return new Status(IStatus.ERROR, UiPlugin.PLUGIN_ID, "No model selected for export"); } return OK_STATUS; } public String generateDdl() { String ddl = null; try { // At this point we have either a relational source or view model // If Source model, we can expect to walk the table, procedure and function objects TeiidModelToDdlGenerator generator = new TeiidModelToDdlGenerator(); ddl = generator.generate(getModelResource()); } catch (ModelWorkspaceException e) { // TODO ADD ERROR STATUS e.printStackTrace(); } return ddl; } /** * @see DdlWriter#write(ModelResource, OutputStream, IProgressMonitor) */ public IStatus write( final ModelResource modelResource, final OutputStream stream, final IProgressMonitor monitor ) { CoreArgCheck.isNotNull(modelResource); CoreArgCheck.isNotNull(stream); // Get the emf resource from the model ... try { final Resource emfResource = modelResource.getEmfResource(); final ModelEditor editor = ModelerCore.getModelEditor(); final String modelName = editor.getModelName(modelResource); final String modelFilename = modelResource.getPath().toString(); final ModelContents contents = ModelContents.getModelContents(modelResource); return doWrite(modelResource, 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, UiConstants.PLUGIN_ID, "ERROR WRITING DDL"); } } /** * 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 ModelResource modelResource, final OutputStream stream, final IProgressMonitor monitor ) { CoreArgCheck.isNotNull(modelResource); 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 new Status(IStatus.OK, UiConstants.PLUGIN_ID, "NOT YET IMPLEMENTED"); //resultStatus; } /* * Write the DDL to the given output stream */ private void writeToStream(final OutputStream stream) throws Exception { new ProgressMonitorDialog(Display.getCurrent().getActiveShell()).run(false, true, new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException { try { writeStatus = write( modelResource, stream, monitor); } catch (final Exception err) { throw new InvocationTargetException(err); } finally { try { stream.close(); } catch (IOException e) { UiConstants.Util.log(e); } monitor.done(); } } }); if (!writeStatus.isOK()) { UiConstants.Util.log(writeStatus); WidgetUtil.showError("ERROR exporting model to file"); } } public void exportToFile() throws Exception { if (ddlFile == null || (ddlFile.exists() && !WidgetUtil.confirmOverwrite(ddlFile))) { return; } writeToStream(new FileOutputStream(ddlFile)); } public void exportToClipboard() throws Exception { if (CLIPBOARD == null || CLIPBOARD.isDisposed()) WidgetUtil.showError("ERROR exporting to clipboard"); ByteArrayOutputStream stream = new ByteArrayOutputStream(); writeToStream(stream); CLIPBOARD.setContents(new Object[] { stream.toString() }, new Transfer[] { TextTransfer.getInstance() }); } }