/*
* 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.ui.wizards;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
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.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.xsd.XSDElementDeclaration;
import org.teiid.core.designer.PluginUtil;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.notification.util.DefaultIgnorableNotificationSource;
import org.teiid.designer.core.transaction.UnitOfWorkImpl;
import org.teiid.designer.core.workspace.ModelResource;
import org.teiid.designer.core.workspace.ModelWorkspaceException;
import org.teiid.designer.metamodels.xsd.XsdBuilderOptions;
import org.teiid.designer.metamodels.xsd.XsdSchemaBuilderImpl;
import org.teiid.designer.ui.UiConstants;
import org.teiid.designer.ui.UiPlugin;
import org.teiid.designer.ui.common.wizard.AbstractWizard;
import org.teiid.designer.webservice.util.WebServiceBuilderHelper;
/**
* This wizard is used to drive the creation of XSD and XML from Relational Selections.
*
* @since 8.0
*/
public class GenerateXsdWizard extends AbstractWizard implements INewWizard, UiConstants {
public static boolean HEADLESS = false; // Flag to set Wizard to run in headless mode for testing
private final PluginUtil Util = UiConstants.Util;
// The page for driving the user options.
protected GenerateXsdWizardOptionslPage genXsdWizardOptionsPage;
// The current workspace selection
protected ISelection selection;
private IWizardPage[] wizardPageArray;
private IProgressMonitor monitor;
// The result messages to return to the user
private MultiStatus result;
// The user options returned from the Options Page.
XsdBuilderOptions ops;
// Map of output XmlDocuments to input global Elements
private HashMap outputToInputMappings = new HashMap();
private ModelResource wsModel;
/**
* Constructor for NewModelWizard.
*/
public GenerateXsdWizard() {
super(UiPlugin.getDefault(), UiConstants.Util.getString("GenerateXsdWizard.title"), null); //$NON-NLS-1$
setNeedsProgressMonitor(true);
}
/**
* @see org.teiid.designer.ui.common.wizard.AbstractWizard#createPageControls(org.eclipse.swt.widgets.Composite)
* @since 4.3
*/
@Override
public void createPageControls( Composite pageContainer ) {
super.createPageControls(pageContainer, false);
}
/**
* Adding the page to the wizard.
*/
@Override
public void addPages() {
genXsdWizardOptionsPage = new GenerateXsdWizardOptionslPage(this.selection);
addPage(genXsdWizardOptionsPage);
// this.getShell().setSize(450, 450);
}
/**
* This method is called when 'Finish' button is pressed in the wizard. We will create an operation and run it using wizard as
* execution context.
*/
@Override
public boolean finish() {
final WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
@Override
protected void execute( IProgressMonitor theMonitor ) {
// Get the options and execute the build.
ops = genXsdWizardOptionsPage.getOptions();
doFinish(theMonitor);
}
};
// Detmine TXN status and start one if required.
// This operation is not undoable OR significant.
final boolean startedTxn = ModelerCore.startTxn(false,
false,
GenerateXsdWizard.this.getWindowTitle(),
new DefaultIgnorableNotificationSource(GenerateXsdWizard.this));
if (startedTxn) {
// Defect 22359 - improve new model performance
// utilize the overrideRollback txn capability so the UOW doesn't cache commands
((UnitOfWorkImpl)ModelerCore.getCurrentUoW()).setOverrideRollback(true);
}
try {
new ProgressMonitorDialog(getShell()).run(false, false, op);
} catch (Throwable err) {
Util.log(IStatus.ERROR, err, err.getMessage());
} finally {
// This operation is NOT undoable or significant... ALWAYS commit to ensure
// Nothing is left hanging.
if (startedTxn) {
ModelerCore.commitTxn();
}
}
return true;
}
/**
* The worker method. It will find the container, create the file(s) - Made this method public to allow for headless testing.
*
* @param IPRogressMonitor - The progress monitor for this operation.
*/
public void doFinish( final IProgressMonitor monitor ) {
CoreArgCheck.isNotNull(this.ops);
// Create the XSD BUilder and capture state from the Options
final XsdSchemaBuilderImpl builder = new XsdSchemaBuilderImpl(this.ops);
this.monitor = (monitor == null) ? new NullProgressMonitor() : monitor;
this.result = getResult();
// Initialize the progress monitor
final String msg = Util.getString("GenerateXsdWizard.begin"); //$NON-NLS-1$
this.monitor.beginTask(msg, 4);
// Execute the build of the actual XSD models.
this.result = builder.buildSchemas(this.monitor, this.result);
// Update the monitor
this.monitor.worked(1);
// Execute the Helper build to finish the XML, XSD, and SQL generation
final GenerateXsdHelper helper = new GenerateXsdHelper(builder, ops, result);
outputToInputMappings = helper.execute(monitor);
// Check if XSDs need to be re-saved since calling helper.execute() can cause XSD imports to be modified as a side-effect.
for (Iterator iter = builder.getRootElements().iterator(); iter.hasNext();) {
XSDElementDeclaration elem = (XSDElementDeclaration)iter.next();
ModelResource resrc = ModelerCore.getModelEditor().findModelResource(elem);
try {
if (resrc != null && resrc.hasUnsavedChanges()) {
resrc.save(monitor, true);
}
} catch (ModelWorkspaceException err) {
Util.log(err);
}
} // for
// Update the monitor
this.monitor.worked(1);
if (ops.genWs()) {
final Collection webServiceOptions = helper.createWebServiceBuildOptions(outputToInputMappings, ops);
WebServiceBuilderHelper wsbh = new WebServiceBuilderHelper();
wsbh.setParentPath(ops.getParentPath());
wsbh.createWebServices(webServiceOptions, true, result, monitor);
helper.doSave();
wsModel = wsbh.getWebServiceModel();
wsbh.postProcess();
}
// Log the result
if (!this.result.isOK()) {
for (int i = 0; i < this.result.getChildren().length; i++) {
Util.log(this.result.getChildren()[i]);
}
}
}
/**
* We will accept the selection in the workbench to see if we can initialize from it.
*
* @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
*/
@Override
public void init( IWorkbench workbench,
IStructuredSelection selection ) {
this.selection = selection;
}
/**
* @see org.eclipse.jface.wizard.IWizard#getNextPage(org.eclipse.jface.wizard.IWizardPage)
*/
@Override
public IWizardPage getNextPage( IWizardPage page ) {
if (page == genXsdWizardOptionsPage) {
return null;
}
for (int i = 0; i < wizardPageArray.length; ++i) {
if (wizardPageArray[i] == page) {
if (i + 1 < wizardPageArray.length) {
return wizardPageArray[i + 1];
}
}
}
return null;
}
/**
* @see org.eclipse.jface.wizard.IWizard#canFinish() This Wizard can finish if the Options page is complete.
*/
@Override
public boolean canFinish() {
boolean result = false;
IWizardPage currentPage = getContainer().getCurrentPage();
if (currentPage == this.genXsdWizardOptionsPage) {
result = currentPage.isPageComplete();
} else {
boolean lastPage = (currentPage == wizardPageArray[wizardPageArray.length - 1]);
result = lastPage && currentPage.isPageComplete();
}
return result;
}
/**
* @see org.eclipse.jface.wizard.IWizard#getPageCount()
*/
@Override
public int getPageCount() {
if (wizardPageArray != null) {
return wizardPageArray.length + 1;
}
return 1;
}
/**
* Add a public setter to allow for Headless testing
*
* @param ops
*/
public void setOptions( XsdBuilderOptions ops ) {
this.ops = ops;
}
/**
* @see org.eclipse.jface.wizard.IWizard#getPreviousPage(org.eclipse.jface.wizard.IWizardPage)
*/
@Override
public IWizardPage getPreviousPage( IWizardPage page ) {
if (wizardPageArray == null || page == this.genXsdWizardOptionsPage) {
return null;
}
if (page == wizardPageArray[0]) {
return this.genXsdWizardOptionsPage;
}
for (int i = 1; i < wizardPageArray.length; ++i) {
if (page == wizardPageArray[i]) {
return wizardPageArray[i - 1];
}
}
return null;
}
/**
* A getter for the result message buffer.
*
* @return The results message buffer
*/
public MultiStatus getResult() {
if (this.result == null) {
this.result = new MultiStatus(UiConstants.PLUGIN_ID, 0, Util.getString("GenerateXsdWizard.result"), null); //$NON-NLS-1$
}
return this.result;
}
/**
* Return the map of Output XmlDocument node to Input Xsd Global Element mappings.
*/
public HashMap getOutPutToInputMappings() {
return outputToInputMappings;
}
public ModelResource getWebServiceModel() {
return this.wsModel;
}
}