/***************************************************************************** * 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: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.editpolicies; import java.util.StringTokenizer; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand; import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper; import org.eclipse.papyrus.uml.appearance.helper.AppliedStereotypeHelper; import org.eclipse.papyrus.uml.appearance.helper.UMLVisualInformationPapyrusConstant; import org.eclipse.papyrus.uml.diagram.common.commands.CreateAppliedStereotypePropertyViewCommand; import org.eclipse.papyrus.uml.diagram.common.editparts.AppliedStereotypePropertyEditPart; import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil; import org.eclipse.swt.widgets.Display; import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.Property; import org.eclipse.uml2.uml.Stereotype; import org.eclipse.uml2.uml.util.UMLUtil; /** * This editpolicy is used to add dynamically labels of stereotypes into nodes int the context of AppliedStereorypeCompartmentEditpart */ public class AppliedStereotypePropertiesEditPolicy extends AppliedStereotypeNodeLabelDisplayEditPolicy { public static String APPLIED_STEREOTYPE_VISIBILITY_COMPARTMENT= "AppliedStereotypeVisibilityEditPolicy"; /** * Creates a new AppliedStereotype display edit policy */ public AppliedStereotypePropertiesEditPolicy() { super(); } /** * Returns the uml element controlled by the host edit part * * @return the uml element controlled by the host edit part */ protected Element getUMLElement() { return (Element)((View)getView().eContainer()).getElement(); } /** * * @see org.eclipse.papyrus.uml.diagram.common.editpolicies.AbstractAppliedStereotypeDisplayEditPolicy#getView() * * @return */ protected View getView() { return (View)((EObject)getHost().getModel()).eContainer(); } /** * this method is used to create a notation node for the property of the stereotype * @param editPart the editpart container * @param property the property of the stereotype that we want to edit with the application of the stereotype */ protected void executeAppliedStereotypePropertytCreation(final GraphicalEditPart editPart, final Property property) { try { editPart.getEditingDomain().runExclusive(new Runnable() { public void run() { Display.getCurrent().asyncExec(new Runnable() { public void run() { CreateAppliedStereotypePropertyViewCommand command= new CreateAppliedStereotypePropertyViewCommand(editPart.getEditingDomain(), editPart.getNotationView(), property); editPart.getEditingDomain().getCommandStack().execute(command); } }); } }); } catch (Exception e) { System.err.println(e); } } /** * * {@inheritedDoc} */ public void notifyChanged(Notification notification) { // refresh obly when the EAnnotation about stereotype is added or remove // to update only property of stereotype application // if element that has changed is a stereotype => refresh the label. if(notification.getNotifier() instanceof Node && (notification.getEventType()==Notification.ADD) &&(notification.getNewValue() instanceof EAnnotation)) { if(UMLVisualInformationPapyrusConstant.STEREOTYPE_ANNOTATION == ((EAnnotation)notification.getNewValue()).getSource() ) { // stereotype annotation has changed => refresh label display refreshDisplay(); } } } /** * maybe to remove */ protected void refreshEAnnotation() { final GraphicalEditPart editPart= (GraphicalEditPart)getHost(); String presentationKind = AppliedStereotypeHelper.getAppliedStereotypePresentationKind((View)editPart.getNotationView().eContainer()); EObject stereotypeApplication=editPart.resolveSemanticElement(); Stereotype stereotype=UMLUtil.getStereotype(stereotypeApplication); final RecordingCommand command=AppliedStereotypeHelper.getAddAppliedStereotypeCommand(editPart.getEditingDomain(), editPart.getNotationView(), stereotype.getQualifiedName(), presentationKind); try { editPart.getEditingDomain().runExclusive(new Runnable() { public void run() { Display.getCurrent().asyncExec(new Runnable() { public void run() { editPart.getEditingDomain().getCommandStack().execute(command); } }); } }); } catch (Exception e) { System.err.println(e); } } protected void refreshStereotypeDisplay() {} /** * Refreshes the stereotype application property */ public void refreshDisplay() { String stereotypesPropertiesToDisplay = AppliedStereotypeHelper.getAppliedStereotypesPropertiesToDisplay((View)((View)getHost().getModel()).eContainer()); final GraphicalEditPart editPart= (GraphicalEditPart)getHost(); final View node=editPart.getNotationView(); //1. Manage adding of application stereotype properties EObject stereotypeApplication=editPart.resolveSemanticElement(); Stereotype stereotype=UMLUtil.getStereotype(stereotypeApplication); //go through each stereotype property manageAddingStereotypeProperties(stereotypesPropertiesToDisplay, editPart, node, stereotype); //Manage removing of Stereotype application properties manageRemovingPropertiesNodes(stereotypesPropertiesToDisplay, editPart, node, stereotype); } /** * this method is used to add if needed propertyNode by taking in account a list of properties to display * @param stereotypesPropertiesToDisplay a list of qualified name of properties * @param editPart the graphical editpart that is the container * @param node the notation node that is the container * @param stereotype the stereotype that is display in this container */ protected void manageAddingStereotypeProperties(String stereotypesPropertiesToDisplay, final GraphicalEditPart editPart, final View node, Stereotype stereotype) { // fill our data structure in order to generate the string StringTokenizer propStringTokenizer = new StringTokenizer(stereotypesPropertiesToDisplay, ","); while(propStringTokenizer.hasMoreElements()) { // extract property to display String propertyQN = propStringTokenizer.nextToken(); //get a property that is interesting for us if( propertyQN.startsWith(stereotype.getQualifiedName())){ String propertyName= propertyQN.substring(propertyQN.lastIndexOf(".")+1); Property stereotypeProperty=StereotypeUtil.getPropertyByName(stereotype, propertyName); Node sterotypePropertyNode= null; int i=0; //we go through all sub nodes to get sub node that is link to this property while(i<node.getChildren().size()&&sterotypePropertyNode==null){ if( (node.getChildren().get(i)) instanceof Node){ final Node currentNode=(Node)(node.getChildren().get(i)); if(currentNode.getType().equals(AppliedStereotypePropertyEditPart.ID)){ if( currentNode.getElement().equals(stereotypeProperty)){ sterotypePropertyNode= currentNode; } } } i++; } if( sterotypePropertyNode==null){ executeAppliedStereotypePropertytCreation(editPart, stereotypeProperty); } } } } /** * this method is used to remove nodes of property that are not in a given list *@param stereotypesPropertiesToDisplay a list of qualified name of properties * @param editPart the graphical editpart that is the container * @param node the notation node that is the container * @param stereotype the stereotype that is display in this container */ protected void manageRemovingPropertiesNodes(String stereotypesPropertiesToDisplay, final GraphicalEditPart editPart, final View node, Stereotype stereotype) { int i=0; while(i<node.getChildren().size()){ if( (node.getChildren().get(i)) instanceof Node){ final Node currentNode=(Node)(node.getChildren().get(i)); if(currentNode.getType().equals(AppliedStereotypePropertyEditPart.ID)){ Property property=(Property)currentNode.getElement(); String propertyQN= stereotype.getQualifiedName()+"."+property.getName(); if(!stereotypesPropertiesToDisplay.contains(propertyQN) ){ try{ //yes, Execution of the Deletion command editPart.getEditingDomain().runExclusive(new Runnable() { public void run() { Display.getCurrent().asyncExec(new Runnable() { public void run() { DeleteCommand command= new DeleteCommand(currentNode); editPart.getEditingDomain().getCommandStack().execute(new GMFtoEMFCommandWrapper(command)); } }); } }); } catch (Exception e) { System.err.println(e); } } } } i++; } } }