/***************************************************************************** * 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: * Saadia Dhouib saadia.dhouib@cea.fr * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.communication.custom.edit.policies; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EObject; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.common.editpolicies.OrphanViewPolicy; import org.eclipse.papyrus.uml.diagram.communication.edit.parts.MessageEditPart; import org.eclipse.papyrus.uml.diagram.communication.part.UMLVisualIDRegistry; // TODO: Auto-generated Javadoc /** * The Class CustomOrphanViewPolicy is intended to ignore the communication diagram message connectors when searching for orphan views */ public class CustomOrphanViewPolicy extends OrphanViewPolicy { /** * @see org.eclipse.papyrus.uml.diagram.common.editpolicies.OrphanViewPolicy#notifyChanged(org.eclipse.emf.common.notify.Notification) * * @param notification */ public void notifyChanged(Notification notification) { // something has change. What ? :) // check who is responsible of notification. If this is host edit part related semantic element, act as standard Object notifier = notification.getNotifier(); // View hostView = (View)getHost().getModel(); if(notifier.equals(hostSemanticElement)) { if(Notification.REMOVE == notification.getEventType() || Notification.SET == notification.getEventType()) { refreshViews(); } } else { // this is perhaps one of the scoped semantic parent if(notifier instanceof EObject) { if(!(notifier instanceof View)) { if(Notification.REMOVE == notification.getEventType()) { // 2 cases... remove or simple move ? // this can be checked with the view, if it is now orphaned or not // if it is orphaned, element has to be destroyed, remove from parent listener, etc. // if not, this was just a move => change listener using new parent // checks also for whole hierarchy... EObject parentNotifier = (EObject)notifier; if(additionalParentToListen.containsKey(parentNotifier)) { // this should be one of the elements that are inside the List<View> views = additionalParentToListen.get(parentNotifier); List<View> orphaned = findOrphanView(views.iterator()); // // delete all the remaining views deleteViews(orphaned.iterator()); removeListeners(orphaned); } } } else { // Notifier is a View // REMOVE or ADD are interesting events: // if remove, remove the list (perhaps) from the views contributing to the delete action // if add, checks it does not need to be watched if(Notification.REMOVE == notification.getEventType()) { if(notification.getNewValue() instanceof View) { View oldView = (View)notification.getOldValue(); removeListenerForView(oldView); } } else if(Notification.ADD == notification.getEventType()) { // check the parent of the associated semantic element if(notification.getNewValue() instanceof View) { View newView = (View)notification.getNewValue(); addListenerForView(newView); } } } } } } /** * Retrieve the list of orphaned views among the specified list view. * Ignore the message connector views * * @param viewChildrenIterator * the iterator on the list of views to check * @return the list of views that are orphaned */ protected List<View> findOrphanView(Iterator<? extends EObject> viewChildrenIterator) { ArrayList<View> orphanView = new ArrayList<View>(); while(viewChildrenIterator.hasNext()) { EObject view = viewChildrenIterator.next(); if(view instanceof View) { //Verify if the view is a message connector, in this case it should not be considered as an orphan view, //because the message connector has no semantic element associated to it if(((View)view).getType().equals(UMLVisualIDRegistry.getType(MessageEditPart.VISUAL_ID))) { //if(!((View)view).getChildren().isEmpty()) continue; } if(isOrphaned((View)view)) { orphanView.add((View)view); } } } return orphanView; } }