/*
* 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;
}
}