/* * 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.xml.ui.actions; //import java.util.ArrayList; import java.lang.reflect.InvocationTargetException; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.views.navigator.ResourceNavigator; import org.eclipse.xsd.XSDElementDeclaration; import org.eclipse.xsd.XSDSchema; import org.teiid.core.designer.util.CoreStringUtil; import org.teiid.core.designer.util.I18nUtil; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelUtil; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.metamodels.core.ModelType; import org.teiid.designer.metamodels.xml.XmlDocumentPackage; import org.teiid.designer.ui.UiConstants; import org.teiid.designer.ui.actions.DeleteAction; import org.teiid.designer.ui.actions.SortableSelectionAction; import org.teiid.designer.ui.common.eventsupport.SelectionUtilities; import org.teiid.designer.ui.common.product.ProductCustomizerMgr; import org.teiid.designer.ui.common.util.UiUtil; import org.teiid.designer.ui.editors.ModelEditorManager; import org.teiid.designer.ui.viewsupport.ModelSelectorDialog; import org.teiid.designer.ui.viewsupport.ModelSelectorInfo; import org.teiid.designer.ui.viewsupport.ModelWorkspaceViewerFilter; import org.teiid.designer.xml.ui.ModelerXmlUiConstants; import org.teiid.designer.xml.ui.ModelerXmlUiPlugin; import org.teiid.designer.xml.ui.dialogs.ConfirmSaveXsdModelDialog; import org.teiid.designer.xml.ui.wizards.XmlViewModelSelectionValidator; /** * @since 8.0 */ public class CreateXmlViewFromXsdAction extends SortableSelectionAction implements ModelerXmlUiConstants { // ///////////////////////////////////////////////////////////////////////////////////////////// // CONSTANTS // ///////////////////////////////////////////////////////////////////////////////////////////// private static final String KEY_NO_SEL_DLG_MSG = "CreateXmlViewFromXsdAction.noSelMsg"; //$NON-NLS-1$ private static final String NO_SEL_DLG_TITLE = Util.getString("CreateXmlViewFromXsdAction.noSelTitle"); //$NON-NLS-1$ private static final String DEFAULT_EXPLORER_TITLE = Util.getString("CreateXmlViewFromXsdAction.defaultViewName"); //$NON-NLS-1$; // ///////////////////////////////////////////////////////////////////////////////////////////// // CONSTRUCTORS // ///////////////////////////////////////////////////////////////////////////////////////////// public CreateXmlViewFromXsdAction() { super(); } // ///////////////////////////////////////////////////////////////////////////////////////////// // METHODS // ///////////////////////////////////////////////////////////////////////////////////////////// /** * The model editor for the specified resource is activated. If the editor is not already opened it is opened. * * @param theModel the model resource whose editor has been requested to be activated */ protected void activateModelEditor( final ModelResource theModel ) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { try { final IFile file = (IFile)theModel.getUnderlyingResource(); if (file != null) { // Changed to use method that insures Object editor mode is on ModelEditorManager.openInEditMode(theModel, true, org.teiid.designer.ui.UiConstants.ObjectEditor.IGNORE_OPEN_EDITOR); ModelEditorManager.save(file); } } catch (ModelWorkspaceException theException) { Util.log(theException); } } }); } protected boolean executeBuild( List theXsdRoots, final IProgressMonitor theMonitor ) { boolean result = false; final String PREFIX = I18nUtil.getPropertyPrefix(CreateXmlViewFromXsdAction.class); theMonitor.beginTask("Building View Model Documents: ", 100); //$NON-NLS-1$; // first select/create a XML Document Model ModelResource xmlDocModel = null; ModelSelectorInfo newModelInfo = new ModelSelectorInfo( Util.getString(PREFIX + "modelTypeName"), //$NON-NLS-1$ ModelType.VIRTUAL_LITERAL, XmlDocumentPackage.eNS_URI, Util.getString(PREFIX + "newModelNameLabel"), //$NON-NLS-1$ Util.getString(PREFIX + "modelSelectorTitle")); //$NON-NLS-1$ ModelSelectorDialog mwdDialog = new ModelSelectorDialog(getShell(), newModelInfo); mwdDialog.addFilter(new ModelWorkspaceViewerFilter(true)); mwdDialog.setValidator(new XmlViewModelSelectionValidator()); mwdDialog.setAllowMultiple(false); mwdDialog.open(); boolean modelCreated = mwdDialog.isNewModel(); if (mwdDialog.getReturnCode() == Window.OK) { Object[] selectedObjects = mwdDialog.getResult(); if ((selectedObjects.length == 1) && (selectedObjects[0] instanceof IFile)) { IFile theFile = (IFile)selectedObjects[0]; if (theFile != null) { try { xmlDocModel = ModelUtil.getModelResource(theFile, false); } catch (ModelWorkspaceException theException) { Util.log(theException); } } } } if (xmlDocModel != null) { // start contributor wizard final ModelResource xmlModel = xmlDocModel; ModelResource schemaModelResource = getSchemaModel(theXsdRoots); if (schemaModelResource != null) { try { final IFile schemaModel = (IFile)schemaModelResource.getUnderlyingResource(); ISelection schemaSelection = new StructuredSelection(schemaModel); ViewXmlMessageStructureWizard wizard = new ViewXmlMessageStructureWizard(xmlModel, schemaSelection); XSDElementDeclaration[] roots = (XSDElementDeclaration[])theXsdRoots.toArray(new XSDElementDeclaration[theXsdRoots.size()]); wizard.setDocumentRoots(roots); // show wizard if (new WizardDialog(getShell(), wizard).open() == Window.OK) { result = true; activateModelEditor(xmlModel); } else if (modelCreated) { // delete model is just created and wizard canceled if (!xmlModel.getPath().toFile().getAbsoluteFile().exists()) { Display.getCurrent().asyncExec(new Runnable() { @Override public void run() { try { IResource resource = xmlModel.getUnderlyingResource(); if (resource != null) { DeleteAction action = new DeleteAction(); action.selectionChanged(null, new StructuredSelection(resource)); action.run(); } } catch (ModelWorkspaceException theException) { Util.log(theException); } } }); } } // need to refresh Model Explorer if opened since when validation is run the XSD is unloaded and // reloaded which makes new instances of schema elements. refresh updates the to the new elements. IViewPart part = UiUtil.getViewPart(UiConstants.Extensions.Explorer.VIEW); if (part != null) { ((ResourceNavigator)part).getViewer().refresh(schemaModel); } } catch (Exception theException) { Util.log(theException); } } } notifyResult(result); return result; } protected boolean processXsdRoots( final List theXsdRoots ) { final boolean[] result = new boolean[1]; if ((theXsdRoots != null) && !theXsdRoots.isEmpty()) { final WorkspaceModifyOperation op = new WorkspaceModifyOperation() { @Override public void execute( IProgressMonitor theMonitor ) { try { // make sure XSD is saved before building if (isXsdSaved(theXsdRoots)) { result[0] = executeBuild(theXsdRoots, theMonitor); } } finally { theMonitor.done(); } } }; final boolean startedTxn = ModelerCore.startTxn(false, false, "Create XML View Model", this); //$NON-NLS-1$ boolean success = false; try { new ProgressMonitorDialog(getShell()).run(false, false, op); success = result[0]; } catch (InterruptedException theException) { success = false; } catch (InvocationTargetException theException) { final String PREFIX = I18nUtil.getPropertyPrefix(CreateXmlViewFromXsdAction.class); success = false; Throwable realException = theException.getTargetException(); String msg = realException.getMessage(); if (CoreStringUtil.isEmpty(msg)) { msg = Util.getString(PREFIX + "noDetailsMsg"); //$NON-NLS-1$ } String title = Util.getString(PREFIX + "errorBuildingDialogTitle"); //$NON-NLS-1$ MessageDialog.openError(getShell(), title, msg); } finally { if (startedTxn) { if (success) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } } } return result[0]; } /** * Obtains the schema model resource for the specified list of XSD element roots. * * @param theXsdRoots the XSD element whose schema model is being requested * @return the schema model or <code>null</code> if not found * @since 5.0.2 */ protected ModelResource getSchemaModel( List theXsdRoots ) { ModelResource result = null; try { result = ModelUtil.getModel(theXsdRoots.get(0)); } catch (ModelWorkspaceException theException) { Util.log(theException); } return result; } /** * Obtains the <code>Shell</code> for the * * @return * @since 5.0.2 */ protected Shell getShell() { return ModelerXmlUiPlugin.getDefault().getCurrentWorkbenchWindow().getShell(); } /** * Indicates if the XSD schema resource for the specified XSD elements is saved. * * @param theXsdRoots the XSD element roots whose schema resource is being checked * @return <code>true</code> if saved; <code>false</code> otherwise. * @since 5.0.2 */ protected boolean isXsdSaved( List theXsdRoots ) { boolean result = true; // if XSD is dirty require the user to authorize a save to continue try { ModelResource schemaModelResource = getSchemaModel(theXsdRoots); if (schemaModelResource == null) { result = false; } else if (schemaModelResource.getEmfResource().isModified()) { ConfirmSaveXsdModelDialog dialog = new ConfirmSaveXsdModelDialog(getShell(), schemaModelResource); result = ((dialog.open() == Window.OK) && dialog.isSchemaSaved()); } } catch (ModelWorkspaceException theException) { result = false; Util.log(theException); } return result; } /** * @see org.eclipse.jface.action.Action#run() * @since 5.0.2 */ @Override public void run() { IWorkbenchWindow iww = ModelerXmlUiPlugin.getDefault().getCurrentWorkbenchWindow(); ISelection selection = getSelection(); if (isValidSelection(selection)) { final List docRoots = SelectionUtilities.getSelectedEObjects(selection); processXsdRoots(docRoots); } else { // selection empty, tell user to select something: String viewId = ProductCustomizerMgr.getInstance().getProductCharacteristics().getPrimaryNavigationViewId(); IViewReference viewRef = iww.getActivePage().findViewReference(viewId); String viewTitle = ((viewRef == null) ? DEFAULT_EXPLORER_TITLE : viewRef.getTitle()); // show the dialog: String dlgMsg = Util.getString(KEY_NO_SEL_DLG_MSG, viewTitle); MessageDialog.openError(iww.getShell(), NO_SEL_DLG_TITLE, dlgMsg); return; } } /** * Valid selections include Relational Tables, Procedures or Relational Models. The roots instance variable will populated * with all Tables and Procedures contained within the current selection. * * @return * @since 4.1 */ @Override protected boolean isValidSelection( ISelection selection ) { boolean isValid = true; if (SelectionUtilities.isEmptySelection(selection)) { isValid = false; } if (isValid) { XSDSchema schema = null; final List objs = SelectionUtilities.getSelectedObjects(selection); for (Iterator iter = objs.iterator(); iter.hasNext();) { Object nextObj = iter.next(); if (nextObj instanceof XSDElementDeclaration) { // make sure all selected elements are from same schema XSDSchema temp = ((XSDElementDeclaration)nextObj).getSchema(); if (schema == null) { schema = temp; } else { isValid = schema.equals(temp); } } else { isValid = false; } if (!isValid) { break; } } } // endif -- is empty sel return isValid; } /** * @see org.teiid.designer.ui.actions.SortableSelectionAction#isApplicable(org.eclipse.jface.viewers.ISelection) * @since 5.0.2 */ @Override public boolean isApplicable( ISelection theSelection ) { return isValidSelection(theSelection); } }