/* * 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.actions; import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchPart; import org.teiid.core.designer.ModelerCoreException; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.util.DisabledCommand; import org.teiid.designer.core.util.NewModelObjectHelperManager; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.metamodels.diagram.Diagram; import org.teiid.designer.ui.UiConstants; import org.teiid.designer.ui.UiPlugin; import org.teiid.designer.ui.common.eventsupport.SelectionUtilities; import org.teiid.designer.ui.editors.ModelEditorManager; import org.teiid.designer.ui.explorer.ModelExplorerLabelProvider; import org.teiid.designer.ui.viewsupport.ModelObjectLabelProvider; import org.teiid.designer.ui.viewsupport.ModelObjectUtilities; import org.teiid.designer.ui.viewsupport.ModelUtilities; import org.teiid.designer.ui.wizards.NewModelObjectWizardManager; /** * The <code>NewSiblingAction</code> class creates a new sibling object. * @since 8.0 */ public class NewSiblingAction extends ModelObjectAction { //============================================================================================================================ // Constants private static final String PROBLEM = "NewSiblingAction.problem"; //$NON-NLS-1$ private static final String NONE_ALLOWED = "NewSiblingAction.noneAllowed"; //$NON-NLS-1$ //============================================================================================================================ // Static Variables private static final ModelExplorerLabelProvider diagramProvider = new ModelExplorerLabelProvider(); private static final ModelObjectLabelProvider provider = (ModelObjectLabelProvider) ModelUtilities.getEMFLabelProvider(); //============================================================================================================================ // Fields /** The sibling type descriptor. */ private Command descriptor; private EObject sibling; //============================================================================================================================ // Constructors /** * Constructs a <code>NewSiblingAction</code> where no siblings are allowed. This action is not * enabled. */ public NewSiblingAction() { super(UiPlugin.getDefault()); configureNoneAllowedState(); } /** * Constructs a <code>NewSiblingAction</code> where a new sibling is created. * @param theDescriptor the descriptor that determines the sibling type created */ public NewSiblingAction(EObject sibling, Command theDescriptor) { super(UiPlugin.getDefault()); this.sibling = sibling; setCommand(theDescriptor); } //============================================================================================================================ // Methods /** * Configures the action by setting text, image, and enabled state. */ private void configureAllowedState() { Object result = descriptor.getResult().iterator().next(); // If the descriptor represents a disabled command then extract the // underlying command to use when getting labels Command cmd = descriptor; if (descriptor instanceof DisabledCommand) { cmd = ((DisabledCommand)descriptor).getDisabledCommand(); } // Use the CreateChildCommand label for the menu text String label = cmd.getLabel(); // If the label does not exist of if we are creating a new root entity // in a model (i.e. AddCommand) then use the label provider's text since // AddCommand labels do not provide meaningful text for a "new" child if ( label == null || label.length() == 0 || cmd instanceof AddCommand) { label = provider.getText(result); } // Remove the "New" prefix present in labels from CreateChildCommand instances if ( label != null && label.startsWith("New ") ) { //$NON-NLS-1$ label = label.substring(4); } setText(label); if ( result instanceof Diagram ) { setImage(diagramProvider.getImage(result)); } else if ( result instanceof EObject ) { setImage(provider.getImage((EObject) result, ModelObjectUtilities.isVirtual(sibling))); } else { setImage(provider.getImage(result)); } setToolTipText(cmd.getDescription()); setEnabled(true); } /** * Configures the action by setting text and disabling it. */ private void configureNoneAllowedState() { setText(getPluginUtils().getString(NONE_ALLOWED)); setEnabled(false); } @Override protected void doRun() { if (descriptor != null) { Shell shell = super.getPlugin().getWorkbench().getActiveWorkbenchWindow().getShell(); ModelResource modelResource = null; boolean continuing = true; try { modelResource = ModelerCore.getModelEditor().findModelResource( sibling ); } catch (Exception ex) { String msg = getPluginUtils().getString(PROBLEM, new Object[] {descriptor}); getPluginUtils().log(IStatus.ERROR, ex, msg); continuing = false; } // BML 9/16/04 ---------------------------- // ModelObjectAction caches a selection, however, this instance does not. // Need to create a temporary selection to pass into the wizards, either an EObject // or a model resource. ISelection tempSelection = null; if( sibling.eContainer() != null ) { tempSelection = new StructuredSelection(sibling.eContainer()); } else { ModelResource mr = ModelUtilities.getModelResourceForModelObject(sibling); if( mr != null ) tempSelection = new StructuredSelection(mr); } // -------------------------------------------- if (continuing) { // We need to insure that all containers (especially Transformation & MappingClassSet containers) are loaded/created // prior to new child transaction. This insures undo works. ModelUtilities.initializeModelContainers(modelResource, "New Sibling Added", this); //$NON-NLS-1$ if ( NewModelObjectWizardManager.isObjectDescriptorValid( shell, descriptor, modelResource, tempSelection ) ) { // System.out.println("[NewSiblingAction.doRun] will run the wizard");//$NON-NLS-1$ // Defect 18433 - The XMLDocumentWizard was changed to insure that all work was done one a single thread // and that wizard managed a single transaction to insure UNDO capability // (i.e. started, committed, canceled/rolledBack) // if there is a wizard, use it: NewModelObjectWizardManager.processObjectDescriptor( shell, descriptor, modelResource, tempSelection ); } else { // if no wizard, create the new objects here // System.out.println("[NewSiblingAction.doRun] will do create txn"); //$NON-NLS-1$ boolean started = ModelerCore.startTxn(true, UiConstants.Util.getString("NewSiblingAction.undoLabel", descriptor.getLabel()), this); //$NON-NLS-1$ boolean succeeded = false; EObject newObj = null; try { boolean undoable = true; newObj = ModelerCore.getModelEditor().createNewSiblingFromCommand( sibling, descriptor ); // Defect 18433 - BML 8/31/05 - Added this manager and INewModelObjectHelper interface to give arbitary // plugins the change to contribute more work following the creation of a new object // In the case of a Virtual Group, we needed to create the transformation for that table so it didn't // get lazily created as another "Undo" event. (i.e. TransformationNotificationListener, EditAction,, etc.) // If Helper exists, ask for helpCreate(newObj) // The helper also has the opportunity to change/override the "Undo" state of the transaction List<EObject> potentialReferences = SelectionUtilities.getSelectedEObjects(getSelection()); if( ! potentialReferences.isEmpty() ) { undoable = NewModelObjectHelperManager.helpCreate(newObj, null, potentialReferences); } else { undoable = NewModelObjectHelperManager.helpCreate(newObj, null); } if( !undoable ) ModelerCore.getCurrentUoW().setUndoable(false); succeeded = true; } catch (ModelerCoreException theException) { String msg = getPluginUtils().getString(PROBLEM, new Object[] {descriptor}); getPluginUtils().log(IStatus.ERROR, theException, msg); setEnabled(false); } finally { if ( started ) { if ( succeeded ) { String newObjName = ModelerCore.getModelEditor().getName(newObj); if( newObjName != null ) { ModelerCore.getCurrentUoW().setDescription(UiConstants.Util.getString("NewSiblingAction.undoLabel", newObjName)); //$NON-NLS-1$ } ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } } } } } } /** * This method is called in the run() method of AbstractAction to give the actions a hook into canceling * the run at the last minute. * This overrides the AbstractAction preRun() method. */ @Override protected boolean preRun() { if( requiresEditorForRun() && sibling != null ) { ModelResource mr = ModelUtilities.getModelResourceForModelObject(sibling); if( mr != null ) { ModelEditorManager.activate(mr, true, true); } } return true; } /* (non-Javadoc) * @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection) */ @Override public void selectionChanged(IWorkbenchPart thePart, ISelection theSelection) { super.selectionChanged(thePart, theSelection); } /** * Sets the sibling type descriptor used to create the sibling. * @param theDescriptor the sibling type descriptor or <code>null</code> if no sibling can be created */ public void setCommand(Command theDescriptor) { descriptor = theDescriptor; if (descriptor == null || descriptor.getResult().isEmpty() ) { configureNoneAllowedState(); } else { configureAllowedState(); if ( descriptor instanceof DisabledCommand ) { super.setEnabled(false); } } } /* (non-Javadoc) * @see org.teiid.designer.ui.actions.ModelObjectAction#requiresEditorForRun() */ @Override protected boolean requiresEditorForRun() { return true; } }