/* * 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.runtime.ui.wizards.vdbs; import java.io.StringWriter; import java.util.Properties; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; 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.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.osgi.util.NLS; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.core.designer.util.StringConstants; import org.teiid.core.designer.util.StringUtilities; import org.teiid.designer.core.validation.rules.StringNameValidator; import org.teiid.designer.runtime.ui.Messages; import org.teiid.designer.transformation.ui.UiConstants; import org.teiid.designer.ui.common.util.CompositeProgressMonitor; import org.teiid.designer.ui.common.util.UiUtil; import org.teiid.designer.ui.common.wizard.AbstractWizard; import org.teiid.designer.ui.viewsupport.ModelUtilities; import org.teiid.designer.vdb.BasicVdb; import org.teiid.designer.vdb.Vdb; import org.teiid.designer.vdb.VdbConstants; import org.teiid.designer.vdb.VdbPlugin; import org.teiid.designer.vdb.XmiVdb; import org.teiid.designer.vdb.dynamic.DynamicVdb; /** * */ public abstract class AbstractGenerateVdbManager implements UiConstants, StringConstants { private class GenerateRunnable implements IRunnableWithProgress { private final GeneratorCallback callback; private final String jobName; public GenerateRunnable(GeneratorCallback callback) { CoreArgCheck.isNotNull(callback); this.callback = callback; this.jobName = NLS.bind(Messages.GenerateVdbWizard_ConvertJobName, StringUtilities.fromCamelCase(callback.getSourceVdb().getClass().getSimpleName()), StringUtilities.fromCamelCase(callback.getTargetType().getSimpleName()) ); } @Override public void run(final IProgressMonitor wizardMonitor) { WorkspaceJob job = new WorkspaceJob(jobName) { @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { CompositeProgressMonitor compositeMonitor = new CompositeProgressMonitor(wizardMonitor, monitor); try { compositeMonitor.beginTask(jobName, 1); callback.execute(); compositeMonitor.worked(1); return Status.OK_STATUS; } catch (Exception ex) { throw toCoreException(ex); } finally { compositeMonitor.done(); } } }; job.addJobChangeListener(new JobChangeAdapter() { @Override public void aboutToRun(IJobChangeEvent event) { callback.aboutToRun(); } @Override public void done(final IJobChangeEvent event) { // // Refresh to display the vdb // try { refreshOutputLocation(); } catch (CoreException ex) { // Nothing to do } callback.onCompletion(event.getResult()); } }); job.schedule(); // // Hold up this thread until the end of the job // try { job.join(); } catch (InterruptedException ex) { CoreException coreException = toCoreException(ex); callback.onCompletion(coreException.getStatus()); // Something went wrong. Eliminate the job just in case job.cancel(); } Runnable swtRunnable = new Runnable() { @Override public void run() { wizard.getContainer().updateButtons(); } }; UiUtil.runInSwtThread(swtRunnable, true); } } protected abstract class GeneratorCallback<V extends Vdb> { private V vdb; /** * Execute prior callback execution */ public void aboutToRun() { // Do nothing by default } /** * Execute the generation */ protected void execute() throws Exception { vdb = getSourceVdb().convert(getTargetType(), getDestination(), conversionOptions); } /** * @param status the status of the execution */ public abstract void onCompletion(IStatus status); /** * @return the source vdb to be generated */ public abstract Vdb getSourceVdb(); /** * @return the target vdb type */ public abstract Class<V> getTargetType(); protected final V getResult() { return vdb; } } protected static final StringNameValidator nameValidator = new StringNameValidator( StringNameValidator.DEFAULT_MINIMUM_LENGTH, StringNameValidator.DEFAULT_MAXIMUM_LENGTH, new char[] {'_', '-', '.'}); private final AbstractWizard wizard; private DynamicVdb dynamicVdb; private String version = Integer.toString(1); private XmiVdb archiveVdb; private IStatus status = Status.OK_STATUS; private IContainer outputLocation; private String outputVdbFileName; private String outputVdbName; private Properties conversionOptions = new Properties(); private boolean overwriteExistingFiles = true; /** * @param wizard */ public AbstractGenerateVdbManager(AbstractWizard wizard) { this.wizard = wizard; } /** * @return dynamic vdb */ public DynamicVdb getDynamicVdb() { return dynamicVdb; } /** * @param dynamicVdb the dynamicVdb to set */ protected void setDynamicVdb(DynamicVdb dynamicVdb) { this.dynamicVdb = dynamicVdb; } /** * @return archive vdb */ public XmiVdb getArchiveVdb() { return archiveVdb; } /** * @param archiveVdb the archiveVdb to set */ protected void setArchiveVdb(XmiVdb archiveVdb) { this.archiveVdb = archiveVdb; } /** * @return output location */ public IContainer getOutputLocation() { return outputLocation; } /** * * @return */ public String getOutputVdbName() { return this.outputVdbName; } /** * @param outputLocation */ protected void setOutputLocation(IContainer outputLocation) { this.outputLocation = outputLocation; } protected void refreshOutputLocation() throws CoreException { if (getOutputLocation() == null) return; if (!getOutputLocation().exists()) return; getOutputLocation().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); } /** * @return the outputName */ public String getOutputVdbFileName() { return this.outputVdbFileName; } /** * @return destination file */ public IFile getDestination() { return outputLocation.getFile(new Path(getOutputVdbFileName())); } /** * @param outputName the outputName to set */ protected void setOutputVdbFileName(String outputName) { this.outputVdbFileName = outputName; } /** * @param outputName the outputVdbName to set */ protected void setOutputVdbName(String outputVdbName) { this.outputVdbName = outputVdbName; } /** * @return version */ public String getVersion() { return version; } /** * @param version */ public void setVersion(String version) { this.version = version; } /** * @return the xml string representation of the dynamic vdb * @throws Exception if error occurs */ public String getDynamicVdbXml() throws Exception { StringWriter writer = new StringWriter(); // // Writer will be closed by write method // dynamicVdb.write(writer); return writer.toString(); } /** * @return status */ public IStatus getStatus() { return status; } /** * @param status the status to set */ protected void setStatus(IStatus status) { this.status = status; } /** * * @param name * @param value */ protected void addConversionOption(String name, String value) { conversionOptions.setProperty(name, value); } /** * * @param key * @return */ protected String getConversionOption(String key) { return conversionOptions.getProperty(key); } protected void setOverwriteExistingFiles(boolean overwrite) { this.overwriteExistingFiles = overwrite; } protected boolean overwriteExistingFiles() { return this.overwriteExistingFiles; } /** * Validate the values of the wizard */ protected void validate() { setStatus(Status.OK_STATUS); // Check ouptut vdb name String proposedVdbName = getOutputVdbFileName(); String validationMessage = nameValidator.checkValidName(proposedVdbName); if (validationMessage != null) { setStatus(new Status(IStatus.ERROR, PLUGIN_ID, validationMessage)); return; } validationMessage = ModelUtilities.vdbNameReservedValidation(proposedVdbName); if (validationMessage != null) { setStatus(new Status(IStatus.ERROR, PLUGIN_ID, validationMessage)); return; } // Check Version # is an integer String version = getVersion(); if( version == null ) { // TODO: Status message (cannot be null) } // output location can't be null if (getOutputLocation() == null) { setStatus(new Status(IStatus.ERROR, PLUGIN_ID, Messages.GenerateVdbWizard_validation_targetLocationUndefined)); return; } if (!getOutputLocation().exists()) { setStatus(new Status(IStatus.ERROR, PLUGIN_ID, Messages.GenerateVdbWizard_validation_targetLocationNotExist)); return; } if (getOutputVdbFileName() == null) { setStatus(new Status(IStatus.ERROR, PLUGIN_ID, Messages.GenerateVdbWizard_validation_vdbFileNameUndefined)); return; } IFile destination = getDestination(); if (destination.exists()) { int severity = overwriteExistingFiles ? IStatus.WARNING : IStatus.ERROR; setStatus(new Status(severity, PLUGIN_ID, Messages.GenerateVdbWizard_validation_targetFileAlreadyExists)); return; } } protected void generateVdbJob(final GeneratorCallback callback) { GenerateRunnable runnable = new GenerateRunnable(callback); try { wizard.getContainer().run(true, true, runnable); } catch (Exception ex) { CoreException coreException = toCoreException(ex); callback.onCompletion(coreException.getStatus()); } finally { wizard.getContainer().updateButtons(); } } protected CoreException toCoreException(Throwable throwable) { if (throwable instanceof CoreException) return (CoreException)throwable; String message = VdbPlugin.UTIL.getStringOrKey(BasicVdb.class.getSimpleName() + DOT + "vdbExceptionThrown"); //$NON-NLS-1$ MultiStatus status = new MultiStatus(VdbConstants.PLUGIN_ID, IStatus.ERROR, message, null); do { status.add(new Status(IStatus.ERROR, VdbConstants.PLUGIN_ID, " * " + throwable.getLocalizedMessage())); //$NON-NLS-1$ throwable = throwable.getCause(); } while (throwable != null); return new CoreException(status); } /** * @throws Exception */ protected void write() throws Exception { // // Refresh the output location // refreshOutputLocation(); // // Perform a clean build on the project // IProject project = getOutputLocation().getProject(); project.build(IncrementalProjectBuilder.CLEAN_BUILD, new NullProgressMonitor()); } }