/* * 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.diagram.ui.custom.actions; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IWorkbenchPart; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.diagram.ui.DiagramUiConstants; import org.teiid.designer.diagram.ui.DiagramUiPlugin; import org.teiid.designer.diagram.ui.actions.DiagramAction; import org.teiid.designer.diagram.ui.connection.UmlRelationshipHelper; import org.teiid.designer.diagram.ui.custom.CustomDiagramModelFactory; import org.teiid.designer.diagram.ui.editor.DiagramEditor; import org.teiid.designer.diagram.ui.editor.DiagramEditorUtil; import org.teiid.designer.diagram.ui.model.DiagramModelNode; import org.teiid.designer.diagram.ui.util.DiagramUiUtilities; import org.teiid.designer.metamodels.diagram.Diagram; import org.teiid.designer.ui.common.eventsupport.SelectionUtilities; import org.teiid.designer.ui.editors.ModelEditor; /** * AddAssociatedObjectsAction This class provides custom diagrams the ability to allow the user to add any objects associated with * objects selected in the diagram. This action should only be offered on diagram node selection. * * @since 8.0 */ public class AddAssociatedObjectsAction extends DiagramAction { private static final String THIS_CLASS = "AddAssociatedObjectsAction"; //$NON-NLS-1$ private DiagramEditor editor; // ///////////////////////////////////////////////////////////////////////////////////////////// // CONSTRUCTORS // ///////////////////////////////////////////////////////////////////////////////////////////// public AddAssociatedObjectsAction() { super(); setImageDescriptor(DiagramUiPlugin.getDefault().getImageDescriptor(DiagramUiConstants.Images.ADD_ASSOCIATED_OBJECTS)); } // ///////////////////////////////////////////////////////////////////////////////////////////// // METHODS // ///////////////////////////////////////////////////////////////////////////////////////////// /* (non-Javadoc) * @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection) */ @Override public void selectionChanged( IWorkbenchPart thePart, ISelection theSelection ) { // initialize abstract base class info super.selectionChanged(thePart, theSelection); setEnabled(shouldEnable()); } /* (non-Javadoc) * @see org.eclipse.jface.action.IAction#run() */ @Override protected void doRun() { if (editor != null) { // Need to get the current diagram DiagramModelNode diagramNode = editor.getCurrentModel(); Diagram diagram = (Diagram)diagramNode.getModelObject(); // Need to get ahold of the CustomDiagramModelFactory CustomDiagramModelFactory modelFactory = (CustomDiagramModelFactory)editor.getModelFactory(); // And call add(SelectionUtilities.getSelectedEObjects(getSelection()) List objectsToAdd = getAssociatedObjectsNotInDiagram(); if (!objectsToAdd.isEmpty() && modelFactory != null) { boolean handleConstruction = !DiagramEditorUtil.isDiagramUnderConstruction(diagram); boolean requiredStart = false; boolean succeeded = false; try { if (handleConstruction) { DiagramEditorUtil.setDiagramUnderConstruction(diagram); } // ------------------------------------------------- // Let's wrap this in a transaction!!! // ------------------------------------------------- requiredStart = ModelerCore.startTxn(true, false, "Add Related Objects", this); //$NON-NLS-1$$ modelFactory.add(objectsToAdd, diagramNode); succeeded = true; } catch (Exception ex) { DiagramUiConstants.Util.log(IStatus.ERROR, ex, ex.getClass().getName() + ":" + THIS_CLASS + ".doRun()"); //$NON-NLS-1$ //$NON-NLS-2$ } finally { if (requiredStart) { if (succeeded) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } if (handleConstruction) { DiagramEditorUtil.setDiagramConstructionComplete(diagram, true); } } } } } private boolean shouldEnable() { if (!(this.getPart() instanceof ModelEditor) || getSelection() == null || SelectionUtilities.getSelectedEObjects(getSelection()).size() < 0) return false; return allSelectedInDiagram() && isWritable() && allObjectsAddable(); } private boolean allSelectedInDiagram() { // check the diagram to see if all selected objects are in diagram?? if (editor != null && editor.getDiagramViewer() != null && editor.getDiagramViewer().getSelectionHandler() != null) { List selectedEObjects = editor.getDiagramViewer().getSelectionHandler().getSelectedEObjects(); if (selectedEObjects == null || selectedEObjects.isEmpty()) return false; Iterator iter = SelectionUtilities.getSelectedEObjects(getSelection()).iterator(); EObject eObj = null; while (iter.hasNext()) { eObj = (EObject)iter.next(); if (!selectedEObjects.contains(eObj)) return false; } } return true; } public void setDiagramEditor( DiagramEditor editor ) { this.editor = editor; } private boolean isWritable() { if (editor != null) { DiagramModelNode currentDiagram = editor.getCurrentModel(); if (currentDiagram != null) { return !isReadOnly(); } } return false; } private boolean allObjectsAddable() { boolean allOK = true; List objectsToAdd = getAssociatedObjectsNotInDiagram(); if (objectsToAdd == null || objectsToAdd.isEmpty()) allOK = false; return allOK; } private List getAssociatedObjectsNotInDiagram() { List newObjects = new ArrayList(); if (editor != null && editor.getCurrentModel() != null) { DiagramModelNode diagramNode = editor.getCurrentModel(); List allAssociatedToAdd = UmlRelationshipHelper.getRelatedObjects(SelectionUtilities.getSelectedEObjects(getSelection())); Iterator iter = allAssociatedToAdd.iterator(); EObject nextEObj = null; while (iter.hasNext()) { nextEObj = (EObject)iter.next(); if (editor != null && editor.getCurrentModel() != null) { if (!(DiagramUiUtilities.diagramContainsEObject(nextEObj, diagramNode))) newObjects.add(nextEObj); } } } if (newObjects.isEmpty()) return Collections.EMPTY_LIST; return newObjects; } @Override protected boolean requiresEditorForRun() { return false; } }