summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoit Maggi2014-01-21 11:24:17 (EST)
committervlorenzo2014-01-30 10:14:29 (EST)
commit51f720f20455548de3e85055ae170c61211fddbe (patch)
tree4f49890af694497ee2bf12c783422a9e87ea13f8
parentb23aaf84507b554e9962d21490c6b0a87aa167e3 (diff)
downloadorg.eclipse.papyrus-51f720f20455548de3e85055ae170c61211fddbe.zip
org.eclipse.papyrus-51f720f20455548de3e85055ae170c61211fddbe.tar.gz
org.eclipse.papyrus-51f720f20455548de3e85055ae170c61211fddbe.tar.bz2
Bug 423666 - Show All Related Link can display erroneous connectors in
multi-level IBDs A connector with multiple view is now correctly redraw. Change-Id: I1217f946c8310a17aea46dc374f9b6b3a4984cf1 Signed-off-by: Benoit Maggi <benoit.maggi@cea.fr>
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AbstractShowHideRelatedLinkEditPolicy.java1433
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/Domain2Notation.java109
-rw-r--r--plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.internalblock/src/org/eclipse/papyrus/sysml/diagram/internalblock/edit/policy/ShowHideRelatedLinkEditPolicy.java705
-rw-r--r--plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/utils/ConnectorUtils.java729
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractUMLShowHideRelatedLinkEditPolicy.java536
5 files changed, 1881 insertions, 1631 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AbstractShowHideRelatedLinkEditPolicy.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AbstractShowHideRelatedLinkEditPolicy.java
index 0923b8c..9cc52bc 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AbstractShowHideRelatedLinkEditPolicy.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AbstractShowHideRelatedLinkEditPolicy.java
@@ -1,706 +1,727 @@
-/*****************************************************************************
- * Copyright (c) 2013 CEA LIST.
- *
- *
- * 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:
- * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.gmfdiag.common.editpolicies;
-
-import java.rmi.UnexpectedException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.Request;
-import org.eclipse.gef.commands.Command;
-import org.eclipse.gef.editpolicies.AbstractEditPolicy;
-import org.eclipse.gef.requests.GroupRequest;
-import org.eclipse.gmf.runtime.common.core.command.CommandResult;
-import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
-import org.eclipse.gmf.runtime.common.core.command.ICommand;
-import org.eclipse.gmf.runtime.diagram.core.commands.SetPropertyCommand;
-import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
-import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
-import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
-import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
-import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
-import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
-import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
-import org.eclipse.gmf.runtime.emf.type.core.IElementType;
-import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
-import org.eclipse.gmf.runtime.notation.BasicCompartment;
-import org.eclipse.gmf.runtime.notation.Connector;
-import org.eclipse.gmf.runtime.notation.Diagram;
-import org.eclipse.gmf.runtime.notation.Shape;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.gmf.tooling.runtime.update.DiagramUpdater;
-import org.eclipse.gmf.tooling.runtime.update.UpdaterLinkDescriptor;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.papyrus.infra.core.services.ServiceException;
-import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
-import org.eclipse.papyrus.infra.gmfdiag.common.commands.requests.ShowHideRelatedLinkRequest;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.ServiceUtilsForEditPart;
-
-
-/**
- *
- * The editPolicy used to show/hide links
- *
- */
-//Inspired from EcoreTools source code
-public abstract class AbstractShowHideRelatedLinkEditPolicy extends AbstractEditPolicy implements IDiagramInformationProviderEditPolicy {
-
- /**
- * the key for this edit policy
- */
- public static final String SHOW_HIDE_RELATED_LINK_ROLE = "ShowHideRelatedLinkEditPolicy"; //$NON-NLS-1$
-
- /**
- *
- * Constructor.
- *
- * @param host
- * the host for this edit policy
- */
- public AbstractShowHideRelatedLinkEditPolicy(final DiagramEditPart host) {
- setHost(host);
- }
-
- /**
- *
- * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getCommand(org.eclipse.gef.Request)
- *
- * @param req
- * @return
- */
- @Override
- public Command getCommand(final Request req) {
- if(understandsRequest(req)) {
- final ShowHideRelatedLinkRequest request = (ShowHideRelatedLinkRequest)req;
-
- //0. Obtain the required informations
- //--the map between semantic eobjects and existing views
- final Map<EObject, View> domain2NotationMap = new HashMap<EObject, View>();
-
- //-- the map between selected EditPart and the semantic existing links
- final Map<EditPart, Set<EObject>> availableLinks = new HashMap<EditPart, Set<EObject>>();
-
- //-- the list of the links which are currently visible on the diagram
- final Set<EObject> visibleLinks = new HashSet<EObject>();
-
- //-- the link descriptors
- final Set<UpdaterLinkDescriptor> linksDescriptors = new HashSet<UpdaterLinkDescriptor>();
-
-
- //1. resolve all to avoid concurrent modification exception during the call of the method collectPartRelatedLinks
- EcoreUtil.resolveAll(getEditingDomain().getResourceSet());
-
- //1. bis To register all EditPart in the global visualIDRegistry
- getHost().refresh();
-
- //2. we associate each view to a semantic element
- mapModel((View)getHost().getAdapter(View.class), domain2NotationMap);
-
- //3.we collect the link descriptors
- for(final EditPart currentEp : request.getSelectedEditParts()) {
- final View view = (View)currentEp.getAdapter(View.class);
- if(view != null) {
- final Collection<? extends UpdaterLinkDescriptor> desc = collectPartRelatedLinks(view, domain2NotationMap);
- linksDescriptors.addAll(desc);
- final Set<EObject> modelLinks = new HashSet<EObject>();
- final Iterator<? extends UpdaterLinkDescriptor> iter = desc.iterator();
-
- while(iter.hasNext()) {
- final UpdaterLinkDescriptor current = iter.next();
- final EObject link = current.getModelElement();
- final View dest = domain2NotationMap.get(current.getDestination());
- final View source = domain2NotationMap.get(current.getSource());
-
- //we add only links for which source and target are already on the diagram
- if(dest != null && source != null) {
- modelLinks.add(link);
- }
-
- //we build the list of the visible links
- View linkView = domain2NotationMap.get(link);
- if(linkView != null && linkView.isVisible()) {
- visibleLinks.add(link);
- }
- }
- availableLinks.put(currentEp, modelLinks);
- }
- }
- switch(request.getMode()) {
- case OPEN_DIALOG:
- return getShowHideRelatedLinkCommandWithDialog(request.getSelectedEditParts(), availableLinks, visibleLinks, domain2NotationMap, linksDescriptors);
- case SHOW_ALL_LINK_BETWEEN_SELECTED_ELEMENT:
- final Collection<EObject> possibleEnds = new HashSet<EObject>();
- for(final EditPart currentIGraphical : request.getSelectedEditParts()) {
- possibleEnds.add((EObject)currentIGraphical.getAdapter(EObject.class));
- }
- final Collection<UpdaterLinkDescriptor> toRemove = new ArrayList<UpdaterLinkDescriptor>();
- for(final UpdaterLinkDescriptor current : linksDescriptors) {
- final EObject source = current.getSource();
- final EObject target = current.getDestination();
- if(!possibleEnds.contains(source) || !possibleEnds.contains(target)) {
- toRemove.add(current);
- }
- }
- linksDescriptors.removeAll(toRemove);
- //not necessary to remove the eobject links from the map availableLinks
- case SHOW_ALL_LINK_IN_DIAGRAM:
- final Set<EObject> allLinks = new HashSet<EObject>();
- for(final Collection<EObject> currentColl : availableLinks.values()) {
- allLinks.addAll(currentColl);
- }
- allLinks.removeAll(visibleLinks);
- return new ICommandProxy(getShowHideRelatedLinkCommand(getEditingDomain(), allLinks, Collections.emptyList(), domain2NotationMap, linksDescriptors));
- default:
- break;
- }
- }
- return null;
- }
-
- /**
- * Collects all related links for view
- *
- * @param view
- * @param domain2NotationMap
- *
- * @return linkdescriptors
- */
- protected Collection<? extends UpdaterLinkDescriptor> collectPartRelatedLinks(final View view, final Map<EObject, View> domain2NotationMap) {
- Collection<UpdaterLinkDescriptor> result = new LinkedList<UpdaterLinkDescriptor>();
- DiagramUpdater diagramUpdater = getDiagramUpdater();
- // We must prevent duplicate descriptors
- List<?> outgoingDescriptors = diagramUpdater.getOutgoingLinks(view);
- cleanAdd(result, view, outgoingDescriptors, domain2NotationMap);
-
- List<?> incomingDescriptors = diagramUpdater.getIncomingLinks(view);
- cleanAdd(result, view, incomingDescriptors, domain2NotationMap);
-
- if(!domain2NotationMap.containsKey(view.getElement()) || view.getEAnnotation("Shortcut") == null) { //$NON-NLS-1$
- domain2NotationMap.put(view.getElement(), view);
- }
-
- return removeInvalidLinkDescriptor(result);
- }
-
- /**
- *
- * @return
- * the current diagram; hosting this edit policy
- */
- protected Diagram getCurrentDiagram() {
- return (Diagram)getHost().getAdapter(Diagram.class);
- }
-
-
- /**
- *
- * @param descriptors
- * the link descriptor
- * @return
- * the collection of link descriptors without some invalid descriptor (we get this case when the link doesn't have source AND target, but
- * only ends
- */
- protected Collection<UpdaterLinkDescriptor> removeInvalidLinkDescriptor(final Collection<UpdaterLinkDescriptor> descriptors) {
- final Collection<UpdaterLinkDescriptor> toRemove = new ArrayList<UpdaterLinkDescriptor>();
- final Collection<UpdaterLinkDescriptor> toAdd = new ArrayList<UpdaterLinkDescriptor>();
- for(final UpdaterLinkDescriptor current : descriptors) {
- if(current.getModelElement() == null) {
- final IElementType elementType = (IElementType)current.getSemanticAdapter().getAdapter(IElementType.class);
- final EdgeWithNoSemanticElementRepresentationImpl noSemantic = new EdgeWithNoSemanticElementRepresentationImpl(current.getSource(), current.getDestination(), ((IHintedType)elementType).getSemanticHint());
- final UpdaterLinkDescriptor replacement = new UpdaterLinkDescriptor(current.getSource(), current.getDestination(), noSemantic, elementType, current.getVisualID());
- toRemove.add(current);
- toAdd.add(replacement);
- }
- }
-
- descriptors.removeAll(toRemove);
- descriptors.addAll(toAdd);
- return descriptors;
- }
-
- /**
- *
- * @param result
- * the result of the call to this method
- * @param view
- * the current view
- * @param descriptors
- * links descriptors for links related to this view
- * @param domain2NotationMap
- * the map between model element and views
- */
- protected void cleanAdd(Collection<UpdaterLinkDescriptor> result, View view, List<?> descriptors, Map<EObject, View> domain2NotationMap) {
- for(Object object : descriptors) {
- if(false == object instanceof UpdaterLinkDescriptor) {
- continue;
- }
- UpdaterLinkDescriptor descriptor = (UpdaterLinkDescriptor)object;
- if(cleanContains(result, descriptor)) {
- continue;
- }
- // check owner
- if(!isOwner(view, descriptor)) {
- continue;
- }
- result.add(descriptor);
- }
- }
-
- private boolean isOwner(View view, UpdaterLinkDescriptor descriptor) {
- EObject source = descriptor.getSource();
- EObject dest = descriptor.getDestination();
- if(source != null && source.equals(view.getElement())) {
- return true;
- }
- if(dest != null && dest.equals(view.getElement())) {
- return true;
- }
- return false;
- }
-
- /**
- * Detect if similar descriptor already exist in given collection.
- *
- * @param collection
- * the collection of unique ingoing and outgoing links descriptors
- * @param umlLinkDescriptor
- * the descriptor to search
- * @return true if already exist
- */
- private boolean cleanContains(Collection<? extends UpdaterLinkDescriptor> collection, UpdaterLinkDescriptor umlLinkDescriptor) {
- for(Object object : collection) {
- if(object instanceof UpdaterLinkDescriptor) {
- UpdaterLinkDescriptor descriptor = (UpdaterLinkDescriptor)object;
- if(descriptor.getModelElement() == umlLinkDescriptor.getModelElement() && descriptor.getSource() == umlLinkDescriptor.getSource() && descriptor.getDestination() == umlLinkDescriptor.getDestination() && descriptor.getVisualID() == umlLinkDescriptor.getVisualID()) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- *
- * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#understandsRequest(org.eclipse.gef.Request)
- *
- * @param request
- * @return
- */
- @Override
- public boolean understandsRequest(final Request request) {
- return request instanceof ShowHideRelatedLinkRequest;
- }
-
- /**
- *
- * @param selectedEditParts
- * the selected edit parts
- * @param availableLinks
- * a map with the selected edit parts and their available links
- * @param domain2NotationMap
- * a map between existing views and semantic elements
- * @param linksDescriptors
- * the link descriptors
- * @return
- * the command to open a dialog and Show/Hide the related links
- */
- protected abstract Command getShowHideRelatedLinkCommandWithDialog(final Collection<EditPart> selectedEditParts, final Map<EditPart, Set<EObject>> availableLinks, final Set<EObject> visibleLinks, final Map<EObject, View> domain2NotationMap, Collection<UpdaterLinkDescriptor> linksDescriptors);
-
- /**
- *
- * @return
- * the editing domain to use
- */
- protected final TransactionalEditingDomain getEditingDomain() {
- try {
- return ServiceUtilsForEditPart.getInstance().getTransactionalEditingDomain(getHost());
- } catch (ServiceException e) {
- Activator.log.error("Editing Domain not found", e); //$NON-NLS-1$
- }
- return null;
- }
-
- /**
- *
- * @param domain
- * the editing domain to use
- * @param previousCommand
- * the previous command
- * @param initialSelection
- * the initial selection
- * @param domain2NotationMap
- * the map referencing the eobject to their existing view
- * @param linkDescriptor
- * the link descriptors
- * @return
- * the command to show/hide links according to the previous command result
- */
- protected ICommand getComputeCommandResultCommand(final TransactionalEditingDomain domain, final ICommand previousCommand, final Set<EObject> initialSelection, final Map<EObject, View> domain2NotationMap, final Collection<UpdaterLinkDescriptor> linkDescriptor) {
- final ICommand computeCommand = new AbstractTransactionalCommand(domain, "Compute Result", null) {//$NON-NLS-1$
-
- /**
- *
- * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor,
- * org.eclipse.core.runtime.IAdaptable)
- *
- * @param monitor
- * @param info
- * @return
- * @throws ExecutionException
- */
- @Override
- protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
- final Object returnedValue = previousCommand.getCommandResult().getReturnValue();
- if(previousCommand.getCommandResult().getStatus().isOK()) {
- if(returnedValue instanceof Collection<?>) {
- final Collection<?> res = (Collection<?>)returnedValue;
- final Set<?> toAdd = new HashSet<Object>(res);
- toAdd.removeAll(initialSelection);
- final Set<?> toHide = new HashSet<Object>(initialSelection);
- toHide.removeAll(res);
- final ICommand cmd = getShowHideRelatedLinkCommand(domain, toAdd, toHide, domain2NotationMap, linkDescriptor);
- if(cmd.canExecute()) {
- cmd.execute(monitor, info);
- } else {
- Activator.log.error(new UnexpectedException("The command is not executable"));//$NON-NLS-1$
- }
- }
- } else {
- return previousCommand.getCommandResult();
- }
- return CommandResult.newOKCommandResult(returnedValue);
- }
- };
- return computeCommand;
- }
-
- /**
- *
- * @param domain
- * the editing domain
- * @param toShow
- * the list of the link to show
- * @param toHide
- * the list of the link to hide
- * @param domain2NotationMap
- * a map linking the eobject to their view
- * @param linkDescriptors
- * the link descriptor
- * @return
- * the command to show/hide the links, according to the args of this method
- */
- protected final ICommand getShowHideRelatedLinkCommand(final TransactionalEditingDomain domain, final Collection<?> toShow, final Collection<?> toHide, final Map<EObject, View> domain2NotationMap, final Collection<? extends UpdaterLinkDescriptor> linkDescriptors) {
- final CompositeCommand compositeCommand = new CompositeCommand("Show/Hide Related Link");//$NON-NLS-1$
- for(final Object current : toShow) {
- if(current instanceof EObject) {
- final ICommand tmp = getShowLinkCommand(domain, (EObject)current, domain2NotationMap, linkDescriptors);
- if(tmp != null && tmp.canExecute()) {
- compositeCommand.add(tmp);
- }
- }
- }
- for(final Object current : toHide) {
- if(current instanceof EObject) {
- final ICommand tmp = getHideLinkCommand(domain, (EObject)current, domain2NotationMap, linkDescriptors);
- if(tmp != null && tmp.canExecute()) {
- compositeCommand.add(tmp);
- }
- }
- }
- return compositeCommand;
- }
-
-
- /**
- *
- * @param domain
- * the editing domain
- * @param linkToHide
- * the link to hide
- * @param domain2NotationMap
- * the map between eobjects and views
- * @param linkDescriptors
- * the link descriptors
- * @return
- * the command to hide the wanted link
- */
- protected ICommand getHideLinkCommand(final TransactionalEditingDomain domain, final EObject linkToHide, final Map<EObject, View> domain2NotationMap, final Collection<? extends UpdaterLinkDescriptor> linkDescriptors) {
- final UpdaterLinkDescriptor descriptor = getLinkDescriptor(linkToHide, linkDescriptors);
- if(descriptor != null) {
- final View view = domain2NotationMap.get(linkToHide);
- final EditPart editPart = DiagramEditPartsUtil.getEditPartFromView(view, getHost());
- return new CommandProxy(editPart.getCommand(new GroupRequest(RequestConstants.REQ_DELETE)));
- }
- return null;
- }
-
- /**
- *
- * @param link
- * a link
- * @param descriptors
- * the list of the known descriptors
- * @return
- * the link descriptor for this link or <code>null</code> if not found
- */
- protected final UpdaterLinkDescriptor getLinkDescriptor(final EObject link, final Collection<? extends UpdaterLinkDescriptor> descriptors) {
- final Iterator<? extends UpdaterLinkDescriptor> iter = descriptors.iterator();
- while(iter.hasNext()) {
- final UpdaterLinkDescriptor current = iter.next();
- if(current.getModelElement() == link) {
- return current;
- }
- }
- return null;
- }
-
-
-
- /**
- * Maps view
- *
- * @param view
- * @param domain2NotationMap
- */
- protected void mapModel(View view, Map<EObject, View> domain2NotationMap) {
- if(!domain2NotationMap.containsKey(view.getElement()) || view.getEAnnotation("Shortcut") == null) { //$NON-NLS-1$
- if((view instanceof Connector || view instanceof Shape) && !(view instanceof BasicCompartment)) {
- EObject element = view.getElement();
- if(element == null) {
- final EObject source = ((Connector)view).getSource().getElement();
- final EObject target = ((Connector)view).getTarget().getElement();
- element = new EdgeWithNoSemanticElementRepresentationImpl(source, target, view.getType());
- }
- domain2NotationMap.put(element, view);
- }
- }
-
- @SuppressWarnings("unchecked")//$NON-NLS-1$
- List<View> children = view.getChildren();
- for(View child : children) {
- mapModel(child, domain2NotationMap);
- }
- @SuppressWarnings("unchecked")//$NON-NLS-1$
- List<View> sourceEdges = view.getSourceEdges();
- for(View edge : sourceEdges) {
- mapModel(edge, domain2NotationMap);
- }
- }
-
-
- /**
- *
- * @param domain
- * the editing domain to use for this command
- * @param linkToShow
- * a link to show
- * @param domain2NotationMap
- * @param linkDescriptors
- * @return
- * the command to display the link on the diagram
- */
- protected ICommand getShowLinkCommand(final TransactionalEditingDomain domain, final EObject linkToShow, final Map<EObject, View> domain2NotationMap, final Collection<? extends UpdaterLinkDescriptor> linkDescriptors) {
- mapModel((View)getHost().getAdapter(View.class), domain2NotationMap);
- final View view = domain2NotationMap.get(linkToShow);
- if(view != null) {
- return new SetPropertyCommand(domain, "Restore related linksCommand show view", new EObjectAdapter(view), Properties.ID_ISVISIBLE, Boolean.TRUE);//$NON-NLS-1$
- } else {//we need to recreate the view
-
- //we look for the link descriptor
- UpdaterLinkDescriptor descriptor = getLinkDescriptor(linkToShow, linkDescriptors);
- if(linkToShow instanceof EdgeWithNoSemanticElementRepresentationImpl) {
- //we replace the specific link descriptor by a new one, with no model element (if not the view provider refuse to create the view
- final IElementType elementType = (IElementType)descriptor.getSemanticAdapter().getAdapter(IElementType.class);
- descriptor = new UpdaterLinkDescriptor(descriptor.getSource(), descriptor.getDestination(), elementType, descriptor.getVisualID());
- }
- if(descriptor != null) {
- EditPart sourceEditPart = getEditPart(descriptor.getSource(), domain2NotationMap);
- EditPart targetEditPart = getEditPart(descriptor.getDestination(), domain2NotationMap);
-
- // If the parts are still null...
- if(sourceEditPart == null || targetEditPart == null) {
- return null;
- }
- String semanticHint = getSemanticHint(linkToShow);
- if(semanticHint == null) {
- semanticHint = ((IHintedType)descriptor.getSemanticAdapter().getAdapter(IElementType.class)).getSemanticHint();
- }
- CreateConnectionViewRequest.ConnectionViewDescriptor viewDescriptor = new CreateConnectionViewRequest.ConnectionViewDescriptor(descriptor.getSemanticAdapter(), semanticHint, ViewUtil.APPEND, false, ((GraphicalEditPart)getHost()).getDiagramPreferencesHint());
- CreateConnectionViewRequest ccr = new CreateConnectionViewRequest(viewDescriptor);
- ccr.setType(RequestConstants.REQ_CONNECTION_START);
- ccr.setSourceEditPart(sourceEditPart);
- sourceEditPart.getCommand(ccr);
- ccr.setTargetEditPart(targetEditPart);
- ccr.setType(RequestConstants.REQ_CONNECTION_END);
- return new CommandProxy(targetEditPart.getCommand(ccr));
- }
- }
- return null;
- }
-
- /**
- *
- * @param eobject
- * an eobject
- * @return
- * the semantic hint to use for this eobject
- */
- protected String getSemanticHint(final EObject eobject) {
- return null;
- }
-
- /**
- * Retrieves editpart corresponding to domainModelElement
- *
- * @param domainModelElement
- * @param domain2NotationMap
- */
- protected EditPart getEditPart(final EObject domainModelElement, Map<? extends EObject, ? extends View> domain2NotationMap) {
- View view = domain2NotationMap.get(domainModelElement);
- if(view != null) {
- return (EditPart)getHost().getViewer().getEditPartRegistry().get(view);
- }
- return null;
- }
-
- /**
- *
- * @return
- * the label provider to use in the dialog
- */
- protected abstract ILabelProvider getLabelProvider();
-
- /**
- *
- * Content provider for the dialog
- *
- */
- public static class LinkContentProvider implements ITreeContentProvider {
-
- /**
- * the map between selected graphical elements and their available links
- */
- private final Map<EditPart, Set<EObject>> availableLinks;
-
-
- public LinkContentProvider(final Map<EditPart, Set<EObject>> availableLinks) {
- this.availableLinks = availableLinks;
- }
-
- /**
- *
- * @see org.eclipse.jface.viewers.IContentProvider#dispose()
- *
- */
- public void dispose() {
- this.availableLinks.clear();
- }
-
- /**
- *
- * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
- *
- * @param viewer
- * @param oldInput
- * @param newInput
- */
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- //nothing to do
- }
-
- /**
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
- *
- * @param inputElement
- * @return
- */
- public Object[] getElements(Object inputElement) {
- if(inputElement instanceof Collection<?>) {
- return ((Collection<?>)inputElement).toArray();
- }
- return new Object[0];
- }
-
- /**
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
- *
- * @param parentElement
- * @return
- */
- public Object[] getChildren(Object parentElement) {
- if(this.availableLinks.containsKey(parentElement)) {
- return this.availableLinks.get(parentElement).toArray();
- }
- return new Object[0];
- }
-
- /**
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
- *
- * @param element
- * @return
- */
- public Object getParent(Object element) {
- final Iterator<Entry<EditPart, Set<EObject>>> iter = this.availableLinks.entrySet().iterator();
- while(iter.hasNext()) {
- final Entry<EditPart, Set<EObject>> current = iter.next();
- if(current.getValue().contains(element)) {
- return current.getKey();
- }
- }
- return null;
- }
-
- /**
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
- *
- * @param element
- * @return
- */
- public boolean hasChildren(Object element) {
- if(this.availableLinks.containsKey(element)) {
- return this.availableLinks.get(element).size() != 0;
- }
- return false;
- }
-
- }
-
-}
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.common.editpolicies;
+
+import java.rmi.UnexpectedException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.editpolicies.AbstractEditPolicy;
+import org.eclipse.gef.requests.GroupRequest;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.diagram.core.commands.SetPropertyCommand;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
+import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
+import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.gmf.tooling.runtime.update.DiagramUpdater;
+import org.eclipse.gmf.tooling.runtime.update.UpdaterLinkDescriptor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
+import org.eclipse.papyrus.infra.gmfdiag.common.commands.requests.ShowHideRelatedLinkRequest;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.Domain2Notation;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.ServiceUtilsForEditPart;
+import org.eclipse.uml2.uml.Connector;
+
+
+/**
+ * The editPolicy used to show/hide links.
+ */
+//Inspired from EcoreTools source code
+public abstract class AbstractShowHideRelatedLinkEditPolicy extends AbstractEditPolicy implements IDiagramInformationProviderEditPolicy {
+
+ /** the key for this edit policy. */
+ public static final String SHOW_HIDE_RELATED_LINK_ROLE = "ShowHideRelatedLinkEditPolicy"; //$NON-NLS-1$
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param host
+ * the host for this edit policy
+ */
+ public AbstractShowHideRelatedLinkEditPolicy(final DiagramEditPart host) {
+ setHost(host);
+ }
+
+
+ /**
+ * Gets the command.
+ *
+ * @param req the req
+ * @return the command
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#getCommand(org.eclipse.gef.Request)
+ */
+ @Override
+ public Command getCommand(final Request req) {
+ if(understandsRequest(req)) {
+ final ShowHideRelatedLinkRequest request = (ShowHideRelatedLinkRequest)req;
+
+ //0. Obtain the required informations
+ //--the map between semantic eobjects and existing views
+ // final Map<EObject, View> domain2NotationMap = new HashMap<EObject, View>();
+
+ final Domain2Notation domain2NotationMap = new Domain2Notation();
+
+ //-- the map between selected EditPart and the semantic existing links
+ final Map<EditPart, Set<EObject>> availableLinks = new HashMap<EditPart, Set<EObject>>();
+
+ //-- the list of the links which are currently visible on the diagram
+ final Set<EObject> visibleLinks = new HashSet<EObject>();
+
+ //-- the link descriptors
+ final Set<UpdaterLinkDescriptor> linksDescriptors = new HashSet<UpdaterLinkDescriptor>();
+
+
+ //1. resolve all to avoid concurrent modification exception during the call of the method collectPartRelatedLinks
+ EcoreUtil.resolveAll(getEditingDomain().getResourceSet());
+
+ //1. bis To register all EditPart in the global visualIDRegistry
+ getHost().refresh();
+
+ //2. we associate each view to a semantic element
+ domain2NotationMap.mapModel((View)getHost().getAdapter(View.class));
+
+ //3.we collect the link descriptors
+ for(final EditPart currentEp : request.getSelectedEditParts()) {
+ final View view = (View)currentEp.getAdapter(View.class);
+ if(view != null) {
+ final Collection<? extends UpdaterLinkDescriptor> desc = collectPartRelatedLinks(view, domain2NotationMap);
+ linksDescriptors.addAll(desc);
+ final Set<EObject> modelLinks = new HashSet<EObject>();
+ final Iterator<? extends UpdaterLinkDescriptor> iter = desc.iterator();
+
+ while(iter.hasNext()) {
+ final UpdaterLinkDescriptor current = iter.next();
+ final EObject link = current.getModelElement();
+ EObject destination = current.getDestination();
+ final View dest = domain2NotationMap.getFirstView(destination);
+ EObject source2 = current.getSource();
+ final View source = domain2NotationMap.getFirstView(source2);
+
+ //we add only links for which at least one source and one target are already on the diagram
+ if(dest != null && source != null) {
+ modelLinks.add(link);
+ }
+
+ //we build the list of the visible links
+
+ View linkView = domain2NotationMap.getFirstView(link);
+ if(linkView != null && linkView.isVisible()) {
+ visibleLinks.add(link);
+ }
+ }
+ availableLinks.put(currentEp, modelLinks);
+ }
+ }
+ switch(request.getMode()) {
+ case OPEN_DIALOG:
+ return getShowHideRelatedLinkCommandWithDialog(request.getSelectedEditParts(), availableLinks, visibleLinks, domain2NotationMap, linksDescriptors);
+ case SHOW_ALL_LINK_BETWEEN_SELECTED_ELEMENT:
+ final Collection<EObject> possibleEnds = new HashSet<EObject>();
+ for(final EditPart currentIGraphical : request.getSelectedEditParts()) {
+ possibleEnds.add((EObject)currentIGraphical.getAdapter(EObject.class));
+ }
+ final Collection<UpdaterLinkDescriptor> toRemove = new ArrayList<UpdaterLinkDescriptor>();
+ for(final UpdaterLinkDescriptor current : linksDescriptors) {
+ final EObject source = current.getSource();
+ final EObject target = current.getDestination();
+ if(!possibleEnds.contains(source) || !possibleEnds.contains(target)) {
+ toRemove.add(current);
+ }
+ }
+ linksDescriptors.removeAll(toRemove);
+ //not necessary to remove the eobject links from the map availableLinks
+ case SHOW_ALL_LINK_IN_DIAGRAM:
+ final Set<EObject> allLinks = new HashSet<EObject>();
+ for(final Collection<EObject> currentColl : availableLinks.values()) {
+ allLinks.addAll(currentColl);
+ }
+ return new ICommandProxy(getShowHideRelatedLinkCommand(getEditingDomain(), allLinks, Collections.emptyList(), domain2NotationMap, linksDescriptors));
+ default:
+ break;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Collects all related links for view.
+ *
+ * @param view the view
+ * @param domain2NotationMap the domain2 notation map
+ * @return linkdescriptors
+ */
+ protected Collection<? extends UpdaterLinkDescriptor> collectPartRelatedLinks(final View view, final Domain2Notation domain2NotationMap) {
+ Collection<UpdaterLinkDescriptor> result = new LinkedList<UpdaterLinkDescriptor>();
+ DiagramUpdater diagramUpdater = getDiagramUpdater();
+
+ // We must prevent duplicate descriptors
+ List<? extends UpdaterLinkDescriptor> outgoingDescriptors = diagramUpdater.getOutgoingLinks(view);
+ cleanAdd(result, view, outgoingDescriptors, domain2NotationMap);
+
+ List<? extends UpdaterLinkDescriptor> incomingDescriptors = diagramUpdater.getIncomingLinks(view);
+ cleanAdd(result, view, incomingDescriptors, domain2NotationMap);
+
+ if(!domain2NotationMap.containsKey(view.getElement()) || view.getEAnnotation("Shortcut") == null) { //$NON-NLS-1$
+ domain2NotationMap.putView(view);
+ }
+
+ return removeInvalidLinkDescriptor(result);
+ }
+
+ /**
+ * Gets the current diagram.
+ *
+ * @return the current diagram
+ * the current diagram; hosting this edit policy
+ */
+ protected Diagram getCurrentDiagram() {
+ return (Diagram)getHost().getAdapter(Diagram.class);
+ }
+
+
+ /**
+ * Removes the invalid link descriptor.
+ *
+ * @param descriptors the link descriptor
+ * @return the collection
+ * the collection of link descriptors without some invalid descriptor (we get this case when the link doesn't have source AND target, but
+ * only ends
+ */
+ protected Collection<UpdaterLinkDescriptor> removeInvalidLinkDescriptor(final Collection<UpdaterLinkDescriptor> descriptors) {
+ final Collection<UpdaterLinkDescriptor> toRemove = new ArrayList<UpdaterLinkDescriptor>();
+ final Collection<UpdaterLinkDescriptor> toAdd = new ArrayList<UpdaterLinkDescriptor>();
+ for(final UpdaterLinkDescriptor current : descriptors) {
+ if(current.getModelElement() == null) {
+ final IElementType elementType = (IElementType)current.getSemanticAdapter().getAdapter(IElementType.class);
+ final EdgeWithNoSemanticElementRepresentationImpl noSemantic = new EdgeWithNoSemanticElementRepresentationImpl(current.getSource(), current.getDestination(), ((IHintedType)elementType).getSemanticHint());
+ final UpdaterLinkDescriptor replacement = new UpdaterLinkDescriptor(current.getSource(), current.getDestination(), noSemantic, elementType, current.getVisualID());
+ toRemove.add(current);
+ toAdd.add(replacement);
+ }
+ }
+
+ descriptors.removeAll(toRemove);
+ descriptors.addAll(toAdd);
+ return descriptors;
+ }
+
+ /**
+ * Clean add.
+ *
+ * @param result the result of the call to this method
+ * @param view the current view
+ * @param descriptors links descriptors for links related to this view
+ * @param domain2NotationMap the map between model element and views
+ */
+ protected void cleanAdd(Collection<UpdaterLinkDescriptor> result, View view, List<? extends UpdaterLinkDescriptor> descriptors, final Domain2Notation domain2NotationMap) {
+ for(UpdaterLinkDescriptor updaterLinkDescriptor : descriptors) {
+ if(cleanContains(result, updaterLinkDescriptor)) {
+ continue;
+ }
+ // check owner
+ if(!isOwner(view, updaterLinkDescriptor)) {
+ continue;
+ }
+ result.add(updaterLinkDescriptor);
+ }
+ }
+
+ /**
+ * Checks if is owner.
+ *
+ * @param view the view
+ * @param descriptor the descriptor
+ * @return true, if is owner
+ */
+ private boolean isOwner(View view, UpdaterLinkDescriptor descriptor) {
+ EObject source = descriptor.getSource();
+ EObject dest = descriptor.getDestination();
+ if(source != null && source.equals(view.getElement())) {
+ return true;
+ }
+ if(dest != null && dest.equals(view.getElement())) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Detect if similar descriptor already exist in given collection.
+ *
+ * @param collection
+ * the collection of unique ingoing and outgoing links descriptors
+ * @param umlLinkDescriptor
+ * the descriptor to search
+ * @return true if already exist
+ */
+ private boolean cleanContains(Collection<? extends UpdaterLinkDescriptor> collection, UpdaterLinkDescriptor umlLinkDescriptor) {
+ for(UpdaterLinkDescriptor descriptor : collection) {
+ if(descriptor.getModelElement() == umlLinkDescriptor.getModelElement() && descriptor.getSource() == umlLinkDescriptor.getSource() && descriptor.getDestination() == umlLinkDescriptor.getDestination() && descriptor.getVisualID() == umlLinkDescriptor.getVisualID()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Understands request.
+ *
+ * @param request the request
+ * @return true, if successful
+ * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#understandsRequest(org.eclipse.gef.Request)
+ */
+ @Override
+ public boolean understandsRequest(final Request request) {
+ return request instanceof ShowHideRelatedLinkRequest;
+ }
+
+ /**
+ * Gets the show hide related link command with dialog.
+ *
+ * @param selectedEditParts the selected edit parts
+ * @param availableLinks a map with the selected edit parts and their available links
+ * @param visibleLinks the visible links
+ * @param domain2NotationMap a map between existing views and semantic elements
+ * @param linksDescriptors the link descriptors
+ * @return the show hide related link command with dialog
+ * the command to open a dialog and Show/Hide the related links
+ */
+ protected abstract Command getShowHideRelatedLinkCommandWithDialog(final Collection<EditPart> selectedEditParts, final Map<EditPart, Set<EObject>> availableLinks, final Set<EObject> visibleLinks, final Domain2Notation domain2NotationMap, Collection<UpdaterLinkDescriptor> linksDescriptors);
+
+ /**
+ * Gets the editing domain.
+ *
+ * @return the editing domain
+ * the editing domain to use
+ */
+ protected final TransactionalEditingDomain getEditingDomain() {
+ try {
+ return ServiceUtilsForEditPart.getInstance().getTransactionalEditingDomain(getHost());
+ } catch (ServiceException e) {
+ Activator.log.error("Editing Domain not found", e); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * Gets the compute command result command.
+ *
+ * @param domain the editing domain to use
+ * @param previousCommand the previous command
+ * @param initialSelection the initial selection
+ * @param domain2NotationMap the map referencing the eobject to their existing view
+ * @param linkDescriptor the link descriptors
+ * @return the compute command result command
+ * the command to show/hide links according to the previous command result
+ */
+ protected ICommand getComputeCommandResultCommand(final TransactionalEditingDomain domain, final ICommand previousCommand, final Set<EObject> initialSelection, final Domain2Notation domain2NotationMap, final Collection<UpdaterLinkDescriptor> linkDescriptor) {
+ final ICommand computeCommand = new AbstractTransactionalCommand(domain, "Compute Result", null) {//$NON-NLS-1$
+
+ /**
+ *
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor,
+ * org.eclipse.core.runtime.IAdaptable)
+ *
+ * @param monitor
+ * @param info
+ * @return
+ * @throws ExecutionException
+ */
+ @Override
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ final Object returnedValue = previousCommand.getCommandResult().getReturnValue();
+ if(previousCommand.getCommandResult().getStatus().isOK()) {
+ if(returnedValue instanceof Collection<?>) {
+ final Collection<?> res = (Collection<?>)returnedValue;
+ final Set<?> toAdd = new HashSet<Object>(res);
+ toAdd.removeAll(initialSelection);
+ final Set<?> toHide = new HashSet<Object>(initialSelection);
+ toHide.removeAll(res);
+ final ICommand cmd = getShowHideRelatedLinkCommand(domain, toAdd, toHide, domain2NotationMap, linkDescriptor);
+ if(cmd.canExecute()) {
+ cmd.execute(monitor, info);
+ } else {
+ Activator.log.error(new UnexpectedException("The command is not executable"));//$NON-NLS-1$
+ }
+ }
+ } else {
+ return previousCommand.getCommandResult();
+ }
+ return CommandResult.newOKCommandResult(returnedValue);
+ }
+ };
+ return computeCommand;
+ }
+
+ /**
+ * Gets the show hide related link command.
+ *
+ * @param domain the editing domain
+ * @param toShow the list of the link to show
+ * @param toHide the list of the link to hide
+ * @param domain2NotationMap a map linking the eobject to their view
+ * @param linkDescriptors the link descriptor
+ * @return the show hide related link command
+ * the command to show/hide the links, according to the args of this method
+ */
+ protected final ICommand getShowHideRelatedLinkCommand(final TransactionalEditingDomain domain, final Collection<?> toShow, final Collection<?> toHide, final Domain2Notation domain2NotationMap, final Collection<? extends UpdaterLinkDescriptor> linkDescriptors) {
+ final CompositeCommand compositeCommand = new CompositeCommand("Show/Hide Related Link");//$NON-NLS-1$
+ for(final Object current : toShow) {
+ if(current instanceof EObject) {
+ final ICommand tmp = getShowLinkCommand(domain, (EObject)current, domain2NotationMap, linkDescriptors);
+ if(tmp != null && tmp.canExecute()) {
+ compositeCommand.add(tmp);
+ }
+ }
+ }
+ for(final Object current : toHide) {
+ if(current instanceof EObject) {
+ final ICommand tmp = getHideLinkCommand(domain, (EObject)current, domain2NotationMap, linkDescriptors);
+ if(tmp != null && tmp.canExecute()) {
+ compositeCommand.add(tmp);
+ }
+ }
+ }
+ return compositeCommand;
+ }
+
+
+ /**
+ * Gets the hide link command.
+ *
+ * @param domain the editing domain
+ * @param linkToHide the link to hide
+ * @param domain2NotationMap the map between eobjects and views
+ * @param linkDescriptors the link descriptors
+ * @return the hide link command
+ * the command to hide the wanted link
+ */
+ protected ICommand getHideLinkCommand(final TransactionalEditingDomain domain, final EObject linkToHide, final Domain2Notation domain2NotationMap, final Collection<? extends UpdaterLinkDescriptor> linkDescriptors) {
+ final UpdaterLinkDescriptor descriptor = getLinkDescriptor(linkToHide, linkDescriptors);
+ if(descriptor != null) {
+ final View view = domain2NotationMap.getFirstView(linkToHide);
+ final EditPart editPart = DiagramEditPartsUtil.getEditPartFromView(view, getHost());
+ return new CommandProxy(editPart.getCommand(new GroupRequest(RequestConstants.REQ_DELETE)));
+ }
+ return null;
+ }
+
+ /**
+ * Gets the link descriptor.
+ *
+ * @param link a link
+ * @param descriptors the list of the known descriptors
+ * @return the link descriptor
+ * the link descriptor for this link or <code>null</code> if not found
+ */
+ protected final UpdaterLinkDescriptor getLinkDescriptor(final EObject link, final Collection<? extends UpdaterLinkDescriptor> descriptors) {
+ final Iterator<? extends UpdaterLinkDescriptor> iter = descriptors.iterator();
+ while(iter.hasNext()) {
+ final UpdaterLinkDescriptor current = iter.next();
+ if(current.getModelElement() == link) {
+ return current;
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Gets the link descriptors.
+ *
+ * @param link the link
+ * @param descriptors the descriptors
+ * @return the link descriptors
+ */
+ protected final List<UpdaterLinkDescriptor> getLinkDescriptors(final EObject link, final Collection<? extends UpdaterLinkDescriptor> descriptors) {
+ List<UpdaterLinkDescriptor> updaterLinkDescriptors = new ArrayList<UpdaterLinkDescriptor>();
+ final Iterator<? extends UpdaterLinkDescriptor> iter = descriptors.iterator();
+ while(iter.hasNext()) {
+ final UpdaterLinkDescriptor current = iter.next();
+ if(current.getModelElement() == link) {
+ updaterLinkDescriptors.add(current);
+ }
+ }
+ return updaterLinkDescriptors;
+ }
+
+
+ /**
+ * Gets the show link command.
+ *
+ * @param domain the editing domain to use for this command
+ * @param linkToShow a link to show
+ * @param domain2NotationMap the domain2 notation map
+ * @param linkDescriptors the link descriptors
+ * @return the show link command
+ * the command to display the link on the diagram
+ */
+ protected ICommand getShowLinkCommand(final TransactionalEditingDomain domain, final EObject linkToShow, final Domain2Notation domain2NotationMap, final Collection<? extends UpdaterLinkDescriptor> linkDescriptors) {
+ domain2NotationMap.mapModel((View)getHost().getAdapter(View.class));
+ final View view = domain2NotationMap.getFirstView(linkToShow);
+ if(view != null) {
+ return new SetPropertyCommand(domain, "Restore related linksCommand show view", new EObjectAdapter(view), Properties.ID_ISVISIBLE, Boolean.TRUE);//$NON-NLS-1$
+ } else {//we need to recreate the view
+
+ //we look for the link descriptor
+ UpdaterLinkDescriptor descriptor = getLinkDescriptor(linkToShow, linkDescriptors);
+ if(linkToShow instanceof EdgeWithNoSemanticElementRepresentationImpl) {
+ //we replace the specific link descriptor by a new one, with no model element (if not the view provider refuse to create the view
+ final IElementType elementType = (IElementType)descriptor.getSemanticAdapter().getAdapter(IElementType.class);
+ descriptor = new UpdaterLinkDescriptor(descriptor.getSource(), descriptor.getDestination(), elementType, descriptor.getVisualID());
+ }
+ if(descriptor != null) {
+
+ Set<View> sourceViewList = domain2NotationMap.get(descriptor.getSource());
+
+ CompositeCommand compositeCommand = new CompositeCommand("Restor All Related Links");
+
+ for (View sourceView : sourceViewList) {
+ Set<View> targetViewList = domain2NotationMap.get(descriptor.getDestination());
+ for (View targetView : targetViewList) {
+
+ if (canDisplayExistingLinkBetweenViews((Connector) linkToShow, sourceView, targetView)){
+
+ EditPart sourceEditPart = getEditPartFromView(sourceView);
+ EditPart targetEditPart = getEditPartFromView(targetView);
+ // If the parts are still null...
+ if(sourceEditPart == null || targetEditPart == null) {
+ return null;
+ }
+ String semanticHint = getSemanticHint(linkToShow);
+ if(semanticHint == null) {
+ semanticHint = ((IHintedType)descriptor.getSemanticAdapter().getAdapter(IElementType.class)).getSemanticHint();
+ }
+ CreateConnectionViewRequest.ConnectionViewDescriptor viewDescriptor = new CreateConnectionViewRequest.ConnectionViewDescriptor(descriptor.getSemanticAdapter(), semanticHint, ViewUtil.APPEND, false, ((GraphicalEditPart)getHost()).getDiagramPreferencesHint());
+ CreateConnectionViewRequest ccr = new CreateConnectionViewRequest(viewDescriptor);
+ ccr.setType(RequestConstants.REQ_CONNECTION_START);
+ ccr.setSourceEditPart(sourceEditPart);
+ sourceEditPart.getCommand(ccr);
+ ccr.setTargetEditPart(targetEditPart);
+ ccr.setType(RequestConstants.REQ_CONNECTION_END);
+ CommandProxy commandProxy = new CommandProxy(targetEditPart.getCommand(ccr));
+ compositeCommand.add(commandProxy);
+ }
+ }
+
+ }
+ return compositeCommand;
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Can display existing link between views.
+ *
+ * @param connector the connector
+ * @param sourceView the source view
+ * @param targetView the target view
+ * @return true, if successful
+ */
+ public boolean canDisplayExistingLinkBetweenViews(final Connector connector, final View sourceView, final View targetView) {
+ return true;
+ }
+
+
+ /**
+ * Gets the semantic hint.
+ *
+ * @param eobject an eobject
+ * @return the semantic hint
+ * the semantic hint to use for this eobject
+ */
+ protected String getSemanticHint(final EObject eobject) {
+ return null;
+ }
+
+
+ /**
+ * Retrieves editpart corresponding to model element.
+ *
+ * @param element the model element
+ * @param domain2NotationMap the domain to notation map
+ * @return the editPart
+ */
+ protected EditPart getEditPart(final EObject element, Domain2Notation domain2NotationMap) {
+ View view = domain2NotationMap.getFirstView(element);
+ if(view != null) {
+ return (EditPart)getHost().getViewer().getEditPartRegistry().get(view);
+ }
+ return null;
+ }
+
+
+ /**
+ * Gets the editpart from view.
+ *
+ * @param view the view
+ * @return the editpart from theview
+ */
+ protected EditPart getEditPartFromView(View view) {
+ if(view != null) {
+ return (EditPart)getHost().getViewer().getEditPartRegistry().get(view);
+ }
+ return null;
+ }
+
+
+
+ /**
+ * Gets the label provider.
+ *
+ * @return the label provider
+ * the label provider to use in the dialog
+ */
+ protected abstract ILabelProvider getLabelProvider();
+
+ /**
+ * Content provider for the dialog.
+ */
+ public static class LinkContentProvider implements ITreeContentProvider {
+
+ /** the map between selected graphical elements and their available links. */
+ private final Map<EditPart, Set<EObject>> availableLinks;
+
+
+ /**
+ * Instantiates a new link content provider.
+ *
+ * @param availableLinks the available links
+ */
+ public LinkContentProvider(final Map<EditPart, Set<EObject>> availableLinks) {
+ this.availableLinks = availableLinks;
+ }
+
+ /**
+ * Dispose.
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ this.availableLinks.clear();
+ }
+
+ /**
+ * Input changed.
+ *
+ * @param viewer the viewer
+ * @param oldInput the old input
+ * @param newInput the new input
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ //nothing to do
+ }
+
+ /**
+ * Gets the elements.
+ *
+ * @param inputElement the input element
+ * @return the elements
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ if(inputElement instanceof Collection<?>) {
+ return ((Collection<?>)inputElement).toArray();
+ }
+ return new Object[0];
+ }
+
+ /**
+ * Gets the children.
+ *
+ * @param parentElement the parent element
+ * @return the children
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parentElement) {
+ if(this.availableLinks.containsKey(parentElement)) {
+ return this.availableLinks.get(parentElement).toArray();
+ }
+ return new Object[0];
+ }
+
+ /**
+ * Gets the parent.
+ *
+ * @param element the element
+ * @return the parent
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(Object element) {
+ final Iterator<Entry<EditPart, Set<EObject>>> iter = this.availableLinks.entrySet().iterator();
+ while(iter.hasNext()) {
+ final Entry<EditPart, Set<EObject>> current = iter.next();
+ if(current.getValue().contains(element)) {
+ return current.getKey();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Checks for children.
+ *
+ * @param element the element
+ * @return true, if successful
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public boolean hasChildren(Object element) {
+ if(this.availableLinks.containsKey(element)) {
+ return this.availableLinks.get(element).size() != 0;
+ }
+ return false;
+ }
+
+ }
+
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/Domain2Notation.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/Domain2Notation.java
new file mode 100644
index 0000000..1a1cabf
--- /dev/null
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/Domain2Notation.java
@@ -0,0 +1,109 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST.
+ *
+ *
+ * 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:
+ * Benoit Maggi (CEA LIST) benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.common.utils;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.notation.BasicCompartment;
+import org.eclipse.gmf.runtime.notation.Connector;
+import org.eclipse.gmf.runtime.notation.Shape;
+import org.eclipse.gmf.runtime.notation.View;
+
+
+/**
+ * The Class Domain2Notation used for mapping between EObject and views
+ */
+public class Domain2Notation extends HashMap<EObject, Set<View>> {
+
+
+ /**
+ * Maps view.
+ *
+ * @param view
+ * the view from which are mapped all subviews
+ */
+ public void mapModel(View view) {
+ if((view instanceof Connector || view instanceof Shape) && !(view instanceof BasicCompartment)) {
+ putView(view);
+ }
+ @SuppressWarnings("unchecked")//$NON-NLS-1$
+ List<View> children = view.getChildren();
+ for(View child : children) {
+ mapModel(child);
+ }
+ @SuppressWarnings("unchecked")//$NON-NLS-1$
+ List<View> sourceEdges = view.getSourceEdges();
+ for(View edge : sourceEdges) {
+ mapModel(edge);
+ }
+ }
+
+
+ /**
+ * Put view.
+ *
+ * @param view
+ * the view
+ */
+ public void putView(View view) {
+ EObject element = view.getElement();
+ Set<View> set = this.get(element);
+ if(set != null) {
+ set.add(view);
+ } else {
+ Set<View> hashSet = new HashSet<View>();
+ hashSet.add(view);
+ put(element, hashSet);
+ }
+ }
+
+ /**
+ * Put view.
+ *
+ * @param element
+ * the element
+ * @param view
+ * the view
+ */
+ public void putView(EObject element, View view) {
+ Set<View> set = this.get(element);
+ if(set != null) {
+ set.add(view);
+ } else {
+ Set<View> hashSet = new HashSet<View>();
+ hashSet.add(view);
+ put(element, hashSet);
+ }
+ }
+
+ /**
+ * Gets the first view, prefer the get(Object key) method to get all the views
+ *
+ * @param key
+ * the key
+ * @return the first view
+ */
+ @Deprecated
+ public View getFirstView(Object key) {
+ Set<View> set = get(key);
+ if(set != null) {
+ return set.iterator().next();
+ }
+ return null;
+ }
+}
diff --git a/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.internalblock/src/org/eclipse/papyrus/sysml/diagram/internalblock/edit/policy/ShowHideRelatedLinkEditPolicy.java b/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.internalblock/src/org/eclipse/papyrus/sysml/diagram/internalblock/edit/policy/ShowHideRelatedLinkEditPolicy.java
index 1f7f91a..3c373c1 100644
--- a/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.internalblock/src/org/eclipse/papyrus/sysml/diagram/internalblock/edit/policy/ShowHideRelatedLinkEditPolicy.java
+++ b/plugins/sysml/diagram/org.eclipse.papyrus.sysml.diagram.internalblock/src/org/eclipse/papyrus/sysml/diagram/internalblock/edit/policy/ShowHideRelatedLinkEditPolicy.java
@@ -1,318 +1,387 @@
-/*****************************************************************************
- * Copyright (c) 2013 CEA LIST.
- *
- * 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:
- *
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.sysml.diagram.internalblock.edit.policy;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gmf.runtime.common.core.command.ICommand;
-import org.eclipse.gmf.runtime.diagram.core.commands.SetPropertyCommand;
-import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
-import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
-import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
-import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
-import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.gmf.tooling.runtime.structure.DiagramStructure;
-import org.eclipse.gmf.tooling.runtime.update.DiagramUpdater;
-import org.eclipse.gmf.tooling.runtime.update.UpdaterLinkDescriptor;
-import org.eclipse.papyrus.sysml.blocks.NestedConnectorEnd;
-import org.eclipse.papyrus.sysml.diagram.internalblock.part.SysMLDiagramUpdater;
-import org.eclipse.papyrus.sysml.diagram.internalblock.part.SysMLVisualIDRegistry;
-import org.eclipse.papyrus.uml.diagram.common.editpolicies.AbstractUMLShowHideRelatedLinkEditPolicy;
-import org.eclipse.papyrus.uml.diagram.common.util.CrossReferencerUtil;
-import org.eclipse.uml2.uml.ConnectableElement;
-import org.eclipse.uml2.uml.Connector;
-import org.eclipse.uml2.uml.ConnectorEnd;
-import org.eclipse.uml2.uml.Property;
-
-/**
- *
- * The edit policy to use in the IBD diagram to restore existing links
- *
- */
-public class ShowHideRelatedLinkEditPolicy extends AbstractUMLShowHideRelatedLinkEditPolicy {
-
- /**
- *
- * Constructor.
- *
- * @param host
- */
- public ShowHideRelatedLinkEditPolicy(DiagramEditPart host) {
- super(host);
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.IDiagramInformationProviderEditPolicy#getDiagramUpdater()
- *
- * @return
- */
- public DiagramUpdater getDiagramUpdater() {
- return SysMLDiagramUpdater.TYPED_INSTANCE;
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.IDiagramInformationProviderEditPolicy#getDiagramStructure()
- *
- * @return
- */
- public DiagramStructure getDiagramStructure() {
- return SysMLVisualIDRegistry.TYPED_INSTANCE;
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#getSemanticHint(org.eclipse.emf.ecore.EObject)
- *
- * @param eobject
- * @return
- */
- @Override
- protected String getSemanticHint(final EObject eobject) {
- return SysMLVisualIDRegistry.getLinkWithClassVisualID(eobject);
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#cleanAdd(java.util.Collection,
- * org.eclipse.gmf.runtime.notation.View, java.util.List, java.util.Map)
- *
- * @param result
- * @param view
- * @param descriptors
- * @param domain2NotationMap
- */
- @Override
- protected void cleanAdd(final Collection<UpdaterLinkDescriptor> result, final View view, final List<?> descriptors, final Map<EObject, View> domain2NotationMap) {
- cleanAddForConnector(result, view, descriptors, domain2NotationMap);
- super.cleanAdd(result, view, descriptors, domain2NotationMap);
- }
-
- /**
- * This method manages descriptors representing Connector to verify that it
- * can be displayed according to the nestedPath of the {@link ConnectorEnd} If the connector can be displayed :
- * <ul>
- * <li>
- * the link descriptor is removed from descriptors and added to result</li>
- * <li>
- * the view associated to the role of the connector are added to domain2NotationMap (using the ConnectorEnd as key)</li>
- * </ul>
- *
- *
- *
- * @param result
- * the result of the method
- * @param view
- * a view
- * @param descriptors
- * the link descriptors
- * @param domain2NotationMap
- * the map between model element and views
- *
- *
- */
- protected void cleanAddForConnector(final Collection<UpdaterLinkDescriptor> result, final View view, final List<?> descriptors, final Map<EObject, View> domain2NotationMap) {
- final List<UpdaterLinkDescriptor> toRemove = new ArrayList<UpdaterLinkDescriptor>();
- for(final Object current : descriptors) {
- if(current instanceof UpdaterLinkDescriptor) {
- final UpdaterLinkDescriptor descriptor = (UpdaterLinkDescriptor)current;
- final EObject element = descriptor.getModelElement();
- if(element instanceof Connector) {
- if(canBeDisplayed((Connector)element, view, domain2NotationMap)) {
- result.add((UpdaterLinkDescriptor)current);
- }
- toRemove.add((UpdaterLinkDescriptor)current);
- }
- }
- }
- descriptors.removeAll(toRemove);
- }
-
- /**
- *
- * @param end
- * a connector end
- * @param view
- * a view
- * @return <code>true</code> if the view represents the role of the
- * connector AND if the view is encapsulated as required by the
- * nested path of the connector end
- */
- protected boolean isCorrectGraphicalView(final ConnectorEnd end, final View view) {
- final NestedConnectorEnd nestedConnectorEnd = org.eclipse.uml2.uml.util.UMLUtil.getStereotypeApplication(end, NestedConnectorEnd.class);
- final Property partWithPort = end.getPartWithPort();
- // final ConnectableElement role = end.getRole();
- // 1. we get the top view of this view with the same semantic element
- View localView = getTopViewWithSameSemanticElement(view);
-
- // 2. we verify the part with port
- if(partWithPort != null) {
- View parent = getTopViewWithSameSemanticElement(ViewUtil.getViewContainer(localView));
- if(parent.getElement() != partWithPort) {
- return false;
- }
- }
-
- // 3. we verify the nested path
- if(nestedConnectorEnd != null && nestedConnectorEnd.getPropertyPath().size() > 0) {
- View parent = view;
- final List<Property> paths = nestedConnectorEnd.getPropertyPath();
- for(int i = paths.size() - 1; i >= 0; i--) {
- final Property currentProperty = paths.get(i);
- parent = getTopViewWithSameSemanticElement(ViewUtil.getViewContainer(parent));
- if(parent.getElement() != currentProperty) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- *
- * @param connector
- * a connector
- * @param selectedView
- * a view used as source or target for the connector to display
- * @param domain2NotationMap
- * the map to complete if we found source and target View on the
- * diagram to diplsay the connector
- * @return <code>true</code> if the view can be used as source/target for
- * the connector according to the nested path AND if we found a
- * second view for the 2nd connector end according to the nested
- * path
- */
- protected boolean canBeDisplayed(final Connector connector, final View selectedView, final Map<EObject, View> domain2NotationMap) {
- // we need to verify the selected view
- final EObject semanticElement = selectedView.getElement();
- ConnectorEnd endForView = null;
-
- // 1. look for the connector end represented by the selected view
- for(final ConnectorEnd current : connector.getEnds()) {
- if(current.getRole() == semanticElement) {
- endForView = current;
- break;
- }
- }
- Assert.isNotNull(endForView);
- // 2. verify the view of the selected connector end
- if(!isCorrectGraphicalView(endForView, selectedView)) {
- return false;
- }
-
- // 3. try to find a view for the second connector end
- View secondView = null;
- for(final ConnectorEnd end : connector.getEnds()) {
- final ConnectableElement role = end.getRole();
- if(role==null){
- return false;
- }
- if(end == endForView) {
- continue;
- }
-
- final Set<View> views = CrossReferencerUtil.getCrossReferencingViewsInDiagram(role, getCurrentDiagram());
- final Iterator<View> iterOnView = views.iterator();
- while(secondView == null && iterOnView.hasNext()) {
- final View currentView = iterOnView.next();
- if(isCorrectGraphicalView(end, currentView)) {
- domain2NotationMap.put(endForView, selectedView);
- domain2NotationMap.put(end, currentView);
- secondView = currentView;
- }
- }
- }
- return secondView != null;
- }
-
- /**
- *
- * @param domain
- * the editing domain to use for this command
- * @param linkToShow
- * a link to show
- * @param domain2NotationMap
- * @param linkDescriptors
- * @return the command to display the link on the diagram
- */
- protected ICommand getShowLinkCommand(final TransactionalEditingDomain domain, final EObject linkToShow, final Map<EObject, View> domain2NotationMap, final Collection<? extends UpdaterLinkDescriptor> linkDescriptors) {
- if(!(linkToShow instanceof Connector)) {
- return super.getShowLinkCommand(domain, linkToShow, domain2NotationMap, linkDescriptors);
- }
- mapModel((View)getHost().getAdapter(View.class), domain2NotationMap);
- final View view = domain2NotationMap.get(linkToShow);
- if(view != null) {
- return new SetPropertyCommand(domain, "Restore related linksCommand show view", new EObjectAdapter(view), Properties.ID_ISVISIBLE, Boolean.TRUE);//$NON-NLS-1$
- } else {// we need to recreate the view
-
- // we look for the link descriptor
- UpdaterLinkDescriptor descriptor = getLinkDescriptor(linkToShow, linkDescriptors);
-
- if(descriptor != null) {
- // we override the way to find the source and the target edit
- // part
- EditPart sourceEditPart = getEditPart(((Connector)linkToShow).getEnds().get(0), domain2NotationMap);
- EditPart targetEditPart = getEditPart(((Connector)linkToShow).getEnds().get(1), domain2NotationMap);
-
- // If the parts are still null...
- if(sourceEditPart == null || targetEditPart == null) {
- return null;
- }
- String semanticHint = getSemanticHint(linkToShow);
- CreateConnectionViewRequest.ConnectionViewDescriptor viewDescriptor = new CreateConnectionViewRequest.ConnectionViewDescriptor(descriptor.getSemanticAdapter(), semanticHint, ViewUtil.APPEND, false, ((GraphicalEditPart)getHost()).getDiagramPreferencesHint());
- CreateConnectionViewRequest ccr = new CreateConnectionViewRequest(viewDescriptor);
- ccr.setType(RequestConstants.REQ_CONNECTION_START);
- ccr.setSourceEditPart(sourceEditPart);
- sourceEditPart.getCommand(ccr);
- ccr.setTargetEditPart(targetEditPart);
- ccr.setType(RequestConstants.REQ_CONNECTION_END);
- return new CommandProxy(targetEditPart.getCommand(ccr));
- }
- }
- return null;
- }
-
- /**
- *
- * @param view
- * a view
- * @return the last parent of this view referencing the same semantic
- * element
- */
- protected View getTopViewWithSameSemanticElement(final View view) {
- final EObject semanticElement = view.getElement();
- View parent = view;
- View lastParent = view;
- while(parent.getElement() == semanticElement) {
- lastParent = parent;
- parent = (View)parent.eContainer();
- }
- return lastParent;
- }
-
-}
+/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ * 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:
+ *
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.sysml.diagram.internalblock.edit.policy;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
+import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.gmf.tooling.runtime.structure.DiagramStructure;
+import org.eclipse.gmf.tooling.runtime.update.DiagramUpdater;
+import org.eclipse.gmf.tooling.runtime.update.UpdaterLinkDescriptor;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.Domain2Notation;
+import org.eclipse.papyrus.sysml.blocks.NestedConnectorEnd;
+import org.eclipse.papyrus.sysml.diagram.internalblock.part.SysMLDiagramUpdater;
+import org.eclipse.papyrus.sysml.diagram.internalblock.part.SysMLVisualIDRegistry;
+import org.eclipse.papyrus.sysml.service.types.utils.ConnectorUtils;
+import org.eclipse.papyrus.uml.diagram.common.editpolicies.AbstractUMLShowHideRelatedLinkEditPolicy;
+import org.eclipse.papyrus.uml.diagram.common.util.CrossReferencerUtil;
+import org.eclipse.uml2.uml.ConnectableElement;
+import org.eclipse.uml2.uml.Connector;
+import org.eclipse.uml2.uml.ConnectorEnd;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.TypedElement;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The edit policy to use in the IBD diagram to restore existing links.
+ */
+public class ShowHideRelatedLinkEditPolicy extends AbstractUMLShowHideRelatedLinkEditPolicy {
+
+ /**
+ * Constructor.
+ *
+ * @param host the host
+ */
+ public ShowHideRelatedLinkEditPolicy(DiagramEditPart host) {
+ super(host);
+ }
+
+ /**
+ * Gets the diagram updater.
+ *
+ * @return the diagram updater
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.IDiagramInformationProviderEditPolicy#getDiagramUpdater()
+ */
+ public DiagramUpdater getDiagramUpdater() {
+ return SysMLDiagramUpdater.TYPED_INSTANCE;
+ }
+
+ /**
+ * Gets the diagram structure.
+ *
+ * @return the diagram structure
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.IDiagramInformationProviderEditPolicy#getDiagramStructure()
+ */
+ public DiagramStructure getDiagramStructure() {
+ return SysMLVisualIDRegistry.TYPED_INSTANCE;
+ }
+
+ /**
+ * Gets the semantic hint.
+ *
+ * @param eobject the eobject
+ * @return the semantic hint
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#getSemanticHint(org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ protected String getSemanticHint(final EObject eobject) {
+ return SysMLVisualIDRegistry.getLinkWithClassVisualID(eobject);
+ }
+
+ /**
+ * Clean add.
+ *
+ * @param result the result
+ * @param view the view
+ * @param descriptors the descriptors
+ * @param domain2NotationMap the domain2 notation map
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#cleanAdd(java.util.Collection,
+ * org.eclipse.gmf.runtime.notation.View, java.util.List, java.util.Map)
+ */
+ @Override
+ protected void cleanAdd(final Collection<UpdaterLinkDescriptor> result, final View view, final List<? extends UpdaterLinkDescriptor> descriptors, final Domain2Notation domain2NotationMap) {
+ cleanAddForConnector(result, view, descriptors, domain2NotationMap);
+ super.cleanAdd(result, view, descriptors, domain2NotationMap);
+ }
+
+ /**
+ * This method manages descriptors representing Connector to verify that it
+ * can be displayed according to the nestedPath of the {@link ConnectorEnd} If the connector can be displayed :
+ * <ul>
+ * <li>
+ * the link descriptor is removed from descriptors and added to result</li>
+ * <li>
+ * the view associated to the role of the connector are added to domain2NotationMap (using the ConnectorEnd as key)</li>
+ * </ul>.
+ *
+ * @param result the result of the method
+ * @param view a view
+ * @param descriptors the link descriptors
+ * @param domain2NotationMap the map between model element and views
+ */
+ protected void cleanAddForConnector(final Collection<UpdaterLinkDescriptor> result, final View view, final List<?> descriptors, final Domain2Notation domain2NotationMap) {
+ final List<UpdaterLinkDescriptor> toRemove = new ArrayList<UpdaterLinkDescriptor>();
+ for(final Object current : descriptors) {
+ if(current instanceof UpdaterLinkDescriptor) {
+ final UpdaterLinkDescriptor descriptor = (UpdaterLinkDescriptor)current;
+ final EObject element = descriptor.getModelElement();
+ if(element instanceof Connector) {
+ if(canBeDisplayed((Connector)element, view, domain2NotationMap)) {
+ result.add((UpdaterLinkDescriptor)current);
+ }
+ toRemove.add((UpdaterLinkDescriptor)current);
+ }
+ }
+ }
+ descriptors.removeAll(toRemove);
+ }
+
+ /**
+ * Checks if is correct graphical view.
+ *
+ * @param connectorEnd a connector end
+ * @param view a view
+ * @return <code>true</code> if the view represents the role of the
+ * connector AND if the view is encapsulated as required by the
+ * nested path of the connector end
+ */
+ protected boolean isCorrectGraphicalView(final ConnectorEnd connectorEnd, final View view) {
+ final NestedConnectorEnd nestedConnectorEnd = org.eclipse.uml2.uml.util.UMLUtil.getStereotypeApplication(connectorEnd, NestedConnectorEnd.class);
+ final Property partWithPort = connectorEnd.getPartWithPort();
+ // final ConnectableElement role = end.getRole();
+ // 1. we get the top view of this view with the same semantic element
+ View localView = getTopViewWithSameSemanticElement(view);
+
+ // 2. we verify the part with port
+ if(partWithPort != null) {
+ View parent = getTopViewWithSameSemanticElement(ViewUtil.getViewContainer(localView));
+ if(parent.getElement() != partWithPort) {
+ return false;
+ }
+ }
+
+ // 3. we verify the nested path
+ if(nestedConnectorEnd != null && nestedConnectorEnd.getPropertyPath().size() > 0) {
+ View parent = view;
+ final List<Property> paths = nestedConnectorEnd.getPropertyPath();
+ for(int i = paths.size() - 1; i >= 0; i--) {
+ final Property currentProperty = paths.get(i);
+ parent = getTopViewWithSameSemanticElement(ViewUtil.getViewContainer(parent));
+ if(parent.getElement() != currentProperty) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Can be displayed.
+ *
+ * @param connector a connector
+ * @param selectedView a view used as source or target for the connector to display
+ * @param domain2NotationMap the map to complete if we found source and target View on the
+ * diagram to diplsay the connector
+ * @return <code>true</code> if the view can be used as source/target for
+ * the connector according to the nested path AND if we found a
+ * second view for the 2nd connector end according to the nested
+ * path
+ */
+ protected boolean canBeDisplayed(final Connector connector, final View selectedView, final Domain2Notation domain2NotationMap) {
+ // we need to verify the selected view
+ final EObject semanticElement = selectedView.getElement();
+ ConnectorEnd endForView = null;
+
+ // 1. look for the connector end represented by the selected view
+ for(final ConnectorEnd current : connector.getEnds()) {
+ if(current.getRole() == semanticElement) {
+ endForView = current;
+ break;
+ }
+ }
+ Assert.isNotNull(endForView);
+ // 2. verify the view of the selected connector end
+ if(!isCorrectGraphicalView(endForView, selectedView)) {
+ return false;
+ }
+
+ // 3. try to find a view for the second connector end
+ View secondView = null;
+ for(final ConnectorEnd end : connector.getEnds()) {
+ final ConnectableElement role = end.getRole();
+ if(role==null){
+ return false;
+ }
+ if(end == endForView) {
+ continue;
+ }
+
+ final Set<View> views = CrossReferencerUtil.getCrossReferencingViewsInDiagram(role, getCurrentDiagram());
+ final Iterator<View> iterOnView = views.iterator();
+ while(secondView == null && iterOnView.hasNext()) {
+ final View currentView = iterOnView.next();
+ if(isCorrectGraphicalView(end, currentView)) {
+ domain2NotationMap.putView(endForView, selectedView);
+ domain2NotationMap.putView(end, currentView);
+ secondView = currentView;
+ }
+ }
+ }
+ return secondView != null;
+ }
+
+ /**
+ * Gets the show link command.
+ *
+ * @param domain the editing domain to use for this command
+ * @param linkToShow a link to show
+ * @param domain2NotationMap the domain2 notation map
+ * @param linkDescriptors the link descriptors
+ * @return the command to display the link on the diagram
+ */
+ protected ICommand getShowLinkCommand(final TransactionalEditingDomain domain, final EObject linkToShow, final Domain2Notation domain2NotationMap, final Collection<? extends UpdaterLinkDescriptor> linkDescriptors) {
+
+ if(!(linkToShow instanceof Connector)) {
+ return super.getShowLinkCommand(domain, linkToShow, domain2NotationMap, linkDescriptors);
+ }
+ domain2NotationMap.mapModel((View)getHost().getAdapter(View.class));
+
+ // we look for the link descriptor
+ UpdaterLinkDescriptor updaterLinkDescriptor = getLinkDescriptor(linkToShow, linkDescriptors);
+ ICommand showLinkCommandFromUpdaterLinkDescriptor = getShowLinkCommandFromUpdaterLinkDescriptor(linkToShow, domain2NotationMap, updaterLinkDescriptor);
+ return showLinkCommandFromUpdaterLinkDescriptor;
+ }
+
+
+ /**
+ * Gets the show link command from updater link descriptor.
+ *
+ * @param linkToShow the link to show
+ * @param domain2NotationMap the domain2 notation map
+ * @param descriptor the descriptor
+ * @return the show link command from updater link descriptor
+ */
+ private ICommand getShowLinkCommandFromUpdaterLinkDescriptor(final EObject linkToShow, final Domain2Notation domain2NotationMap, UpdaterLinkDescriptor descriptor) {
+ ConnectorUtils connectorUtils = new ConnectorUtils();
+
+ if(descriptor != null) {
+
+ Set<View> sourceViewList = domain2NotationMap.get(descriptor.getSource());
+ Set<View> targetViewList = domain2NotationMap.get(descriptor.getDestination());
+
+
+ final Set<View> linkSet = domain2NotationMap.get(linkToShow);
+
+ CompositeCommand compositeCommand = new CompositeCommand("Restor All Related Links");
+ for (View sourceView : sourceViewList) {
+ for (View targetView : targetViewList) {
+ if (canDisplayExistingLinkBetweenViews((Connector) linkToShow, sourceView, targetView)){
+
+ if (connectorUtils.canDisplayExistingConnectorBetweenViewsAccordingToPartWithPort((Connector) linkToShow, sourceView, targetView)){
+ boolean alreadyDisplayed = false;
+ if (linkSet != null){
+ for (View viewLink : linkSet) {
+ boolean linkForViews = isLinkForViews((org.eclipse.gmf.runtime.notation.Connector) viewLink, sourceView, targetView);
+ alreadyDisplayed = alreadyDisplayed || linkForViews;
+ }
+ }
+
+ if (!alreadyDisplayed){
+ EditPart sourceEditPart = getEditPartFromView(sourceView);
+ EditPart targetEditPart = getEditPartFromView(targetView);
+
+ // If the parts are still null...
+ if(sourceEditPart == null || targetEditPart == null) {
+ return null;
+ }
+ String semanticHint = getSemanticHint(linkToShow);
+ CreateConnectionViewRequest.ConnectionViewDescriptor viewDescriptor = new CreateConnectionViewRequest.ConnectionViewDescriptor(descriptor.getSemanticAdapter(), semanticHint, ViewUtil.APPEND, false, ((GraphicalEditPart)getHost()).getDiagramPreferencesHint());
+ CreateConnectionViewRequest ccr = new CreateConnectionViewRequest(viewDescriptor);
+ ccr.setType(RequestConstants.REQ_CONNECTION_START);
+ ccr.setSourceEditPart(sourceEditPart);
+ sourceEditPart.getCommand(ccr);
+ ccr.setTargetEditPart(targetEditPart);
+ ccr.setType(RequestConstants.REQ_CONNECTION_END);
+ CommandProxy commandProxy = new CommandProxy(targetEditPart.getCommand(ccr));
+ compositeCommand.add(commandProxy);
+ }
+ }
+ }
+ }
+ }
+ return compositeCommand;
+ }
+ return null;
+ }
+
+
+
+
+
+
+
+
+
+
+ /**
+ * Can display existing link between views.
+ *
+ * @param connector the connector
+ * @param sourceView the source view
+ * @param targetView the target view
+ * @return true, if successful
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#canDisplayExistingLinkBetweenViews(org.eclipse.uml2.uml.Connector, org.eclipse.gmf.runtime.notation.View, org.eclipse.gmf.runtime.notation.View)
+ */
+
+ @Override
+ public boolean canDisplayExistingLinkBetweenViews(final Connector connector, final View sourceView, final View targetView) {
+ ConnectorUtils connectorUtils = new ConnectorUtils();
+ return connectorUtils.canDisplayExistingConnectorBetweenViewsAccordingToNestedPaths(connector, sourceView, targetView);
+ }
+
+ /**
+ * Checks if is link for views.
+ *
+ * @param link a connector existing in the model
+ * @param sourceView a potential source for this connector
+ * @param targetView a potential target for this connector
+ * @return true, if is link for views
+ * <code>true</code> if displaying the existing connector between this source and this target view is correct
+ */
+ public final boolean isLinkForViews(final org.eclipse.gmf.runtime.notation.Connector link, final View sourceView, final View targetView) {
+ View source = link.getSource();
+ View target = link.getTarget();
+ boolean isDrawingAllowed = source.equals(sourceView) && target.equals(targetView);
+ boolean isReverseDrawingAllowed = source.equals(targetView) && target.equals(sourceView);
+ return isDrawingAllowed || isReverseDrawingAllowed ;
+ }
+
+
+
+ /**
+ * Gets the top view with same semantic element.
+ *
+ * @param view a view
+ * @return the last parent of this view referencing the same semantic
+ * element
+ */
+ protected View getTopViewWithSameSemanticElement(final View view) {
+ final EObject semanticElement = view.getElement();
+ View parent = view;
+ View lastParent = view;
+ while(parent.getElement() == semanticElement) {
+ lastParent = parent;
+ parent = (View)parent.eContainer();
+ }
+ return lastParent;
+ }
+
+}
diff --git a/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/utils/ConnectorUtils.java b/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/utils/ConnectorUtils.java
index 056fb1c..bb965e5 100644
--- a/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/utils/ConnectorUtils.java
+++ b/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/utils/ConnectorUtils.java
@@ -1,339 +1,390 @@
-/*****************************************************************************
- * Copyright (c) 2012 CEA LIST.
- *
- * 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:
- *
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.sysml.service.types.utils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.sysml.blocks.Block;
-import org.eclipse.papyrus.sysml.blocks.NestedConnectorEnd;
-import org.eclipse.uml2.uml.ConnectableElement;
-import org.eclipse.uml2.uml.Connector;
-import org.eclipse.uml2.uml.ConnectorEnd;
-import org.eclipse.uml2.uml.NamedElement;
-import org.eclipse.uml2.uml.Port;
-import org.eclipse.uml2.uml.Property;
-import org.eclipse.uml2.uml.Stereotype;
-import org.eclipse.uml2.uml.StructuredClassifier;
-import org.eclipse.uml2.uml.Type;
-import org.eclipse.uml2.uml.util.UMLUtil;
-
-/**
- * Utility class for Connector edit helpers.
- */
-public class ConnectorUtils extends org.eclipse.papyrus.uml.service.types.utils.ConnectorUtils {
-
- /**
- * the key used to store the nested path as parameter of the request. The value will be a List of {@link Property}
- */
- public static String NESTED_CONNECTOR_END_PATH = "connectorEndPath"; //$NON-NLS-1$
-
- /**
- * the separator used in the role path to distinguish the part
- */
- public static final String PART_SEPARATOR = "."; //$NON-NLS-1$
-
- /**
- * allow to know if a string contains others characters than a-z A-Z 0-9 and _
- */
- public static final String HAS_NO_WORD_CHAR_REGEX = "\\W+";
-
- /**
- * String used to delimit a name with contains special chars
- */
- public static final String STRING_DELIMITER = "\'";
-
- /**
- * @param view
- * the view
- * @return the nearest encapsulated structure container or null
- */
- public View getEncapsulatedContainer(View view) {
- View encapsulatedContainer = null;
-
- for(View containerView : getStructureContainers(view)) {
-
- if(view == containerView) {
- continue;
- }
-
- if((view.getElement() instanceof Port) && (containerView.getChildren().contains(view))) {
- continue;
- }
-
- StructuredClassifier structuredClassifier = getStructuredClassifier(containerView);
- Block block = UMLUtil.getStereotypeApplication(structuredClassifier, Block.class);
- if(block.isEncapsulated()) {
- encapsulatedContainer = containerView;
- break;
- }
- }
-
- return encapsulatedContainer;
- }
-
- /**
- * Test if an encapsulation crossing is required to connect the checked end to the opposite end.
- *
- * @param checkedEnd
- * the checked end view.
- * @param oppositeEnd
- * the opposite end view.
- * @return true if the gesture break encapsulation rule.
- */
- public boolean isCrossingEncapsulation(View checkedEnd, View oppositeEnd) {
- boolean isCrossingEncapsulation = false;
-
- View encapsulatedContainer = new ConnectorUtils().getEncapsulatedContainer(checkedEnd);
- if(encapsulatedContainer != null) {
- View containerView = new ConnectorUtils().deduceViewContainer(checkedEnd, oppositeEnd);
- List<View> containers = new ConnectorUtils().getStructureContainers(checkedEnd);
-
- if(containers.indexOf(encapsulatedContainer) < containers.indexOf(containerView)) {
- isCrossingEncapsulation = true;
- }
- }
-
- return isCrossingEncapsulation;
- }
-
- /**
- * Get the path of structure views crossed by the checked end.
- *
- * @param checkedEnd
- * the checked end view.
- * @param oppositeEnd
- * the opposite end view.
- * @return the list of crossed structure views.
- */
- public List<View> getNestedPath(View checkedEnd, View oppositeEnd) {
- List<View> isNestedConnectableElement = new ArrayList<View>();
-
- View nearestContainer = new ConnectorUtils().getNearestStructureContainer(checkedEnd);
- if(nearestContainer != null) {
- View containerView = new ConnectorUtils().deduceViewContainer(checkedEnd, oppositeEnd);
- List<View> containers = new ConnectorUtils().getStructureContainers(checkedEnd);
-
- if(containers.indexOf(nearestContainer) < containers.indexOf(containerView)) {
- isNestedConnectableElement = containers.subList(containers.indexOf(nearestContainer), containers.indexOf(containerView));
- }
- }
-
- // nested path is taken from the top block to the deepest property ==> collection must be reverted
- Collections.reverse(isNestedConnectableElement);
-
- return isNestedConnectableElement;
- }
-
- /**
- * Get the path of structure views crossed by the checked end.
- *
- * @param checkedEnd
- * the checked end view.
- * @param oppositeEnd
- * the opposite end view.
- * @return the list of crossed structure views.
- */
- public List<Property> getNestedPropertyPath(View checkedEnd, View oppositeEnd) {
- List<Property> nestedPropertyPath = new ArrayList<Property>();
- List<View> nestedPath = getNestedPath(checkedEnd, oppositeEnd);
-
- for(View view : nestedPath) {
- if((view.getElement() != null) && (view.getElement() instanceof Property)) {
- nestedPropertyPath.add((Property)view.getElement());
- }
- }
-
- // if end is a port, and the list is not empty, add the property from the check view in the list
- if(!nestedPropertyPath.isEmpty() && checkedEnd.getElement() instanceof Port) {
- Property partWithPort = getPartWithPort(checkedEnd, oppositeEnd);
- if(partWithPort != null) {
- nestedPropertyPath.add(partWithPort);
- }
- }
-
- return nestedPropertyPath;
- }
-
- /**
- * Test if the checked end is nested (means it cross StructuredClassifier borders).
- *
- * @param checkedEnd
- * the checked end view.
- * @param oppositeEnd
- * the opposite end view.
- * @return true if the checked end is nested.
- */
- public boolean isNestedConnectableElement(View checkedEnd, View oppositeEnd) {
- return !(getNestedPath(checkedEnd, oppositeEnd).isEmpty());
- }
-
- /**
- * @param view
- * the view
- * @return the nearest structure container or null
- */
- public View getNearestStructureContainer(View view) {
- View nearestStructureContainer = null;
-
- for(View containerView : getStructureContainers(view)) {
-
- if(view == containerView) {
- continue;
- }
-
- if((view.getElement() instanceof Port) && (containerView.getChildren().contains(view))) {
- continue;
- }
-
- nearestStructureContainer = containerView;
- break;
- }
-
- return nearestStructureContainer;
- }
-
-
-
- /**
- *
- * @param end
- * the connector end
- * @return
- * the path for the role of the connector end (without using label provider)
- */
- public static final String getRolePath(final ConnectorEnd end) {
- final NestedConnectorEnd nestedConnectorEnd = UMLUtil.getStereotypeApplication(end, NestedConnectorEnd.class);
- final ConnectableElement role = end.getRole();
- final StringBuilder rolePath = new StringBuilder();
- if(role != null) {
- if(nestedConnectorEnd != null) {
- final List<Property> properties = nestedConnectorEnd.getPropertyPath();
- for(final Property current : properties) {
- rolePath.append(getNameWithQuotes(current));
- rolePath.append(ConnectorUtils.PART_SEPARATOR);
- }
- } else {
- //when the stereotype is applied, the Property for partWithPort is included in the stereotype#path
- final Property partWithPort = end.getPartWithPort();
- if(partWithPort != null) {
- rolePath.append(getNameWithQuotes(partWithPort));
- rolePath.append(ConnectorUtils.PART_SEPARATOR);
- }
- }
- rolePath.append(getNameWithQuotes(role));
- }
-
- return rolePath.toString();
- }
-
- /**
- *
- * @param property
- * a property
- * @return
- * the property name with name delimiter if it is required
- */
- public static final String getNameWithQuotes(final NamedElement property) {
- final String partName = property.getName();
- final StringBuffer partNameBuffer = new StringBuffer();
- final Pattern pattern = Pattern.compile(ConnectorUtils.HAS_NO_WORD_CHAR_REGEX);
- final Matcher matcher = pattern.matcher(partName);
- boolean mustHaveQuote = false;
- while(matcher.find() && !mustHaveQuote) {
- mustHaveQuote = true;
- }
- if(mustHaveQuote) {
- partNameBuffer.append(ConnectorUtils.STRING_DELIMITER);
- partNameBuffer.append(partName);
- partNameBuffer.append(ConnectorUtils.STRING_DELIMITER);
- } else {
- partNameBuffer.append(partName);
- }
-
- return partNameBuffer.toString();
- }
-
- /**
- *
- * @param nestedPath
- * the nested path
- * @return
- * <code>true</code> if we are breaking encapsulation (see SysML rules in SysML Standard 1.2, p.44):
- * isEncapsulated: Boolean [0..1] If true, then the block is treated as a black box; a part typed by this black box can only be connected
- * via its ports or directly to its outer boundary. If false, or if a value is not present, then connections can be established to
- * elements of its internal structure via deep-nested connector ends.
- */
- public static final boolean isCrossingEncapuslation(final List<Property> nestedPath) {
- for(final Property current : nestedPath) {
- final Type type = current.getType();
- if(type != null) {
- final Block block = UMLUtil.getStereotypeApplication(type, Block.class);
- if(block != null && block.isEncapsulated()) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- *
- * @param connector
- * a connector existing in the model
- * @param sourceView
- * a potential source for this connector
- * @param targetView
- * a potential target for this connector
- * @return
- * <code>true</code> if displaying the existing connector between this source and this target view is correct
- */
- public final boolean canDisplayExistingConnectorBetweenViewsAccordingToNestedPaths(final Connector connector, final View sourceView, final View targetView) {
- ConnectorUtils utils = new ConnectorUtils();
- final List<Property> sourcePath = utils.getNestedPropertyPath(sourceView, targetView);
- final List<Property> targetPath = utils.getNestedPropertyPath(targetView, sourceView);
- boolean hasWantedPath = true;
- for(final ConnectorEnd end : connector.getEnds()) {
- if(sourceView != null && end.getRole() == sourceView.getElement()) {
- hasWantedPath = hasWantedPath && haveSamePath(sourcePath, end);
- } else if(targetView != null && end.getRole() == targetView.getElement()) {
- hasWantedPath = hasWantedPath && haveSamePath(targetPath, end);
- }
- }
- return hasWantedPath;
- }
-
- /**
- *
- * @param wantedPath
- * the wanted nested path for the end
- * @param end
- * an end
- * @return
- * true if the end has as nested path THE wanted path
- */
- protected boolean haveSamePath(final List<Property> wantedPath, final ConnectorEnd end) {
- Stereotype ste = end.getAppliedStereotype("SysML::Blocks::NestedConnectorEnd");//$NON-NLS-1$
- if(ste != null) {
- final NestedConnectorEnd nestedConnectorEnd = (NestedConnectorEnd)end.getStereotypeApplication(ste);
- return nestedConnectorEnd.getPropertyPath().equals(wantedPath);
- } else {
- return wantedPath.isEmpty();
- }
- }
-}
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ * 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:
+ *
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.sysml.service.types.utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.sysml.blocks.Block;
+import org.eclipse.papyrus.sysml.blocks.NestedConnectorEnd;
+import org.eclipse.uml2.uml.ConnectableElement;
+import org.eclipse.uml2.uml.Connector;
+import org.eclipse.uml2.uml.ConnectorEnd;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Port;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.StructuredClassifier;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.TypedElement;
+import org.eclipse.uml2.uml.util.UMLUtil;
+
+/**
+ * Utility class for Connector edit helpers.
+ */
+public class ConnectorUtils extends org.eclipse.papyrus.uml.service.types.utils.ConnectorUtils {
+
+ /**
+ * the key used to store the nested path as parameter of the request. The value will be a List of {@link Property}
+ */
+ public static String NESTED_CONNECTOR_END_PATH = "connectorEndPath"; //$NON-NLS-1$
+
+ /** the separator used in the role path to distinguish the part. */
+ public static final String PART_SEPARATOR = "."; //$NON-NLS-1$
+
+ /** allow to know if a string contains others characters than a-z A-Z 0-9 and _. */
+ public static final String HAS_NO_WORD_CHAR_REGEX = "\\W+";
+
+ /** String used to delimit a name with contains special chars. */
+ public static final String STRING_DELIMITER = "\'";
+
+ /**
+ * Gets the encapsulated container.
+ *
+ * @param view the view
+ * @return the nearest encapsulated structure container or null
+ */
+ public View getEncapsulatedContainer(View view) {
+ View encapsulatedContainer = null;
+
+ for(View containerView : getStructureContainers(view)) {
+
+ if(view == containerView) {
+ continue;
+ }
+
+ if((view.getElement() instanceof Port) && (containerView.getChildren().contains(view))) {
+ continue;
+ }
+
+ StructuredClassifier structuredClassifier = getStructuredClassifier(containerView);
+ Block block = UMLUtil.getStereotypeApplication(structuredClassifier, Block.class);
+ if(block.isEncapsulated()) {
+ encapsulatedContainer = containerView;
+ break;
+ }
+ }
+
+ return encapsulatedContainer;
+ }
+
+ /**
+ * Test if an encapsulation crossing is required to connect the checked end to the opposite end.
+ *
+ * @param checkedEnd
+ * the checked end view.
+ * @param oppositeEnd
+ * the opposite end view.
+ * @return true if the gesture break encapsulation rule.
+ */
+ public boolean isCrossingEncapsulation(View checkedEnd, View oppositeEnd) {
+ boolean isCrossingEncapsulation = false;
+
+ View encapsulatedContainer = new ConnectorUtils().getEncapsulatedContainer(checkedEnd);
+ if(encapsulatedContainer != null) {
+ View containerView = new ConnectorUtils().deduceViewContainer(checkedEnd, oppositeEnd);
+ List<View> containers = new ConnectorUtils().getStructureContainers(checkedEnd);
+
+ if(containers.indexOf(encapsulatedContainer) < containers.indexOf(containerView)) {
+ isCrossingEncapsulation = true;
+ }
+ }
+
+ return isCrossingEncapsulation;
+ }
+
+ /**
+ * Get the path of structure views crossed by the checked end.
+ *
+ * @param checkedEnd
+ * the checked end view.
+ * @param oppositeEnd
+ * the opposite end view.
+ * @return the list of crossed structure views.
+ */
+ public List<View> getNestedPath(View checkedEnd, View oppositeEnd) {
+ List<View> isNestedConnectableElement = new ArrayList<View>();
+
+ View nearestContainer = new ConnectorUtils().getNearestStructureContainer(checkedEnd);
+ if(nearestContainer != null) {
+ View containerView = new ConnectorUtils().deduceViewContainer(checkedEnd, oppositeEnd);
+ List<View> containers = new ConnectorUtils().getStructureContainers(checkedEnd);
+
+ if(containers.indexOf(nearestContainer) < containers.indexOf(containerView)) {
+ isNestedConnectableElement = containers.subList(containers.indexOf(nearestContainer), containers.indexOf(containerView));
+ }
+ }
+
+ // nested path is taken from the top block to the deepest property ==> collection must be reverted
+ Collections.reverse(isNestedConnectableElement);
+
+ return isNestedConnectableElement;
+ }
+
+ /**
+ * Get the path of structure views crossed by the checked end.
+ *
+ * @param checkedEnd
+ * the checked end view.
+ * @param oppositeEnd
+ * the opposite end view.
+ * @return the list of crossed structure views.
+ */
+ public List<Property> getNestedPropertyPath(View checkedEnd, View oppositeEnd) {
+ List<Property> nestedPropertyPath = new ArrayList<Property>();
+ List<View> nestedPath = getNestedPath(checkedEnd, oppositeEnd);
+
+ for(View view : nestedPath) {
+ if((view.getElement() != null) && (view.getElement() instanceof Property)) {
+ nestedPropertyPath.add((Property)view.getElement());
+ }
+ }
+
+ // if end is a port, and the list is not empty, add the property from the check view in the list
+ if(!nestedPropertyPath.isEmpty() && checkedEnd.getElement() instanceof Port) {
+ Property partWithPort = getPartWithPort(checkedEnd, oppositeEnd);
+ if(partWithPort != null) {
+ nestedPropertyPath.add(partWithPort);
+ }
+ }
+
+ return nestedPropertyPath;
+ }
+
+ /**
+ * Test if the checked end is nested (means it cross StructuredClassifier borders).
+ *
+ * @param checkedEnd
+ * the checked end view.
+ * @param oppositeEnd
+ * the opposite end view.
+ * @return true if the checked end is nested.
+ */
+ public boolean isNestedConnectableElement(View checkedEnd, View oppositeEnd) {
+ return !(getNestedPath(checkedEnd, oppositeEnd).isEmpty());
+ }
+
+ /**
+ * Gets the nearest structure container.
+ *
+ * @param view the view
+ * @return the nearest structure container or null
+ */
+ public View getNearestStructureContainer(View view) {
+ View nearestStructureContainer = null;
+
+ for(View containerView : getStructureContainers(view)) {
+
+ if(view == containerView) {
+ continue;
+ }
+
+ if((view.getElement() instanceof Port) && (containerView.getChildren().contains(view))) {
+ continue;
+ }
+
+ nearestStructureContainer = containerView;
+ break;
+ }
+
+ return nearestStructureContainer;
+ }
+
+
+
+ /**
+ * Gets the role path.
+ *
+ * @param end the connector end
+ * @return the role path
+ * the path for the role of the connector end (without using label provider)
+ */
+ public static final String getRolePath(final ConnectorEnd end) {
+ final NestedConnectorEnd nestedConnectorEnd = UMLUtil.getStereotypeApplication(end, NestedConnectorEnd.class);
+ final ConnectableElement role = end.getRole();
+ final StringBuilder rolePath = new StringBuilder();
+ if(role != null) {
+ if(nestedConnectorEnd != null) {
+ final List<Property> properties = nestedConnectorEnd.getPropertyPath();
+ for(final Property current : properties) {
+ rolePath.append(getNameWithQuotes(current));
+ rolePath.append(ConnectorUtils.PART_SEPARATOR);
+ }
+ } else {
+ //when the stereotype is applied, the Property for partWithPort is included in the stereotype#path
+ final Property partWithPort = end.getPartWithPort();
+ if(partWithPort != null) {
+ rolePath.append(getNameWithQuotes(partWithPort));
+ rolePath.append(ConnectorUtils.PART_SEPARATOR);
+ }
+ }
+ rolePath.append(getNameWithQuotes(role));
+ }
+
+ return rolePath.toString();
+ }
+
+ /**
+ * Gets the name with quotes.
+ *
+ * @param property a property
+ * @return the name with quotes
+ * the property name with name delimiter if it is required
+ */
+ public static final String getNameWithQuotes(final NamedElement property) {
+ final String partName = property.getName();
+ final StringBuffer partNameBuffer = new StringBuffer();
+ final Pattern pattern = Pattern.compile(ConnectorUtils.HAS_NO_WORD_CHAR_REGEX);
+ final Matcher matcher = pattern.matcher(partName);
+ boolean mustHaveQuote = false;
+ while(matcher.find() && !mustHaveQuote) {
+ mustHaveQuote = true;
+ }
+ if(mustHaveQuote) {
+ partNameBuffer.append(ConnectorUtils.STRING_DELIMITER);
+ partNameBuffer.append(partName);
+ partNameBuffer.append(ConnectorUtils.STRING_DELIMITER);
+ } else {
+ partNameBuffer.append(partName);
+ }
+
+ return partNameBuffer.toString();
+ }
+
+ /**
+ * Checks if is crossing encapuslation.
+ *
+ * @param nestedPath the nested path
+ * @return true, if is crossing encapuslation
+ * <code>true</code> if we are breaking encapsulation (see SysML rules in SysML Standard 1.2, p.44):
+ * isEncapsulated: Boolean [0..1] If true, then the block is treated as a black box; a part typed by this black box can only be connected
+ * via its ports or directly to its outer boundary. If false, or if a value is not present, then connections can be established to
+ * elements of its internal structure via deep-nested connector ends.
+ */
+ public static final boolean isCrossingEncapuslation(final List<Property> nestedPath) {
+ for(final Property current : nestedPath) {
+ final Type type = current.getType();
+ if(type != null) {
+ final Block block = UMLUtil.getStereotypeApplication(type, Block.class);
+ if(block != null && block.isEncapsulated()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Can display existing connector between views according to nested paths.
+ *
+ * @param connector a connector existing in the model
+ * @param sourceView a potential source for this connector
+ * @param targetView a potential target for this connector
+ * @return true, if successful
+ * <code>true</code> if displaying the existing connector between this source and this target view is correct
+ */
+ public final boolean canDisplayExistingConnectorBetweenViewsAccordingToNestedPaths(final Connector connector, final View sourceView, final View targetView) {
+ ConnectorUtils utils = new ConnectorUtils();
+ final List<Property> sourcePath = utils.getNestedPropertyPath(sourceView, targetView);
+ final List<Property> targetPath = utils.getNestedPropertyPath(targetView, sourceView);
+ boolean hasWantedPath = true;
+ for(final ConnectorEnd end : connector.getEnds()) {
+ if(sourceView != null && end.getRole() == sourceView.getElement()) {
+ hasWantedPath = hasWantedPath && haveSamePath(sourcePath, end);
+ } else if(targetView != null && end.getRole() == targetView.getElement()) {
+ hasWantedPath = hasWantedPath && haveSamePath(targetPath, end);
+ }
+ }
+ return hasWantedPath;
+ }
+
+
+
+ /**
+ * Have same path.
+ *
+ * @param wantedPath the wanted nested path for the end
+ * @param end an end
+ * @return true, if successful
+ * true if the end has as nested path THE wanted path
+ */
+ protected boolean haveSamePath(final List<Property> wantedPath, final ConnectorEnd end) {
+ Stereotype ste = end.getAppliedStereotype("SysML::Blocks::NestedConnectorEnd");//$NON-NLS-1$
+ if(ste != null) {
+ final NestedConnectorEnd nestedConnectorEnd = (NestedConnectorEnd)end.getStereotypeApplication(ste);
+ return nestedConnectorEnd.getPropertyPath().equals(wantedPath);
+ } else {
+ return wantedPath.isEmpty();
+ }
+ }
+
+
+
+ /**
+ * Can display existing connector between views according to partWithPort.
+ *
+ * @param connector the connector
+ * @param sourceView the source view
+ * @param targetView the target view
+ * @return true, if successful
+ */
+ public boolean canDisplayExistingConnectorBetweenViewsAccordingToPartWithPort(final Connector connector, final View sourceView, final View targetView) {
+ Property partWithPort = getPartWithPortFromConnector(connector);
+ if (partWithPort != null){
+ String partWithPortName = partWithPort.getName();
+ Type partWithPortType = partWithPort.getType();
+ EObject sourceContainer = ((View) sourceView.eContainer()).getElement();
+ EObject targetContainer = ((View) targetView.eContainer()).getElement();
+
+ boolean sameSourceType = false;
+ if (sourceContainer instanceof TypedElement){
+ sameSourceType = partWithPortType.conformsTo(((TypedElement)sourceContainer).getType());
+ }
+ boolean sameSourceName = partWithPortName.equals(((NamedElement) sourceContainer).getName());
+
+ boolean sameTargetType = false;
+ if (targetContainer instanceof TypedElement){
+ sameTargetType = partWithPortType.conformsTo(((TypedElement)targetContainer).getType());
+ }
+ boolean sametargetName = partWithPortName.equals(((NamedElement) targetContainer).getName());
+
+ return (sameSourceType && sameSourceName) || (sameTargetType && sametargetName);
+ }
+ return true;
+ }
+
+ /**
+ * Gets the partWithPort from the connector.
+ *
+ * @param connector the connector
+ * @return the part with port from connector
+ */
+ public Property getPartWithPortFromConnector(final Connector connector){
+ if (connector!=null && connector.getEnds() != null){
+ for(final ConnectorEnd end : connector.getEnds()) {
+ Property partWithPort = end.getPartWithPort();
+ if (partWithPort != null){
+ return partWithPort;
+ }
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractUMLShowHideRelatedLinkEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractUMLShowHideRelatedLinkEditPolicy.java
index 1d95e90..3cc7b3b 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractUMLShowHideRelatedLinkEditPolicy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractUMLShowHideRelatedLinkEditPolicy.java
@@ -1,268 +1,268 @@
-/*****************************************************************************
- * Copyright (c) 2013 CEA LIST.
- *
- *
- * 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:
- * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.uml.diagram.common.editpolicies;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.commands.Command;
-import org.eclipse.gmf.runtime.common.core.command.CommandResult;
-import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
-import org.eclipse.gmf.runtime.common.core.command.ICommand;
-import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
-import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.gmf.tooling.runtime.update.UpdaterLinkDescriptor;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.window.Window;
-import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy;
-import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.EdgeWithNoSemanticElementRepresentationImpl;
-import org.eclipse.papyrus.uml.diagram.common.helper.LinkMappingHelper;
-import org.eclipse.papyrus.uml.diagram.common.ui.dialogs.ShowHideRelatedLinkSelectionDialog;
-import org.eclipse.papyrus.uml.diagram.common.util.LinkEndsMapper;
-import org.eclipse.papyrus.uml.tools.providers.UMLLabelProvider;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.uml2.uml.Comment;
-import org.eclipse.uml2.uml.Connector;
-import org.eclipse.uml2.uml.Constraint;
-import org.eclipse.uml2.uml.DirectedRelationship;
-import org.eclipse.uml2.uml.Element;
-import org.eclipse.uml2.uml.Relationship;
-
-
-/**
- *
- * Abstract class used to show hide related links on UML Diagram
- *
- */
-public abstract class AbstractUMLShowHideRelatedLinkEditPolicy extends AbstractShowHideRelatedLinkEditPolicy {
-
-
- /**
- *
- * Constructor.
- *
- * @param host
- * the host for this edit policy
- */
- public AbstractUMLShowHideRelatedLinkEditPolicy(final DiagramEditPart host) {
- super(host);
- }
-
-
- /**
- *
- * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#getShowHideRelatedLinkCommandWithDialog(java.util.Collection,
- * java.util.Map, java.util.Set, java.util.Map, java.util.Collection)
- *
- * @param selectedEditParts
- * @param availableLinks
- * @param visibleLinks
- * @param domain2NotationMap
- * @param linksDescriptors
- * @return
- * the command which open a dialog to ask for the user to select visible links, chained with the command to show/hide the links according
- * to the user selection
- */
- @Override
- protected Command getShowHideRelatedLinkCommandWithDialog(final Collection<EditPart> selectedEditParts, final Map<EditPart, Set<EObject>> availableLinks, final Set<EObject> visibleLinks, final Map<EObject, View> domain2NotationMap, final Collection<UpdaterLinkDescriptor> linksDescriptors) {
- //0. build the mapping between semantic link and their representations used in the dialog
- final Map<EObject, LinkEndsMapper> linkMapping = new HashMap<EObject, LinkEndsMapper>();
- final Iterator<UpdaterLinkDescriptor> iter = linksDescriptors.iterator();
- while(iter.hasNext()) {
- final UpdaterLinkDescriptor current = iter.next();
- final EObject link = current.getModelElement();
- if(link instanceof Element) {
- linkMapping.put(link, createLinkEndMapper((Element)link, current));
- } else if(link instanceof EdgeWithNoSemanticElementRepresentationImpl) {
- final EObject source = ((EdgeWithNoSemanticElementRepresentationImpl)link).getSource();
- if(source instanceof Comment || source instanceof Constraint) {
- linkMapping.put(link, createLinkEndMapper((Element)source, current));
- }
- }
- }
-
- final TransactionalEditingDomain domain = getEditingDomain();
- final CompositeCommand compositeCommand = new CompositeCommand("Show/Hide Related Link Command"); //$NON-NLS-1$
- final ICommand cmd = getOpenDialogCommand(domain, selectedEditParts, availableLinks, visibleLinks, linkMapping);
- compositeCommand.add(cmd);
- compositeCommand.add(getComputeCommandResultCommand(domain, cmd, visibleLinks, domain2NotationMap, linksDescriptors));
- return new ICommandProxy(compositeCommand);
- }
-
-
-
-
-
- /**
- *
- * @param descriptor
- * the link descriptor
- * @return
- * the collection of link descriptors without some invalid descriptor (we get this case when the link doesn't have source AND target, but
- * only ends)
- */
- protected Collection<UpdaterLinkDescriptor> removeInvalidLinkDescriptor(final Collection<UpdaterLinkDescriptor> descriptor) {
- final Collection<UpdaterLinkDescriptor> firstResult = super.removeInvalidLinkDescriptor(descriptor);
- final Collection<UpdaterLinkDescriptor> result = new ArrayList<UpdaterLinkDescriptor>();
- final Iterator<UpdaterLinkDescriptor> iter = firstResult.iterator();
- while(iter.hasNext()) {
- final UpdaterLinkDescriptor current = iter.next();
- final EObject modelElement = current.getModelElement();
-
- /*
- * for example, for association between Class1 and class2, we get a link descriptor between class1 and class2 BUT another one between
- * class1 and class1...
- */
- if(!isAnOrientedLink(modelElement)) {
- EObject src = current.getSource();
- EObject target = current.getDestination();
- if(src == target) {
- final Collection<?> sources = LinkMappingHelper.getSource((Element)modelElement);
- final Collection<?> targets = LinkMappingHelper.getTarget((Element)modelElement);
- if(sources.size() > 1 && sources.equals(targets)) {
- int nbOccurencesInSource = 0;
- final Iterator<?> iterSrc = sources.iterator();
- while(nbOccurencesInSource < 2 && iterSrc.hasNext()) {
- if(iterSrc.next() == src) {
- nbOccurencesInSource++;
- }
- }
-
- int nbOccurencesInTarget = 0;
- final Iterator<?> iterTarget = targets.iterator();
- while(nbOccurencesInTarget < 2 && iterTarget.hasNext()) {
- if(iterTarget.next() == src) {
- nbOccurencesInTarget++;
- }
- }
-
- if(nbOccurencesInSource > 1 || nbOccurencesInTarget > 1) {
- //do nothing;
- } else {
- continue;//we must exclude it!
- }
- } else if(!(sources.contains(src) && targets.contains(src))) {
- continue;
- }
- }
- }
- result.add(current);
- }
- return result;
- }
-
- /**
- *
- * @return
- * <code>true</code> if the link is oriented and <code>false</code> if not.
- * If not, that is to say than {@link LinkMappingHelper} should returns the same values for sources and targets
- */
- public static final boolean isAnOrientedLink(final EObject link) {
- if(link instanceof DirectedRelationship) {
- return true;
- } else if(link instanceof Relationship) {
- return false;
- } else if(link instanceof Connector) {
- return false;
- } else if(link instanceof Comment || link instanceof Constraint) {
- return true;
- }
- return false;
- }
-
-
-
-
- /**
- *
- * @param element
- * an element
- * @return
- * a linkEndsMapper according to this element
- */
- public static final LinkEndsMapper createLinkEndMapper(final Element element, final UpdaterLinkDescriptor descriptor) {
- Collection<?> ends;
- Collection<?> sources;
- Collection<?> targets;
- if(element instanceof Comment || element instanceof Constraint) {
- ends = Collections.emptyList();
- sources = Collections.singletonList(descriptor.getSource());
- targets = Collections.singletonList(descriptor.getDestination());
- } else if(isAnOrientedLink(element)) {
- ends = Collections.emptyList();
- sources = LinkMappingHelper.getSource(element);
- targets = LinkMappingHelper.getTarget(element);
- } else {
- ends = LinkMappingHelper.getSource(element);
- sources = Collections.emptyList();
- targets = Collections.emptyList();
- }
- return new LinkEndsMapper(element, ends, sources, targets);
- }
-
- /**
- *
- * @param domain
- * the editing domain
- * @return
- * the command to open the dialog to choose the link to show
- */
- protected ICommand getOpenDialogCommand(final TransactionalEditingDomain domain, final Collection<EditPart> selectedEditPart, final Map<EditPart, Set<EObject>> availableLinks, final Collection<EObject> initialSelection, final Map<EObject, LinkEndsMapper> linkMapping) {
- final ICommand cmd = new AbstractTransactionalCommand(domain, "Open Show/HideDialogCommand", null) {//$NON-NLS-1$
-
- @Override
- protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
- final ShowHideRelatedLinkSelectionDialog dialog = new ShowHideRelatedLinkSelectionDialog(Display.getDefault().getActiveShell(), getLabelProvider(), new AbstractShowHideRelatedLinkEditPolicy.LinkContentProvider(availableLinks), availableLinks, linkMapping);
- dialog.setTitle("Show/Hide Links");//$NON-NLS-1$
- dialog.setMessage("Choose the links to show.");//$NON-NLS-1$
- dialog.setInput(selectedEditPart);
- dialog.setInitialSelection(initialSelection);
- dialog.setExpandedElements(selectedEditPart.toArray());
- dialog.setContainerMode(true);
- int status = dialog.open();
- if(status == Window.CANCEL) {
- return CommandResult.newCancelledCommandResult();
- }
- return CommandResult.newOKCommandResult(Arrays.asList(dialog.getResult()));
- }
- };
-
- return cmd;
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#getLabelProvider()
- *
- * @return
- */
- @Override
- protected ILabelProvider getLabelProvider() {
- return new UMLLabelProvider();
- }
-}
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.diagram.common.editpolicies;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.tooling.runtime.update.UpdaterLinkDescriptor;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy;
+import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.EdgeWithNoSemanticElementRepresentationImpl;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.Domain2Notation;
+import org.eclipse.papyrus.uml.diagram.common.helper.LinkMappingHelper;
+import org.eclipse.papyrus.uml.diagram.common.ui.dialogs.ShowHideRelatedLinkSelectionDialog;
+import org.eclipse.papyrus.uml.diagram.common.util.LinkEndsMapper;
+import org.eclipse.papyrus.uml.tools.providers.UMLLabelProvider;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.Connector;
+import org.eclipse.uml2.uml.Constraint;
+import org.eclipse.uml2.uml.DirectedRelationship;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Relationship;
+
+
+/**
+ *
+ * Abstract class used to show hide related links on UML Diagram
+ *
+ */
+public abstract class AbstractUMLShowHideRelatedLinkEditPolicy extends AbstractShowHideRelatedLinkEditPolicy {
+
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param host
+ * the host for this edit policy
+ */
+ public AbstractUMLShowHideRelatedLinkEditPolicy(final DiagramEditPart host) {
+ super(host);
+ }
+
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#getShowHideRelatedLinkCommandWithDialog(java.util.Collection,
+ * java.util.Map, java.util.Set, java.util.Map, java.util.Collection)
+ *
+ * @param selectedEditParts
+ * @param availableLinks
+ * @param visibleLinks
+ * @param domain2NotationMap
+ * @param linksDescriptors
+ * @return
+ * the command which open a dialog to ask for the user to select visible links, chained with the command to show/hide the links according
+ * to the user selection
+ */
+ @Override
+ protected Command getShowHideRelatedLinkCommandWithDialog(final Collection<EditPart> selectedEditParts, final Map<EditPart, Set<EObject>> availableLinks, final Set<EObject> visibleLinks, final Domain2Notation domain2NotationMap, final Collection<UpdaterLinkDescriptor> linksDescriptors) {
+ //0. build the mapping between semantic link and their representations used in the dialog
+ final Map<EObject, LinkEndsMapper> linkMapping = new HashMap<EObject, LinkEndsMapper>();
+ final Iterator<UpdaterLinkDescriptor> iter = linksDescriptors.iterator();
+ while(iter.hasNext()) {
+ final UpdaterLinkDescriptor current = iter.next();
+ final EObject link = current.getModelElement();
+ if(link instanceof Element) {
+ linkMapping.put(link, createLinkEndMapper((Element)link, current));
+ } else if(link instanceof EdgeWithNoSemanticElementRepresentationImpl) {
+ final EObject source = ((EdgeWithNoSemanticElementRepresentationImpl)link).getSource();
+ if(source instanceof Comment || source instanceof Constraint) {
+ linkMapping.put(link, createLinkEndMapper((Element)source, current));
+ }
+ }
+ }
+
+ final TransactionalEditingDomain domain = getEditingDomain();
+ final CompositeCommand compositeCommand = new CompositeCommand("Show/Hide Related Link Command"); //$NON-NLS-1$
+ final ICommand cmd = getOpenDialogCommand(domain, selectedEditParts, availableLinks, visibleLinks, linkMapping);
+ compositeCommand.add(cmd);
+ compositeCommand.add(getComputeCommandResultCommand(domain, cmd, visibleLinks, domain2NotationMap, linksDescriptors));
+ return new ICommandProxy(compositeCommand);
+ }
+
+
+
+
+
+ /**
+ *
+ * @param descriptor
+ * the link descriptor
+ * @return
+ * the collection of link descriptors without some invalid descriptor (we get this case when the link doesn't have source AND target, but
+ * only ends)
+ */
+ protected Collection<UpdaterLinkDescriptor> removeInvalidLinkDescriptor(final Collection<UpdaterLinkDescriptor> descriptor) {
+ final Collection<UpdaterLinkDescriptor> firstResult = super.removeInvalidLinkDescriptor(descriptor);
+ final Collection<UpdaterLinkDescriptor> result = new ArrayList<UpdaterLinkDescriptor>();
+ final Iterator<UpdaterLinkDescriptor> iter = firstResult.iterator();
+ while(iter.hasNext()) {
+ final UpdaterLinkDescriptor current = iter.next();
+ final EObject modelElement = current.getModelElement();
+
+ /*
+ * for example, for association between Class1 and class2, we get a link descriptor between class1 and class2 BUT another one between
+ * class1 and class1...
+ */
+ if(!isAnOrientedLink(modelElement)) {
+ EObject src = current.getSource();
+ EObject target = current.getDestination();
+ if(src == target) {
+ final Collection<?> sources = LinkMappingHelper.getSource((Element)modelElement);
+ final Collection<?> targets = LinkMappingHelper.getTarget((Element)modelElement);
+ if(sources.size() > 1 && sources.equals(targets)) {
+ int nbOccurencesInSource = 0;
+ final Iterator<?> iterSrc = sources.iterator();
+ while(nbOccurencesInSource < 2 && iterSrc.hasNext()) {
+ if(iterSrc.next() == src) {
+ nbOccurencesInSource++;
+ }
+ }
+
+ int nbOccurencesInTarget = 0;
+ final Iterator<?> iterTarget = targets.iterator();
+ while(nbOccurencesInTarget < 2 && iterTarget.hasNext()) {
+ if(iterTarget.next() == src) {
+ nbOccurencesInTarget++;
+ }
+ }
+
+ if(nbOccurencesInSource > 1 || nbOccurencesInTarget > 1) {
+ //do nothing;
+ } else {
+ continue;//we must exclude it!
+ }
+ } else if(!(sources.contains(src) && targets.contains(src))) {
+ continue;
+ }
+ }
+ }
+ result.add(current);
+ }
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ * <code>true</code> if the link is oriented and <code>false</code> if not.
+ * If not, that is to say than {@link LinkMappingHelper} should returns the same values for sources and targets
+ */
+ public static final boolean isAnOrientedLink(final EObject link) {
+ if(link instanceof DirectedRelationship) {
+ return true;
+ } else if(link instanceof Relationship) {
+ return false;
+ } else if(link instanceof Connector) {
+ return false;
+ } else if(link instanceof Comment || link instanceof Constraint) {
+ return true;
+ }
+ return false;
+ }
+
+
+
+
+ /**
+ *
+ * @param element
+ * an element
+ * @return
+ * a linkEndsMapper according to this element
+ */
+ public static final LinkEndsMapper createLinkEndMapper(final Element element, final UpdaterLinkDescriptor descriptor) {
+ Collection<?> ends;
+ Collection<?> sources;
+ Collection<?> targets;
+ if(element instanceof Comment || element instanceof Constraint) {
+ ends = Collections.emptyList();
+ sources = Collections.singletonList(descriptor.getSource());
+ targets = Collections.singletonList(descriptor.getDestination());
+ } else if(isAnOrientedLink(element)) {
+ ends = Collections.emptyList();
+ sources = LinkMappingHelper.getSource(element);
+ targets = LinkMappingHelper.getTarget(element);
+ } else {
+ ends = LinkMappingHelper.getSource(element);
+ sources = Collections.emptyList();
+ targets = Collections.emptyList();
+ }
+ return new LinkEndsMapper(element, ends, sources, targets);
+ }
+
+ /**
+ *
+ * @param domain
+ * the editing domain
+ * @return
+ * the command to open the dialog to choose the link to show
+ */
+ protected ICommand getOpenDialogCommand(final TransactionalEditingDomain domain, final Collection<EditPart> selectedEditPart, final Map<EditPart, Set<EObject>> availableLinks, final Collection<EObject> initialSelection, final Map<EObject, LinkEndsMapper> linkMapping) {
+ final ICommand cmd = new AbstractTransactionalCommand(domain, "Open Show/HideDialogCommand", null) {//$NON-NLS-1$
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ final ShowHideRelatedLinkSelectionDialog dialog = new ShowHideRelatedLinkSelectionDialog(Display.getDefault().getActiveShell(), getLabelProvider(), new AbstractShowHideRelatedLinkEditPolicy.LinkContentProvider(availableLinks), availableLinks, linkMapping);
+ dialog.setTitle("Show/Hide Links");//$NON-NLS-1$
+ dialog.setMessage("Choose the links to show.");//$NON-NLS-1$
+ dialog.setInput(selectedEditPart);
+ dialog.setInitialSelection(initialSelection);
+ dialog.setExpandedElements(selectedEditPart.toArray());
+ dialog.setContainerMode(true);
+ int status = dialog.open();
+ if(status == Window.CANCEL) {
+ return CommandResult.newCancelledCommandResult();
+ }
+ return CommandResult.newOKCommandResult(Arrays.asList(dialog.getResult()));
+ }
+ };
+
+ return cmd;
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractShowHideRelatedLinkEditPolicy#getLabelProvider()
+ *
+ * @return
+ */
+ @Override
+ protected ILabelProvider getLabelProvider() {
+ return new UMLLabelProvider();
+ }
+}