/*****************************************************************************
* Copyright (c) 2010 Atos Origin.
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
* Patrick Tessier (CEA LIST)-modification
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.editpolicies;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.OpenEditPolicy;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.papyrus.infra.core.editorsfactory.IPageIconsRegistry;
import org.eclipse.papyrus.infra.core.editorsfactory.PageIconsRegistry;
import org.eclipse.papyrus.infra.core.extension.commands.CreationCommandDescriptor;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.utils.EditorUtils;
import org.eclipse.papyrus.infra.gmfdiag.common.DiagramsUtil;
import org.eclipse.papyrus.infra.gmfdiag.navigation.ExistingNavigableElement;
import org.eclipse.papyrus.infra.gmfdiag.navigation.NavigableElement;
import org.eclipse.papyrus.infra.gmfdiag.navigation.NavigationHelper;
import org.eclipse.papyrus.infra.gmfdiag.navigation.preference.INavigationPreferenceConstant;
import org.eclipse.papyrus.infra.hyperlink.helper.AbstractHyperLinkHelper;
import org.eclipse.papyrus.infra.hyperlink.helper.HyperLinkHelperFactory;
import org.eclipse.papyrus.infra.hyperlink.object.HyperLinkObject;
import org.eclipse.papyrus.infra.hyperlink.ui.EditorNavigationDialog;
import org.eclipse.papyrus.infra.hyperlink.ui.HyperLinkManagerShell;
import org.eclipse.papyrus.infra.hyperlink.util.HyperLinkHelpersRegistrationUtil;
import org.eclipse.papyrus.uml.diagram.common.Activator;
import org.eclipse.papyrus.uml.diagram.common.ui.hyperlinkshell.AdvancedHLManager;
import org.eclipse.papyrus.uml.diagram.common.ui.hyperlinkshell.HyperLinkDiagram;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Package;
/**
* This class is used to open a new diagram when the double click is detected.
* It is dependent of papyrus environment
*/
public class NavigationEditPolicy extends OpenEditPolicy {
public static final String NAVIGATION_POLICY = "NavigationEditPolicy";
public NavigationEditPolicy() {
}
/**
*
* @param element
* a UML element
* @return the top package of the given element
*/
public static Package topPackage(Element element) {
if(element.getOwner() == null) {
return (Package)element;
} else {
return topPackage(element.getOwner());
}
}
/**
*
* @param request
* @return get the command to open a new diagram
*/
@Override
protected Command getOpenCommand(Request request) {
final IGraphicalEditPart gep;
// in order to obtain the list of default diagram we need to fin the
// edit part that refers to default diagram
// if this a label of a compartment, the good editpart is the parent
if((IGraphicalEditPart)getHost() instanceof CompartmentEditPart) {
gep = (IGraphicalEditPart)getHost().getParent();
} else {
gep = (IGraphicalEditPart)getHost();
}
final EObject semanticElement = gep.resolveSemanticElement();
// navigable element by using heuristic
List<NavigableElement> navElements = null;
// defaultHyperlinks
final ArrayList<HyperLinkObject> defaultHyperLinkObject = new ArrayList<HyperLinkObject>();
final ArrayList<HyperLinkObject> hyperLinkObjectList;
// Diagrams that will be found by using heuristic
HashMap<NavigableElement, List<Diagram>> existingDiagrams = new HashMap<NavigableElement, List<Diagram>>();
if(semanticElement == null) {
return UnexecutableCommand.INSTANCE;
}
// initialition of code to extract hyperlinks, in the future to do with
// extension points
ArrayList<AbstractHyperLinkHelper> hyperLinkHelpers = new ArrayList<AbstractHyperLinkHelper>();
// hyperLinkHelpers.add(new DiagramHyperLinkHelper());
// hyperLinkHelpers.add(new DocumentHyperLinkHelper());
// hyperLinkHelpers.add(new WebHyperLinkHelper());
hyperLinkHelpers.addAll(HyperLinkHelpersRegistrationUtil.INSTANCE.getAllRegisteredHyperLinkHelper());
final HyperLinkHelperFactory hyperlinkHelperFactory = new HyperLinkHelperFactory(hyperLinkHelpers);
try {
// fill the list of default hyperlinks
hyperLinkObjectList = (ArrayList<HyperLinkObject>)hyperlinkHelperFactory.getAllreferenced(gep.getNotationView());
Iterator<HyperLinkObject> iterator = hyperLinkObjectList.iterator();
while(iterator.hasNext()) {
HyperLinkObject hyperlinkObject = iterator.next();
if(hyperlinkObject.getIsDefault()) {
defaultHyperLinkObject.add(hyperlinkObject);
}
}
// fill navigation by using heuristics
navElements = NavigationHelper.getInstance().getAllNavigableElements(semanticElement);
HashMap<NavigableElement, List<CreationCommandDescriptor>> possibleCreations = new HashMap<NavigableElement, List<CreationCommandDescriptor>>();
// test which kind of navigation by consulting preference
String navigationKind = Activator.getDefault().getPreferenceStore().getString(INavigationPreferenceConstant.PAPYRUS_NAVIGATION_DOUBLECLICK_KIND);
// no naviagation
if(navigationKind.equals(INavigationPreferenceConstant.NO_NAVIGATION)) {
// do nothing
return UnexecutableCommand.INSTANCE;
}
// navigation by using heuristic
// add list of diagram navigables by using heuristic
if(navigationKind.equals(INavigationPreferenceConstant.EXPLICIT_IMPLICIT_NAVIGATION)) {
for(NavigableElement navElement : navElements) {
final EObject element = navElement.getElement();
if(navElement instanceof ExistingNavigableElement) {
List<Diagram> associatedDiagrams = DiagramsUtil.getAssociatedDiagrams(element, null);
// ignore the current diagram
associatedDiagrams.remove(gep.getNotationView().getDiagram());
if(associatedDiagrams != null && !associatedDiagrams.isEmpty()) {
existingDiagrams.put(navElement, associatedDiagrams);
}
}
}
Iterator<List<Diagram>> iter = existingDiagrams.values().iterator();
while(iter.hasNext()) {
List<Diagram> list = iter.next();
Iterator<Diagram> iterDiagram = list.iterator();
while(iterDiagram.hasNext()) {
Diagram diagram = iterDiagram.next();
HyperLinkDiagram hyperLinkDiagram = new HyperLinkDiagram();
hyperLinkDiagram.setDiagram(diagram);
hyperLinkDiagram.setTooltipText(diagram.getName() + " (found by heuristic)");
// look for if a hyperlink already exists
HyperLinkObject foundHyperlink = null;
for(int i = 0; i < defaultHyperLinkObject.size() && foundHyperlink == null; i++) {
if(defaultHyperLinkObject.get(i).getObject().equals(diagram)) {
foundHyperlink = defaultHyperLinkObject.get(i);
}
}
// the diagram was not into the list of existing default
// hyperlink
if(foundHyperlink == null) {
defaultHyperLinkObject.add(hyperLinkDiagram);
}
}
}
}
if(defaultHyperLinkObject.size() == 0) {
Command command = new Command() {
@Override
public void execute() {
EObject semanticElement = gep.getNotationView().getElement();
if(semanticElement instanceof Element) {
HyperLinkManagerShell hyperLinkManagerShell = new AdvancedHLManager(createEditorRegistry(), ((GraphicalEditPart)getHost()).getEditingDomain(), (Element)semanticElement, gep.getNotationView(), topPackage((Element)semanticElement), hyperlinkHelperFactory);
hyperLinkManagerShell.setInput(hyperLinkObjectList);
hyperLinkManagerShell.open();
}
}
};
return command;
}
if(defaultHyperLinkObject.size() == 1) {
// open the diagram
Command command = new Command() {
@Override
public void execute() {
super.execute();
defaultHyperLinkObject.get(0).executeSelectPressed();
}
};
return command;
}
if(defaultHyperLinkObject.size() > 1) {
// open a dialog to choose a diagram
EditorNavigationDialog diagramNavigationDialog = new EditorNavigationDialog(getHost().getViewer().getControl().getShell(), defaultHyperLinkObject);
diagramNavigationDialog.open();
final List<HyperLinkObject> hList = diagramNavigationDialog.getSelectedHyperlinks();
Command command = new Command() {
@Override
public void execute() {
super.execute();
Iterator<HyperLinkObject> iter = hList.iterator();
while(iter.hasNext()) {
HyperLinkObject hyperlinkObject = iter.next();
hyperlinkObject.executeSelectPressed();
}
}
};
return command;
}
} catch (Exception e) {
org.eclipse.papyrus.uml.diagram.common.Activator.log.error("Impossible to load hyperlinks", e);
}
return UnexecutableCommand.INSTANCE;
}
/**
* Return the EditorRegistry for nested editor descriptors. Subclass should
* implements this method in order to return the registry associated to the
* extension point namespace.
*
* @return the EditorRegistry for nested editor descriptors
*
* @generated NOT
*/
protected IPageIconsRegistry createEditorRegistry() {
try {
return EditorUtils.getServiceRegistry().getService(IPageIconsRegistry.class);
} catch (ServiceException e) {
// Return an empty registry always providing null;
return new PageIconsRegistry();
}
}
}