/***************************************************************************** * 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: * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.composite.custom.helper.advice; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.emf.ecore.EObject; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.gmf.runtime.emf.type.core.IHintedType; import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyReferenceRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.common.util.CrossReferencerUtil; import org.eclipse.papyrus.uml.diagram.composite.edit.parts.CompositeStructureDiagramEditPart; import org.eclipse.papyrus.uml.diagram.composite.providers.UMLElementTypes; import org.eclipse.uml2.uml.Collaboration; import org.eclipse.uml2.uml.ConnectableElement; import org.eclipse.uml2.uml.UMLPackage; /** * * This advice is used to remove the view of the Collaboration roles * */ public class CollaborationHelperAdvice extends AbstractEditHelperAdvice { /** The hint of Collaboration role (not always possible to distinguish role and property with the model information). */ final String COLLABORATION_ROLE_HINT = ((IHintedType)UMLElementTypes.ConnectableElement_3115).getSemanticHint(); /** The hint of Collaboration role (not always possible to distinguish role and property with the model information). */ final String ROLE_BINDING_HINT = ((IHintedType)UMLElementTypes.Dependency_4017).getSemanticHint(); @Override protected ICommand getBeforeDestroyReferenceCommand(DestroyReferenceRequest request) { EObject elementToEdit = request.getContainer(); Set<View> viewsToDelete = new HashSet<View>(); // Test if current destroy reference is removing a Property from Collaboration role if((elementToEdit instanceof Collaboration) && (request.getContainingFeature() == UMLPackage.eINSTANCE.getCollaboration_CollaborationRole())) { // Removed referenced ConnectableElement from roles ConnectableElement refRole = (ConnectableElement)request.getReferencedObject(); Collaboration collaborationToEdit = (Collaboration)elementToEdit; viewsToDelete.addAll(getViewsForRole(refRole, collaborationToEdit)); } if((viewsToDelete != null) && !(viewsToDelete.isEmpty())) { DestroyDependentsRequest req = new DestroyDependentsRequest(request.getEditingDomain(), elementToEdit, false); return req.getDestroyDependentsCommand(viewsToDelete); } return null; } @Override protected ICommand getBeforeSetCommand(SetRequest request) { EObject elementToEdit = request.getElementToEdit(); Set<View> viewsToDelete = new HashSet<View>(); if((elementToEdit instanceof Collaboration) && (request.getFeature() == UMLPackage.eINSTANCE.getCollaboration_CollaborationRole())) { Collaboration collaborationToEdit = (Collaboration)elementToEdit; // Get the list of roles currently removed Set<ConnectableElement> removedRoles = new HashSet<ConnectableElement>(); removedRoles.addAll(collaborationToEdit.getRoles()); if(request.getValue() instanceof ConnectableElement) { removedRoles.remove((ConnectableElement)request.getValue()); } else if(request.getValue() instanceof List<?>) { removedRoles.removeAll((List<?>)request.getValue()); } // Parse removed roles and find views to delete Iterator<ConnectableElement> it = removedRoles.iterator(); while(it.hasNext()) { ConnectableElement currentRole = it.next(); viewsToDelete.addAll(getViewsForRole(currentRole, collaborationToEdit)); } } if((viewsToDelete != null) && !(viewsToDelete.isEmpty())) { DestroyDependentsRequest req = new DestroyDependentsRequest(request.getEditingDomain(), elementToEdit, false); return req.getDestroyDependentsCommand(viewsToDelete); } return null; } /** * <pre> * This method retrieves all views (only in Composite Structure Diagrams) that are representing the role. * </pre> * * @param role * the {@link ConnectableElement} currently removed from role list * @param modifiedCollaboration * the {@link Collaboration} currently modified * @return the views that should be deleted */ private Set<View> getViewsForRole(ConnectableElement role, Collaboration modifiedCollaboration) { Set<View> viewsToDelete = new HashSet<View>(); // Get all view for the role in Composite Structure Diagrams Set<View> collaborationToEditViews = CrossReferencerUtil.getCrossReferencingViews(modifiedCollaboration, CompositeStructureDiagramEditPart.MODEL_ID); // Parse views of the edited Collaboration for(View currentCollaborationView : collaborationToEditViews) { Iterator<EObject> it = currentCollaborationView.eAllContents(); while(it.hasNext()) { EObject currentChildObject = it.next(); if(currentChildObject instanceof View) { View currentChildView = (View)currentChildObject; if((COLLABORATION_ROLE_HINT.equals(currentChildView.getType())) && (currentChildView.getElement() == role)) { viewsToDelete.add(currentChildView); } } } } return viewsToDelete; } }