/***************************************************************************** * Copyright (c) 2010 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: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.editpolicies; import java.util.ArrayList; import java.util.Iterator; import java.util.Map; import org.eclipse.draw2d.geometry.Point; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EAnnotation; 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.gef.editpolicies.GraphicalEditPolicy; import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker; import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener; import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.infra.core.listenerservice.IPapyrusListener; import org.eclipse.papyrus.uml.appearance.helper.AppliedStereotypeHelper; import org.eclipse.papyrus.uml.appearance.helper.UMLVisualInformationPapyrusConstant; import org.eclipse.papyrus.uml.diagram.common.editparts.AbstractShapeEditPart; import org.eclipse.uml2.uml.Element; public abstract class ChangeStereotypedShapeEditPolicy extends GraphicalEditPolicy implements NotificationListener, IPapyrusListener { /** constant for this edit policy role */ public final static String CHANGE_SHAPE_POLICY = "CHANGE_SHAPE_POLICY"; /** host semantic element */ protected Element hostSemanticElement; /** * Creates a new AppliedStereotype display edit policy */ public ChangeStereotypedShapeEditPolicy() { super(); } /** * Gets the diagram event broker from the editing domain. * * @return the diagram event broker */ protected DiagramEventBroker getDiagramEventBroker() { TransactionalEditingDomain theEditingDomain = ((IGraphicalEditPart)getHost()).getEditingDomain(); if(theEditingDomain != null) { return DiagramEventBroker.getInstance(theEditingDomain); } return null; } /** * Returns the uml element controlled by the host edit part * * @return the uml element controlled by the host edit part * can return null if this semantic element is not an uml element */ protected Element getUMLElement() { if(getView().getElement() instanceof Element) { return (Element)getView().getElement(); } return null; } /** * Returns the view controlled by the host edit part * * @return the view controlled by the host edit part */ protected View getView() { return (View)getHost().getModel(); } /** * get all semantic link that are source or target of the graphical edit part * @param gmfpart the graphical editpart for each we look for source and target link * @return a list of eobject */ public ArrayList<EObject> getAllSemanticLink(GraphicalEditPart gmfpart){ ArrayList<EObject> elementToDrop= new ArrayList<EObject>(); Iterator linkIter= gmfpart.getNotationView().getSourceEdges().iterator(); while(linkIter.hasNext()) { Edge edge = (Edge)linkIter.next(); if(edge.getElement()!=null){ elementToDrop.add(edge.getElement()); } } linkIter= gmfpart.getNotationView().getTargetEdges().iterator(); while(linkIter.hasNext()) { Edge edge = (Edge)linkIter.next(); if(edge.getElement()!=null){ elementToDrop.add(edge.getElement()); } } return elementToDrop; } /** * drop a set of link into the container * @param gmfparent the parent which contain the links * @param elementToDrop contains the list of semantic link to drop * */ public void dropLink(GraphicalEditPart gmfparent, ArrayList<EObject> elementToDrop){ Iterator<EObject> iterDrop= elementToDrop.iterator(); while(iterDrop.hasNext()) { EObject currentObject = (EObject)iterDrop.next(); DropObjectsRequest dropObjectsRequest= new DropObjectsRequest(); ArrayList<EObject> list = new ArrayList<EObject>(); list.add((Element)currentObject); dropObjectsRequest.setObjects(list); dropObjectsRequest.setLocation(new Point(0,0)); Command cmd= gmfparent.getCommand(dropObjectsRequest); gmfparent.getDiagramEditDomain().getDiagramCommandStack().execute(cmd); } } /** * * {@inheritedDoc} */ public void notifyChanged(Notification notification) { // change the label of the figure managed by the host edit part (managed by the parent edit // part in general...) // it must be changed only if: // - the annotation corresponding to the display of the stereotype changes // - the stereotype application list has changed // if element that has changed is a stereotype => refresh the label. if(notification.getNotifier() instanceof EAnnotation) { if(UMLVisualInformationPapyrusConstant.STEREOTYPE_ANNOTATION == ((EAnnotation)notification.getNotifier()).getSource()) { // stereotype annotation has changed => refresh label display //add a test about kind old value if(!(getHost() instanceof AbstractShapeEditPart) && AppliedStereotypeHelper.getAppliedStereotypePresentationKind(getView()) == UMLVisualInformationPapyrusConstant.IMAGE_STEREOTYPE_PRESENTATION) { if(notification.getNewValue() instanceof Map.Entry<?, ?>) { if(((Map.Entry<?, ?>)notification.getNewValue()).getKey().equals(UMLVisualInformationPapyrusConstant.STEREOTYPE_PRESENTATION_KIND)) { transformIntoShape(getHost()); } } } if((getHost() instanceof AbstractShapeEditPart) && AppliedStereotypeHelper.getAppliedStereotypePresentationKind(getView()) != UMLVisualInformationPapyrusConstant.IMAGE_STEREOTYPE_PRESENTATION) { if(notification.getNewValue() instanceof Map.Entry<?, ?>) { if(((Map.Entry<?, ?>)notification.getNewValue()).getKey().equals(UMLVisualInformationPapyrusConstant.STEREOTYPE_PRESENTATION_KIND)) { transformIntoNormalShape(getHost()); } } } } } } /** * * {@inheritDoc} */ public void activate() { // retrieve the view and the element managed by the edit part View view = getView(); if(view == null) { return; } hostSemanticElement = getUMLElement(); // adds a listener on the view and the element controlled by the editpart getDiagramEventBroker().addNotificationListener(view, this); if(hostSemanticElement == null) { return; } getDiagramEventBroker().addNotificationListener(hostSemanticElement, this); // adds the listener for stereotype application and applied stereotypes // add listener to react to the application and remove of a stereotype // add a lister to each already applied stereotyped for(EObject stereotypeApplication : hostSemanticElement.getStereotypeApplications()) { getDiagramEventBroker().addNotificationListener(stereotypeApplication, this); } } /** * * {@inheritDoc} */ public void deactivate() { // retrieve the view and the element managed by the edit part View view = getView(); if(view == null) { return; } getDiagramEventBroker().removeNotificationListener(view, this); if(hostSemanticElement == null) { return; } // remove listeners to applied stereotyped for(EObject stereotypeApplication : hostSemanticElement.getStereotypeApplications()) { getDiagramEventBroker().removeNotificationListener(stereotypeApplication, this); } // remove notification on element getDiagramEventBroker().removeNotificationListener(hostSemanticElement, this); // removes the reference to the semantic element hostSemanticElement = null; } /** * implementation to transform this editpart into shape from the stereotype * * @param part * the graphical editpart to change */ public abstract void transformIntoShape(EditPart part); /** * implementation to transform a shape editpart into normal editpart * * @param part * the graphical editpart to change */ public abstract void transformIntoNormalShape(EditPart part); }