/* * 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.mapping.ui.diagram; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.gef.EditPart; import org.eclipse.swt.widgets.Display; import org.teiid.designer.core.metamodel.aspect.MetamodelAspect; import org.teiid.designer.core.metamodel.aspect.uml.UmlClassifier; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.diagram.ui.DiagramUiPlugin; import org.teiid.designer.diagram.ui.editor.DiagramEditor; import org.teiid.designer.diagram.ui.editor.DiagramEditorUtil; import org.teiid.designer.diagram.ui.editor.DiagramSelectionHandler; import org.teiid.designer.diagram.ui.editor.DiagramViewer; import org.teiid.designer.diagram.ui.notation.uml.part.UmlAttributeEditPart; import org.teiid.designer.diagram.ui.notation.uml.part.UmlClassifierEditPart; import org.teiid.designer.diagram.ui.part.DiagramEditPart; import org.teiid.designer.diagram.ui.part.EditableEditPart; import org.teiid.designer.diagram.ui.util.DiagramUiUtilities; import org.teiid.designer.mapping.ui.PluginConstants; import org.teiid.designer.mapping.ui.UiConstants; import org.teiid.designer.mapping.ui.actions.MappingObjectEditHelper; import org.teiid.designer.mapping.ui.editor.MappingDiagramController; import org.teiid.designer.mapping.ui.part.MappingExtentEditPart; import org.teiid.designer.mapping.ui.part.MappingLinkEditPart; import org.teiid.designer.metamodels.diagram.Diagram; import org.teiid.designer.metamodels.transformation.InputSet; import org.teiid.designer.metamodels.transformation.TransformationMappingRoot; import org.teiid.designer.metamodels.transformation.impl.MappingClassImpl; import org.teiid.designer.metamodels.xml.XmlAttribute; import org.teiid.designer.metamodels.xml.XmlElement; import org.teiid.designer.transformation.ui.part.TransformationEditPart; import org.teiid.designer.transformation.util.TransformationHelper; import org.teiid.designer.ui.common.viewsupport.UiBusyIndicator; import org.teiid.designer.ui.editors.ModelEditorManager; import org.teiid.designer.ui.viewsupport.ModelObjectUtilities; import org.teiid.designer.ui.viewsupport.ModelUtilities; /** * MappingDiagramSelectionHandler * * @since 8.0 */ public class MappingDiagramSelectionHandler extends DiagramSelectionHandler { private MappingObjectEditHelper editHelper; private MappingDiagramProvider diagramProvider; /** * Construct an instance of MappingDiagramSelectionHandler. * * @param viewer */ public MappingDiagramSelectionHandler( DiagramViewer viewer ) { super(viewer); editHelper = new MappingObjectEditHelper(); diagramProvider = new MappingDiagramProvider(); } @Override public void select( EObject selectedObject ) { // System.out.println("[MappingDiagramSelectionHandler.select 1] TOP, selectedObject is: " + selectedObject ); // Thread.dumpStack(); super.deselectAll(); super.select(selectedObject); // // jh defect 20457, etc: selection problems in Detailed diagram: This hilite seems redundant: // hiliteDependencies(selectedObject); // fix for 20078: hiliteDependenciesForTreeSelection(selectedObject); // fix for 20235: // MappingDiagramController controller = (MappingDiagramController)getViewer().getEditor().getDiagramController(); // controller.handleReveal(); // System.out.println("[MappingDiagramSelectionHandler.select 1] BOT " ); } @Override public void select( List selectedEObjects ) { // System.out.println("[MappingDiagramSelectionHandler.select 2] TOP, selectedObject is: " + selectedEObjects ); // Thread.dumpStack(); clearDependencyHilites(); super.select(selectedEObjects); // System.out.println("[MappingDiagramSelectionHandler.select 2] BOT " ); } @Override public List getSelectedEObjects() { List selectedEObjects = new ArrayList(); Iterator iter = getViewer().getSelectedEditParts().iterator(); Object obj = null; EObject nextEObject = null; while (iter.hasNext()) { obj = iter.next(); if (obj instanceof DiagramEditPart) { DiagramEditPart dep = (DiagramEditPart)obj; nextEObject = null; nextEObject = dep.getModelObject(); if (nextEObject != null && !selectedEObjects.contains(nextEObject)) { selectedEObjects.add(nextEObject); } } } return selectedEObjects; } // This method overides the base class method so we can hilite the extents for selecting a Mapping Class @Override public void hiliteDependencies( Object selectedObject ) { // System.out.println("\n[MappingDiagramSelectionHandler.hiliteDependencies] TOP; selectedObject is: " + selectedObject ); // Thread.dumpStack(); clearDependencyHilites(); EObject selectedEObject = null; EditPart selectedPart = null; if (selectedObject != null && selectedObject instanceof EObject) { selectedEObject = (EObject)selectedObject; selectedPart = findEditPart(selectedEObject, false); if (selectedPart != null && selectedPart instanceof DiagramEditPart) { // System.out.println("[MappingDiagramSelectionHandler.hiliteDependencies] selectedPart is a DiagramEditPart"); // Assume that we want to hilite all "connected" objects here in coarse mapping if (selectedPart instanceof UmlClassifierEditPart) { // get all "source" connections List sConnectionEditParts = ((DiagramEditPart)selectedPart).getSourceConnections(); Iterator sIter = sConnectionEditParts.iterator(); MappingLinkEditPart nextMLEP = null; Object nextObj = null; while (sIter.hasNext()) { nextObj = sIter.next(); if (nextObj instanceof MappingLinkEditPart) { nextMLEP = (MappingLinkEditPart)nextObj; ((DiagramEditPart)nextMLEP.getTarget()).hiliteBackground(UiConstants.Colors.DEPENDENCY); } } } else if (selectedPart instanceof MappingExtentEditPart) { // System.out.println("[MappingDiagramSelectionHandler.hiliteDependencies] selectedPart is a MappingExtentEditPart"); if (getDiagramType().equals(PluginConstants.MAPPING_DIAGRAM_TYPE_ID)) { // get all "source" connections List tConnectionEditParts = ((DiagramEditPart)selectedPart).getTargetConnections(); Iterator tIter = tConnectionEditParts.iterator(); MappingLinkEditPart nextMLEP = null; Object nextObj = null; int iEditPartsProcessed = 0; while (tIter.hasNext()) { nextObj = tIter.next(); if (nextObj instanceof MappingLinkEditPart) { nextMLEP = (MappingLinkEditPart)nextObj; ((DiagramEditPart)nextMLEP.getSource()).hiliteBackground(UiConstants.Colors.DEPENDENCY); ++iEditPartsProcessed; if (iEditPartsProcessed < 2) { getViewer().reveal(nextMLEP.getSource()); } } } } else { // System.out.println("[MappingDiagramSelectionHandler.hiliteDependencies] this is a Detailed Diagram"); // We have a detailed diagram, so the extent selection also means column selection EObject selectedColumn = ((MappingDiagramController)getViewer().getEditor().getDiagramController()).getMappingAdapter().getMappingClassColumn((EObject)selectedObject); if (selectedColumn != null) { selectedPart = findEditPart(selectedColumn, false); if (selectedPart != null) { // selectedEObject = selectedColumn; ((DiagramEditPart)selectedPart).hiliteBackground(UiConstants.Colors.DEPENDENCY); // reveal Classifier Parent DiagramEditPart dep = DiagramUiUtilities.getClassifierParent((DiagramEditPart)selectedPart); if (dep != null) getViewer().reveal(dep); } } } } else if (selectedPart instanceof UmlAttributeEditPart && getDiagramType().equals(PluginConstants.MAPPING_TRANSFORMATION_DIAGRAM_TYPE_ID)) { // System.out.println("[MappingDiagramSelectionHandler.hiliteDependencies] selectedPart is a UmlAttributeEditPart"); super.hiliteDependencies(selectedObject); // Now we add the attribute dependency from the Transformation Helper.. // have to pass in the mapping root TransformationMappingRoot tmr = null; Diagram detailedDiagram = getViewer().getEditor().getDiagram(); if (detailedDiagram != null) { EObject virtualGroup = detailedDiagram.getTarget(); tmr = (TransformationMappingRoot)TransformationHelper.getTransformationMappingRoot(virtualGroup); List allDependencies = new ArrayList(); // Only add source dependencies when the selectedObject is virtual, else there will be // no mapping's defining the selected physical attribute!! if (ModelObjectUtilities.isVirtual(selectedEObject)) allDependencies.addAll(TransformationHelper.getSourceAttributesForTargetAttr(selectedObject, tmr)); // Always look for target attributes because the selected attribute may in a virtual // group that is just one step in a complex tranformation hiearchy. allDependencies.addAll(TransformationHelper.getTargetAttributesForSourceAttr(selectedObject, tmr)); Iterator iter = allDependencies.iterator(); EditPart nextEP = null; EObject nextEObject = null; while (iter.hasNext()) { nextEObject = (EObject)iter.next(); nextEP = findEditPart(nextEObject, false); if (nextEP != null && nextEP instanceof DiagramEditPart) { ((DiagramEditPart)nextEP).hiliteBackground(UiConstants.Colors.DEPENDENCY); } } } } else { super.hiliteDependencies(selectedObject); } } else { // Here we need to check for "attribute" or child type edit parts... (i.e. XmlSequence, etc... EObject selectedColumn = ((MappingDiagramController)getViewer().getEditor().getDiagramController()).getMappingAdapter().getMappingClassColumn((EObject)selectedObject); if (selectedColumn != null) { selectedPart = findEditPart(selectedColumn, false); if (selectedPart != null) { // selectedEObject = selectedColumn; ((DiagramEditPart)selectedPart).hiliteBackground(UiConstants.Colors.DEPENDENCY); // reveal Classifier Parent DiagramEditPart dep = DiagramUiUtilities.getClassifierParent((DiagramEditPart)selectedPart); if (dep != null) getViewer().reveal(dep); } } } } // System.out.println("[MappingDiagramSelectionHandler.hiliteDependencies] BOT"); } // jh 2/13/2006: Fix for Defect 20078: Added this alternate 'hilite' method so we can handle a selection // of an XML Element in the tree // To handle XML Element and XML Attribute public void hiliteDependenciesForTreeSelection( Object selectedObject ) { // System.out.println("\n[MappingDiagramSelectionHandler.hiliteDependenciesForTreeSelection] TOP; selectedObject is: " + // selectedObject ); clearDependencyHilites(); EditPart selectedPart = null; if (selectedObject != null && selectedObject instanceof EObject) { if (selectedObject instanceof XmlElement || selectedObject instanceof XmlAttribute) { // System.out.println("[MappingDiagramSelectionHandler.hiliteDependencies] selectedObject is a XmlElement"); // Here we need to check for "attribute" or child type edit parts... (i.e. XmlSequence, etc... EObject selectedColumn = ((MappingDiagramController)getViewer().getEditor().getDiagramController()).getMappingAdapter().getMappingClassColumn((EObject)selectedObject); if (selectedColumn != null) { selectedPart = findEditPart(selectedColumn, false); if (selectedPart != null) { // selectedEObject = selectedColumn; ((DiagramEditPart)selectedPart).hiliteBackground(UiConstants.Colors.DEPENDENCY); // reveal Classifier Parent DiagramEditPart dep = DiagramUiUtilities.getClassifierParent((DiagramEditPart)selectedPart); if (dep != null) { getViewer().reveal(dep); } return; } } } } // System.out.println("[MappingDiagramSelectionHandler.hiliteDependenciesForTreeSelection] BOT"); } @Override public boolean handleDoubleClick( final EObject selectedObject ) { boolean handledHere = false; // If current diagram is of type MAPPING_COARSE, then if object is Classifier, then we // check for Mapping Class, then open up the DETAILED View. MappingDiagramController controller = (MappingDiagramController)getViewer().getEditor().getDiagramController(); if (controller != null && controller.getMappingType() == PluginConstants.COARSE_MAPPING) { final EditPart selectedEP = findEditPart(selectedObject, false); // Need to see if the selected object is of UmlClassifierAspect and isVirtual if (selectedEP != null && ModelObjectUtilities.isVirtual(selectedObject)) { MetamodelAspect aspect = DiagramUiPlugin.getDiagramAspectManager().getUmlAspect(selectedObject); if (aspect instanceof UmlClassifier) { boolean navigateToDetailedDiagram = true; if (selectedEP instanceof UmlClassifierEditPart && ((UmlClassifierEditPart)selectedEP).doubleClickedName()) { navigateToDetailedDiagram = false; } if (!navigateToDetailedDiagram) { ((EditableEditPart)selectedEP).edit(); handledHere = true; } else { final Diagram detailedDiagram = getDetailedMappingDiagram(selectedObject); if (detailedDiagram != null) { if (getViewer().getEditor().canOpenContext(detailedDiagram)) { UiBusyIndicator.showWhile(Display.getCurrent(), new Runnable() { @Override public void run() { if (selectedEP instanceof EditableEditPart) { // ==> do Edit ((EditableEditPart)selectedEP).edit(); // ==> do Expand // jh 2/28/2006: Fix for Defect 21044: force an expand so we'll see treenodes and // normal // extents in the detailed diagram if (selectedEP instanceof UmlClassifierEditPart) { MappingDiagramController controller = (MappingDiagramController)getViewer().getEditor().getDiagramController(); UmlClassifierEditPart ucep = (UmlClassifierEditPart)selectedEP; MappingClassImpl mci = (MappingClassImpl)ucep.getModelObject(); EList elst = mci.getColumns(); // we need a list of MappingClassColumns for this... controller.notifyElementsRevealed(ucep, elst); } // ==> do Refresh // jh 2/13/2006: Fix for Defect 20182: force a refresh to make sure extents line up // properly in Detailed Diagram. DiagramEditor editor = DiagramEditorUtil.getVisibleDiagramEditor(); if (editor != null && editor.getCurrentModel() != null) { editor.doRefreshDiagram(); editor.getDiagramViewer().setFocus(selectedEP); } } else { getViewer().getEditor().openContext(detailedDiagram); } select(selectedObject); } }); } handledHere = true; } } } } } /* * jh Defect 18919: New case: d-click on another MC root node or other mappable column in the * doc tree while already in a DETAILED DIAGRAM willl reload the DETAILED DIAGRAM editor with the * new MC. */ else if (controller != null && controller.getMappingType() == PluginConstants.DETAILED_MAPPING) { ModelResource modelResource = ModelUtilities.getModelResourceForModelObject(controller.getDocumentEObject()); EditPart selectedEP = findEditPart(selectedObject, false); if (selectedEP != null && selectedEP instanceof EditableEditPart && editHelper.canEdit(selectedObject, modelResource)) { // Check to see if we want to direct edit // System.out.println("[MappingDiagramSelectionHandler.handleDoubleClick] About to call 'NOT coarse!' edit()"); ((EditableEditPart)selectedEP).edit(); handledHere = true; } else if (ModelObjectUtilities.isVirtual(selectedObject) && ModelUtilities.areModelResourcesSame(selectedObject, controller.getCurrentDiagram())) { final Diagram detailedDiagram = getDetailedMappingDiagram(selectedObject); if (detailedDiagram != null) { // proceed only if this diagram is NOT already the current diagram if (detailedDiagram != getViewer().getEditor().getDiagram()) { if (getViewer().getEditor().canOpenContext(detailedDiagram)) { UiBusyIndicator.showWhile(Display.getCurrent(), new Runnable() { @Override public void run() { getViewer().getEditor().openContext(detailedDiagram); select(selectedObject); } }); } } } handledHere = true; } else { // The d-clicked object is NOT in the Mapping's Resource, so we assume it's in a source resource and call open() // to show it's object in a package diagram ModelEditorManager.open(selectedObject, true); handledHere = true; } } else if (controller != null) { EditPart selectedEP = findEditPart(selectedObject, false); if (selectedEP != null && selectedEP instanceof TransformationEditPart && selectedEP instanceof EditableEditPart) { // Check to see if we want to direct edit ((EditableEditPart)selectedEP).edit(); handledHere = true; } else if (ModelObjectUtilities.isVirtual(selectedObject)) { if (selectedEP != null) { if (selectedEP instanceof UmlClassifierEditPart || selectedObject instanceof InputSet) { if (ModelEditorManager.canEdit(selectedObject)) { UiBusyIndicator.showWhile(Display.getCurrent(), new Runnable() { @Override public void run() { ModelEditorManager.edit(selectedObject); } }); handledHere = true; } } } } } return handledHere; } private Diagram getDetailedMappingDiagram( EObject targetEObject ) { return diagramProvider.getDetailedMappingDiagram(targetEObject); } /* (non-Javadoc) * @See org.teiid.designer.diagram.ui.editor.IDiagramSelectionHandler#shouldReveal(org.eclipse.emf.ecore.EObject) */ @Override public boolean shouldReveal( EObject eObject ) { if (TransformationHelper.isSqlTable(eObject)) return true; return false; } }