/***************************************************************************** * Copyright (c) 2011 Atos Origin. * * * 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: * Atos Origin - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.groups.groupcontainment; import java.util.ArrayList; import java.util.List; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EReference; import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.notation.View; /** * This abstract class describes the required methods to register to the org.eclipse.papyrus.uml.diagram.common.groups.groupcontainment extension point. * These methods allow to recover necessary information on the container node for a given type. * * @author adaussy */ public abstract class AbstractContainerNodeDescriptor { /** * Get the eclass of the model eobject represented by the node * * @return model object eclass */ public abstract EClass getContainerEClass(); public List<EClass> getPossibleGraphicalChildren() { List<EReference> refs = this.getChildrenReferences(); List<EClass> result = new ArrayList<EClass>(refs.size()); for(EReference ref : refs) { result.add(ref.getEReferenceType()); } return result; } /** * Get the area in which contained children are located. * * @param containerPart * the part containing children, and representing an element of the getContainerEClass() eclass * @return the rectangle in which nodes are considered as children of this part (absolute coordinates) */ public Rectangle getContentArea(IGraphicalEditPart containerPart) { Rectangle bounds = containerPart.getContentPane().getBounds().getCopy(); containerPart.getContentPane().translateToAbsolute(bounds); return bounds; } /** * Get the list of references linking the container to children element. * Note that these may not be direct containment relations in case the element is only a graphical container. * * @return the references to contained elements */ public abstract List<EReference> getChildrenReferences(); /** * Get the edit part which is registered to the group framework (compartment) from a view of the corresponding node. * * @param nodeView * a view of the node, which can be either the compartment's view or the primary view of the containing node * @param diagramPart * the diagram edit part (used to recover parts from views) * @return the compartment edit part which is registered to the group framework */ public abstract IGraphicalEditPart getPartFromView(View nodeView, DiagramEditPart diagramPart); /** * Give you the right be a graphical parent of child. * * @param childType * EClass of the child you want to test * @return */ public boolean canIBeGraphicalParentOf(EClass childType) { for(EReference reference : this.getChildrenReferences()) { if(reference.getEReferenceType().isSuperTypeOf(childType)) { return true; } } return false; } /** * Give you the right to be a model parent of child * * @param childType * EClass of the child you want to test * @return */ public boolean canIBeModelParentOf(EClass childType) { for(EReference reference : this.getChildrenReferences()) { if(reference.getEReferenceType().isSuperTypeOf(childType) && reference.isContainment()) { return true; } } return false; } /** * Give the reference object which can reference the child. * * @param childType * EClass of the child you want to test * @return null if no reference is found */ public List<EReference> getReferenceFor(EClass childType) { List<EReference> result = new ArrayList<EReference>(); for(EReference reference : this.getChildrenReferences()) { if(reference.getEReferenceType().isSuperTypeOf(childType) && !reference.isContainment()) { result.add(reference); } } return result; } /** * Give the reference object which can contain the child. * * @param childType * EClass of the child you want to test * @return null if no reference is found */ public EReference getContainmentReferenceFor(EClass childType) { EReference usedReference = null; List<EReference> result = new ArrayList<EReference>(); for(EReference reference : this.getChildrenReferences()) { if(reference.getEReferenceType().isSuperTypeOf(childType) && reference.isContainment() && !reference.isDerived()) { result.add(reference); } } //Select the best containment relation for(EReference ref : result) { if(usedReference == null || ref.getEReferenceType().getEAllSuperTypes().contains(usedReference.getEReferenceType())) { // the ref feature is more precise than the previously selected one. Use it instead. usedReference = ref; } } return usedReference; } }