diff options
13 files changed, 790 insertions, 297 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/edit/part/AbstractAssociationEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/edit/part/AbstractAssociationEditPart.java index 3afd8ccccbf..e0426d38aa3 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/edit/part/AbstractAssociationEditPart.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/edit/part/AbstractAssociationEditPart.java @@ -10,6 +10,8 @@ * Contributors: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation * Benoit Maggi (CEA LIST) - Bug 468026 + * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 493430 + * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.clazz.custom.edit.part; @@ -19,9 +21,9 @@ import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.common.editparts.UMLConnectionNodeEditPart; import org.eclipse.papyrus.uml.diagram.common.figure.edge.AssociationFigure; +import org.eclipse.papyrus.uml.diagram.common.util.AssociationUtil; import org.eclipse.uml2.uml.AggregationKind; import org.eclipse.uml2.uml.Association; -import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.Property; import org.eclipse.uml2.uml.Type; @@ -56,8 +58,8 @@ public abstract class AbstractAssociationEditPart extends UMLConnectionNodeEditP if (semanticElement instanceof Association) { Association association = (Association) semanticElement; if (association.getMemberEnds().size() >= 2) { - EObject sourceEnd = association.getMemberEnds().get(0); - EObject targetEnd = association.getMemberEnds().get(1); + EObject sourceEnd = getSourceProperty(association); + EObject targetEnd = getTargetProperty(association); addListenerFilter(ASSOCIATION_END_LISTENERS_SOURCE, this, sourceEnd); addListenerFilter(ASSOCIATION_END_LISTENERS_TARGET, this, targetEnd); } @@ -106,23 +108,30 @@ public abstract class AbstractAssociationEditPart extends UMLConnectionNodeEditP if (((GraphicalEditPart) getSource()).resolveSemanticElement() == null || ((GraphicalEditPart) getTarget()).resolveSemanticElement() == null) { return; } - Property source = null; - Property target = null; - // Get the association - Element umlElement = getUMLElement(); - if (umlElement instanceof Association) { + + if (getUMLElement() instanceof Association) { Association association = (Association) getUMLElement(); - assert (association.getMemberEnds().size() >= 2); - if (association.getMemberEnds() != null && association.getMemberEnds().size() >= 2) { - Property firstProperty = association.getMemberEnds().get(0); - Type firstPropertyType = firstProperty.getType(); - if (firstPropertyType!= null && firstPropertyType.equals(((GraphicalEditPart) getSource()).resolveSemanticElement())) { - source = (firstProperty); - target = ((association.getMemberEnds().get(1))); - } else { - source = ((association.getMemberEnds().get(1))); - target = (firstProperty); + if (null != association.getMemberEnds() && 2 <= association.getMemberEnds().size()) { + Property source = getSourceProperty(association); + Property target = getTargetProperty(association); + + if (null == source || null == target) { + return; + } + + if (!source.getType().equals(target.getType())) { + Property propertyGet0 = association.getMemberEnds().get(0); + Property propertyGet1 = association.getMemberEnds().get(1); + Type propertyTypeGet0 = propertyGet0.getType(); + if (null != propertyTypeGet0 && propertyTypeGet0.equals(((GraphicalEditPart) getSource()).resolveSemanticElement())) { + source = propertyGet0; + target = propertyGet1; + } else { + source = propertyGet1; + target = propertyGet0; + } } + int sourceType = 0; int targetType = 0; // to display the dot. @@ -166,6 +175,28 @@ public abstract class AbstractAssociationEditPart extends UMLConnectionNodeEditP } /** + * Get the source member end of the Association. + * + * @param association + * The Association. + * @return The source member end. + */ + protected Property getSourceProperty(final Association association) { + return AssociationUtil.getTargetSecondEnd(association); + } + + /** + * Get the target member end of the Association. + * + * @param association + * The Association. + * @return The target member end. + */ + protected Property getTargetProperty(final Association association) { + return AssociationUtil.getSourceFirstEnd(association); + } + + /** * this method is used to remove listener on ends */ protected void removeAssociationEndListeners() { diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/helper/AssociationClassHelper.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/helper/AssociationClassHelper.java index 3f3bfdb2686..3fecbe05580 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/helper/AssociationClassHelper.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/helper/AssociationClassHelper.java @@ -9,6 +9,7 @@ * * Contributors: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 493430 * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.clazz.custom.helper; @@ -41,10 +42,11 @@ import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter; import org.eclipse.gmf.runtime.emf.type.core.IHintedType; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.infra.gmfdiag.common.commands.SemanticAdapter; +import org.eclipse.papyrus.infra.gmfdiag.common.commands.SemanticElementAdapter; import org.eclipse.papyrus.uml.diagram.clazz.custom.command.AssociationClassViewCreateCommand; import org.eclipse.papyrus.uml.diagram.clazz.custom.command.CustomDeferredCreateConnectionViewCommand; import org.eclipse.papyrus.uml.diagram.clazz.providers.UMLElementTypes; -import org.eclipse.papyrus.infra.gmfdiag.common.adapter.SemanticAdapter; import org.eclipse.papyrus.uml.diagram.common.helper.ElementHelper; import org.eclipse.uml2.uml.AssociationClass; import org.eclipse.uml2.uml.Property; @@ -85,7 +87,7 @@ public class AssociationClassHelper extends ElementHelper { public Command dropAssociationClass(AssociationClass associationClass, EditPartViewer viewer, PreferencesHint diagramPreferencesHint, Point location, View containerView) { CompositeCommand cc = new CompositeCommand("drop"); // 0. Obtain list of property to display - List<Property> endToDisplay = new ArrayList<Property>(associationClass.getMemberEnds()); + List<Property> endToDisplay = new ArrayList<>(associationClass.getMemberEnds()); GraphicalEditPart[] endEditPart = new GraphicalEditPart[associationClass.getMemberEnds().size()]; // 2. for each element create a graphical representation of the type and // finally the branch @@ -122,32 +124,35 @@ public class AssociationClassHelper extends ElementHelper { // 3. creation of the dashed line between the associationClass link // and associationClass Node // target + // The Target Type is contains on the first property. if (endEditPart[0] == null) { // creation of the node ViewDescriptor _descriptor = new ViewDescriptor(new EObjectAdapter(endToDisplay.get(0)), Node.class, null, ViewUtil.APPEND, true, diagramPreferencesHint); // get the command and execute it. CreateCommand endNodeCreationCommand = new CreateCommand(getEditingDomain(), _descriptor, containerView); cc.compose(endNodeCreationCommand); - setBoundsCommand = new SetBoundsCommand(getEditingDomain(), "move", (IAdaptable) endNodeCreationCommand.getCommandResult().getReturnValue(), new Point(location.x, location.y + 100)); + setBoundsCommand = new SetBoundsCommand(getEditingDomain(), "move", (IAdaptable) endNodeCreationCommand.getCommandResult().getReturnValue(), new Point(location.x, location.y - 100)); cc.compose(setBoundsCommand); - sourceAdapter = (IAdaptable) endNodeCreationCommand.getCommandResult().getReturnValue(); + targetAdapter = (IAdaptable) endNodeCreationCommand.getCommandResult().getReturnValue(); } else { - sourceAdapter = new SemanticAdapter(null, endEditPart[0].getModel()); + targetAdapter = new SemanticAdapter(null, endEditPart[0].getModel()); } + // The Source Type is contains on the second property. if (endEditPart[1] == null) { // creation of the node - ViewDescriptor _descriptor = new ViewDescriptor(new EObjectAdapter(endToDisplay.get(2)), Node.class, null, ViewUtil.APPEND, true, diagramPreferencesHint); + ViewDescriptor _descriptor = new ViewDescriptor(new EObjectAdapter(endToDisplay.get(1)), Node.class, null, ViewUtil.APPEND, true, diagramPreferencesHint); // get the command and execute it. CreateCommand endNodeCreationCommand = new CreateCommand(getEditingDomain(), _descriptor, containerView); cc.compose(endNodeCreationCommand); - setBoundsCommand = new SetBoundsCommand(getEditingDomain(), "move", (IAdaptable) endNodeCreationCommand.getCommandResult().getReturnValue(), new Point(location.x, location.y - 100)); + setBoundsCommand = new SetBoundsCommand(getEditingDomain(), "move", (IAdaptable) endNodeCreationCommand.getCommandResult().getReturnValue(), new Point(location.x, location.y + 100)); cc.compose(setBoundsCommand); - targetAdapter = (IAdaptable) endNodeCreationCommand.getCommandResult().getReturnValue(); + sourceAdapter = (IAdaptable) endNodeCreationCommand.getCommandResult().getReturnValue(); } else { - targetAdapter = new SemanticAdapter(null, endEditPart[1].getModel()); + sourceAdapter = new SemanticAdapter(null, endEditPart[1].getModel()); } // create association link - ConnectionViewDescriptor viewDescriptor = new ConnectionViewDescriptor(UMLElementTypes.AssociationClass_Edge, ((IHintedType) UMLElementTypes.AssociationClass_Edge).getSemanticHint(), diagramPreferencesHint); + SemanticElementAdapter adapter = new SemanticElementAdapter(associationClass, UMLElementTypes.AssociationClass_Edge); + ConnectionViewDescriptor viewDescriptor = new ConnectionViewDescriptor(adapter, ((IHintedType) UMLElementTypes.AssociationClass_Edge).getSemanticHint(), diagramPreferencesHint); // Creation of the associationLink CustomDeferredCreateConnectionViewCommand associationcClassLinkCommand = new CustomDeferredCreateConnectionViewCommand(getEditingDomain(), ((IHintedType) UMLElementTypes.AssociationClass_Edge).getSemanticHint(), sourceAdapter, targetAdapter, viewer, diagramPreferencesHint, viewDescriptor, null); diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/policies/ClassDiagramDragDropEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/policies/ClassDiagramDragDropEditPolicy.java index 6f34c0f2bb2..c90a0a70974 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/policies/ClassDiagramDragDropEditPolicy.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz/custom-src/org/eclipse/papyrus/uml/diagram/clazz/custom/policies/ClassDiagramDragDropEditPolicy.java @@ -70,6 +70,7 @@ import org.eclipse.papyrus.uml.diagram.clazz.part.UMLVisualIDRegistry; import org.eclipse.papyrus.uml.diagram.clazz.providers.UMLElementTypes; import org.eclipse.papyrus.uml.diagram.common.editpolicies.CommonDiagramDragDropEditPolicy; import org.eclipse.papyrus.uml.diagram.common.strategy.paste.ShowConstraintContextLink; +import org.eclipse.papyrus.uml.diagram.common.util.AssociationUtil; import org.eclipse.uml2.uml.Association; import org.eclipse.uml2.uml.AssociationClass; import org.eclipse.uml2.uml.Constraint; @@ -77,7 +78,6 @@ import org.eclipse.uml2.uml.Dependency; import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.InstanceSpecification; import org.eclipse.uml2.uml.PackageableElement; -import org.eclipse.uml2.uml.Property; /** * The Class ClassDiagramDragDropEditPolicy. @@ -248,16 +248,9 @@ public class ClassDiagramDragDropEditPolicy extends CommonDiagramDragDropEditPol return new ICommandProxy(dropBinaryLink(new CompositeCommand("drop Association"), source, target, AssociationEditPart.VISUAL_ID, dropRequest.getLocation(), semanticLink)); //$NON-NLS-1$ } if (endtypes.size() == 2) { - Element source = null; - Element target = null; - final List<Property> memberEnds = ((Association) semanticLink).getMemberEnds(); - if (memberEnds.get(0).equals(endtypes.get(0))) { - source = (Element) endtypes.get(0); - target = (Element) endtypes.get(1); - } else { - source = (Element) endtypes.get(1); - target = (Element) endtypes.get(0); - } + // Source link is based on the target property and the target link is based on the source property + Element source = AssociationUtil.getTargetSecondEnd((Association) semanticLink).getType(); + Element target = AssociationUtil.getSourceFirstEnd((Association) semanticLink).getType(); return new ICommandProxy(dropBinaryLink(new CompositeCommand("drop Association"), source, target, AssociationEditPart.VISUAL_ID, dropRequest.getLocation(), semanticLink)); //$NON-NLS-1$ } if (endtypes.size() > 2) { diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommonDiagramDragDropEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommonDiagramDragDropEditPolicy.java index 185207d770e..79d6457f8b2 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommonDiagramDragDropEditPolicy.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommonDiagramDragDropEditPolicy.java @@ -12,9 +12,10 @@ * Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - refactor common behavior between diagrams * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - add the line ViewServiceUtil.forceLoad(); * Christian W. Damus (CEA) - bug 430726 - * Benoit Maggi (CEA LIST) benoit.maggi@cea.fr - bug 450341 + * Benoit Maggi (CEA LIST) benoit.maggi@cea.fr - bug 450341 * Christian W. Damus - bug 450944 * Christian W. Damus - bug 477384 + * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 493430 *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.editpolicies; @@ -70,6 +71,7 @@ import org.eclipse.papyrus.commands.wrappers.CommandProxyWithResult; import org.eclipse.papyrus.infra.gmfdiag.common.adapter.SemanticAdapter; import org.eclipse.papyrus.infra.gmfdiag.common.commands.CommonDeferredCreateConnectionViewCommand; import org.eclipse.papyrus.infra.gmfdiag.common.commands.CreateViewCommand; +import org.eclipse.papyrus.infra.gmfdiag.common.commands.SemanticElementAdapter; import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AbstractDiagramDragDropEditPolicy; import org.eclipse.papyrus.infra.gmfdiag.common.service.visualtype.VisualTypeService; import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil; @@ -140,7 +142,7 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra /** * Gets the notational diagram in which my host edit part is rendering a view. - * + * * @return the contextual diagram */ protected Diagram getContextDiagram() { @@ -194,7 +196,9 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra IAdaptable sourceAdapter = findAdapter(cc, source, getLinkSourceDropLocation(absoluteLocation, source, target)); IAdaptable targetAdapter = findAdapter(cc, target, getLinkTargetDropLocation(absoluteLocation, source, target)); // descriptor of the link - CreateConnectionViewRequest.ConnectionViewDescriptor linkdescriptor = new CreateConnectionViewRequest.ConnectionViewDescriptor(getUMLElementType(linkVISUALID), ((IHintedType) getUMLElementType(linkVISUALID)).getSemanticHint(), + + SemanticElementAdapter adapter = new SemanticElementAdapter(semanticLink, getUMLElementType(linkVISUALID)); + CreateConnectionViewRequest.ConnectionViewDescriptor linkdescriptor = new CreateConnectionViewRequest.ConnectionViewDescriptor(adapter, ((IHintedType) getUMLElementType(linkVISUALID)).getSemanticHint(), getDiagramPreferencesHint()); CommonDeferredCreateConnectionViewCommand aLinkCommand = new CommonDeferredCreateConnectionViewCommand(getEditingDomain(), ((IHintedType) getUMLElementType(linkVISUALID)).getSemanticHint(), sourceAdapter, targetAdapter, getViewer(), @@ -258,17 +262,17 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra /* * when it's the first action after the opening of Papyrus, the * viewService is not loaded! see bug 302555 - * + * * Duration test for 100000 creations of DropCommand : Here 2 solutions * : - call ViewServiceUtil.forceLoad(); for each drop -> ~2500ms - * + * * - test if the command cc can be executed at the end of the method, * and if not : - call ViewServiceUtil.forceLoad(); - and return * getDropObjectsCommand(getDropObjectsCommand) -> ~4700ms - * + * * - for information : without call ViewServiceUtil.forceLoad(); -> * ~1600ms - * + * * It's better don't test if the command is executable! */ ViewServiceUtil.forceLoad(); @@ -714,7 +718,7 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra /** * Returns The command to drop the {@link Constraint} and the links, if the * constraints elements are on the diagram - * + * * @param comment * the comment to drop * @param viewer @@ -738,7 +742,7 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra int nbAnnotated = constraint.getConstrainedElements().size(); // 0. Obtain list of the annotatedElement - ArrayList<Element> endToConnect = new ArrayList<Element>(constraint.getConstrainedElements()); + ArrayList<Element> endToConnect = new ArrayList<>(constraint.getConstrainedElements()); GraphicalEditPart[] endEditPart = new GraphicalEditPart[nbAnnotated]; // 1. Look for if each annotated element is on the diagram @@ -791,7 +795,7 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra /** * Returns The command to drop the {@link Comment} and the links, if the * attached elements are on the diagram - * + * * @param comment * the comment to drop * @param viewer @@ -816,7 +820,7 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra int nbAnnotated = comment.getAnnotatedElements().size(); // 0. Obtain list of the annotatedElement - ArrayList<Element> endToConnect = new ArrayList<Element>(comment.getAnnotatedElements()); + ArrayList<Element> endToConnect = new ArrayList<>(comment.getAnnotatedElements()); GraphicalEditPart[] endEditPart = new GraphicalEditPart[nbAnnotated]; // 1. Look for if each annotated element is on the diagram @@ -879,7 +883,7 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra * - a Class that owns or inherits the Port * - a Property which type owns or inherits the Port * </pre> - * + * * @param dropRequest * the drop request * @param droppedElement @@ -967,10 +971,10 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra /** * <pre> - * This method returns the drop command for AffixedNode (Port, Parameter) + * This method returns the drop command for AffixedNode (Port, Parameter) * in case the node is dropped on a ShapeCompartmentEditPart. * </pre> - * + * * @param nodeVISUALID * the node visual identifier * @param location @@ -1006,7 +1010,7 @@ public abstract class CommonDiagramDragDropEditPolicy extends AbstractDiagramDra * Find source/target adapter * If the source and the target views do not exist, these views will be * created. - * + * * @see dropBinaryLink(CompositeCommand cc, Element source, Element target, int linkVISUALID * , Point absoluteLocation, Element semanticLink) * diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/AssociationEndSourceLabelHelper.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/AssociationEndSourceLabelHelper.java index dd3045d0d61..d3cc009fe43 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/AssociationEndSourceLabelHelper.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/AssociationEndSourceLabelHelper.java @@ -10,6 +10,8 @@ * Contributors: * Patrick Tessier (CEA LIST) - Initial API and implementation * Benoit Maggi (CEA LIST) - Bug 468026 + * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 493430 + * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.helper; @@ -20,6 +22,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.uml.diagram.common.util.AssociationUtil; import org.eclipse.uml2.uml.Association; import org.eclipse.uml2.uml.Property; @@ -49,8 +52,17 @@ public class AssociationEndSourceLabelHelper extends AssociationEndPropertyLabel if (sourceContainer == null) { return null; } - + Property propertyToDisplay = null; + + if (model != null && (model.getElement() instanceof Association)) { + propertyToDisplay = AssociationUtil.getTargetSecondEnd((Association) model.getElement()); + } + + if (null != propertyToDisplay) { + return propertyToDisplay; + } + if (model != null && (model.getElement() instanceof Association)) { // look for the property that is typed by the classifier Iterator<Property> propertiesIterator = ((Association) model.getElement()).getMemberEnds().iterator(); @@ -68,7 +80,7 @@ public class AssociationEndSourceLabelHelper extends AssociationEndPropertyLabel } // /in the case of reorient the property must be not found, // so we have to find the property that is different from the source. - + if (model != null && (model.getElement() instanceof Association)) { // look for the property that is typed by the classifier Iterator<Property> propertiesIterator = ((Association) model.getElement()).getMemberEnds().iterator(); diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/AssociationEndTargetLabelHelper.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/AssociationEndTargetLabelHelper.java index 7b5452f6848..6816c7b301c 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/AssociationEndTargetLabelHelper.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/helper/AssociationEndTargetLabelHelper.java @@ -10,6 +10,8 @@ * Contributors: * Patrick Tessier (CEA LIST) - Initial API and implementation * Benoit Maggi (CEA LIST) - Bug 468026 + * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 493430 + * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.helper; @@ -20,6 +22,7 @@ import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.uml.diagram.common.util.AssociationUtil; import org.eclipse.uml2.uml.Association; import org.eclipse.uml2.uml.Property; @@ -53,8 +56,17 @@ public class AssociationEndTargetLabelHelper extends AssociationEndPropertyLabel if (targetContainer == null) { return null; } - + Property propertyToDisplay = null; + + if (model != null && (model.getElement() instanceof Association)) { + propertyToDisplay = AssociationUtil.getSourceFirstEnd((Association) model.getElement()); + } + + if (null != propertyToDisplay) { + return propertyToDisplay; + } + if (model != null && (model.getElement() instanceof Association)) { // look for the property that is typed by the classifier Iterator<Property> propertiesIterator = ((Association) model.getElement()).getMemberEnds().iterator(); @@ -72,7 +84,7 @@ public class AssociationEndTargetLabelHelper extends AssociationEndPropertyLabel } // in the case of reorient the property must be not found, // so we have to find the property that is different from the source. - + if (model != null && (model.getElement() instanceof Association)) { // look for the property that is typed by the classifier Iterator<Property> propertiesIterator = ((Association) model.getElement()).getMemberEnds().iterator(); diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/AssociationUtil.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/AssociationUtil.java index 887ee1f6223..86396536b1c 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/AssociationUtil.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/AssociationUtil.java @@ -12,7 +12,10 @@ *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.common.util; +import java.util.List; + import org.eclipse.uml2.uml.AggregationKind; +import org.eclipse.uml2.uml.Association; import org.eclipse.uml2.uml.Property; /** @@ -81,4 +84,32 @@ public class AssociationUtil { return identicalNavigable; } + + /** + * + * @param association + * @return + */ + public static Property getSourceFirstEnd(final Association association) { + Property source = null; + List<Property> memberEnds = association.getMemberEnds(); + if (!memberEnds.isEmpty()) { + source = memberEnds.get(0); + } + return source; + } + + /** + * + * @param association + * @return + */ + public static Property getTargetSecondEnd(final Association association) { + Property target = null; + List<Property> memberEnds = association.getMemberEnds(); + if (2 <= memberEnds.size()) { + target = memberEnds.get(1); + } + return target; + } } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.profile/custom-src/org/eclipse/papyrus/uml/diagram/profile/custom/edit/parts/AbstractAssociationEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.profile/custom-src/org/eclipse/papyrus/uml/diagram/profile/custom/edit/parts/AbstractAssociationEditPart.java index f6a57c66e48..89120be3c74 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.profile/custom-src/org/eclipse/papyrus/uml/diagram/profile/custom/edit/parts/AbstractAssociationEditPart.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.profile/custom-src/org/eclipse/papyrus/uml/diagram/profile/custom/edit/parts/AbstractAssociationEditPart.java @@ -1,186 +1,219 @@ -/*****************************************************************************
- * Copyright (c) 2009 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
- * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Adapted code from Class Diagram
- *****************************************************************************/
-package org.eclipse.papyrus.uml.diagram.profile.custom.edit.parts;
-
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.uml.diagram.common.editparts.UMLConnectionNodeEditPart;
-import org.eclipse.papyrus.uml.diagram.profile.custom.figure.AssociationFigure;
-import org.eclipse.uml2.uml.AggregationKind;
-import org.eclipse.uml2.uml.Association;
-import org.eclipse.uml2.uml.Element;
-import org.eclipse.uml2.uml.Property;
-
-/**
- * this a abstract editpart use to add listeners
- */
-public abstract class AbstractAssociationEditPart extends UMLConnectionNodeEditPart {
-
- /** Filter ID for the end source listener */
- protected static final String ASSOCIATION_END_LISTENERS_SOURCE = "AssociationEndListenersSource"; //$NON-NLS-1$
-
- /** Filter ID for the end target listener */
- protected static final String ASSOCIATION_END_LISTENERS_TARGET = "AssociationEndListenersTarget"; //$NON-NLS-1$
-
- /**
- *
- * Constructor.
- *
- * @param view
- * the view
- */
- public AbstractAssociationEditPart(View view) {
- super(view);
- }
-
- /**
- *
- * {@inheritDoc}
- */
- @Override
- public void activate() {
- super.activate();
- addAssociationEndListeners();
- }
-
- /**
- * this methods add listeners on targets and sources
- */
- protected void addAssociationEndListeners() {
- EObject semanticElement = resolveSemanticElement();
- if (semanticElement instanceof Association) {
- Association association = (Association) semanticElement;
- if (association.getMemberEnds().size() >= 2) {
- EObject sourceEnd = association.getMemberEnds().get(0);
- EObject targetEnd = association.getMemberEnds().get(1);
-
- addListenerFilter(ASSOCIATION_END_LISTENERS_SOURCE, this, sourceEnd);
- addListenerFilter(ASSOCIATION_END_LISTENERS_TARGET, this, targetEnd);
- }
- }
- }
-
- /**
- *
- * {@inheritDoc}
- */
-
- @Override
- public void deactivate() {
- removeAssociationEndListeners();
- super.deactivate();
- }
-
- /**
- *
- * {@inheritDoc}
- */
-
- @Override
- protected void handleNotificationEvent(Notification event) {
- super.handleNotificationEvent(event);
-
- // set the good ends for the association figure
- if (resolveSemanticElement() != null) {
-
- refreshVisuals();
- }
- }
-
- /**
- *
- * {@inheritDoc}
- */
- @Override
- protected void refreshVisuals() {
- if (resolveSemanticElement() != null) {
- if (getSource() == null || getTarget() == null) {
- return;
- }
- if (((GraphicalEditPart) getSource()).resolveSemanticElement() == null || ((GraphicalEditPart) getTarget()).resolveSemanticElement() == null) {
- return;
- }
-
- Property source = null;
- Property target = null;
-
- // Get the association
- Element umlElement = getUMLElement();
- if (umlElement instanceof Association) {
- Association association = (Association) getUMLElement();
- assert (association.getMemberEnds().size() >= 2);
- if (association.getMemberEnds() != null && association.getMemberEnds().size() >= 2) {
- if (((association.getMemberEnds().get(0))).getType().equals(((GraphicalEditPart) getSource()).resolveSemanticElement())) {
- source = ((association.getMemberEnds().get(0)));
- target = ((association.getMemberEnds().get(1)));
- } else {
- source = ((association.getMemberEnds().get(1)));
- target = ((association.getMemberEnds().get(0)));
- }
- int sourceType = 0;
- int targetType = 0;
- // to display the dot.
- // owned?
- if (!source.getOwner().equals(resolveSemanticElement())) {
- sourceType += AssociationFigure.owned;
- sourceType += AssociationFigure.navigable;
- }
- if (!target.getOwner().equals(resolveSemanticElement())) {
- targetType += AssociationFigure.owned;
- targetType += AssociationFigure.navigable;
- }
- // aggregation? for it the opposite is changed
- if (source.getAggregation() == AggregationKind.SHARED_LITERAL) {
- targetType += AssociationFigure.aggregation;
- }
- if (target.getAggregation() == AggregationKind.SHARED_LITERAL) {
- sourceType += AssociationFigure.aggregation;
- }
- // composite? for it the opposite is changed
- if (source.getAggregation() == AggregationKind.COMPOSITE_LITERAL) {
- targetType += AssociationFigure.composition;
- }
- if (target.getAggregation() == AggregationKind.COMPOSITE_LITERAL) {
- sourceType += AssociationFigure.composition;
- }
-
- // navigable?
- if (association.getNavigableOwnedEnds().contains(source)) {
- sourceType += AssociationFigure.navigable;
- }
- if (association.getNavigableOwnedEnds().contains(target)) {
- targetType += AssociationFigure.navigable;
- }
- if (getPrimaryShape() instanceof AssociationFigure) {
- ((AssociationFigure) getPrimaryShape()).setEnd(sourceType, targetType);
- }
- }
-
- }
-
- }
- super.refreshVisuals();
- }
-
- /**
- * this method is used to remove listener on ends
- */
- protected void removeAssociationEndListeners() {
- removeListenerFilter(ASSOCIATION_END_LISTENERS_SOURCE);
- removeListenerFilter(ASSOCIATION_END_LISTENERS_TARGET);
-
- }
-}
+/***************************************************************************** + * Copyright (c) 2009 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 + * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Adapted code from Class Diagram + * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 493430 + * + *****************************************************************************/ +package org.eclipse.papyrus.uml.diagram.profile.custom.edit.parts; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.uml.diagram.common.editparts.UMLConnectionNodeEditPart; +import org.eclipse.papyrus.uml.diagram.common.util.AssociationUtil; +import org.eclipse.papyrus.uml.diagram.profile.custom.figure.AssociationFigure; +import org.eclipse.uml2.uml.AggregationKind; +import org.eclipse.uml2.uml.Association; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.Type; + +/** + * this a abstract editpart use to add listeners + */ +public abstract class AbstractAssociationEditPart extends UMLConnectionNodeEditPart { + + /** Filter ID for the end source listener */ + protected static final String ASSOCIATION_END_LISTENERS_SOURCE = "AssociationEndListenersSource"; //$NON-NLS-1$ + + /** Filter ID for the end target listener */ + protected static final String ASSOCIATION_END_LISTENERS_TARGET = "AssociationEndListenersTarget"; //$NON-NLS-1$ + + /** + * + * Constructor. + * + * @param view + * the view + */ + public AbstractAssociationEditPart(View view) { + super(view); + } + + /** + * + * {@inheritDoc} + */ + @Override + public void activate() { + super.activate(); + addAssociationEndListeners(); + } + + /** + * this methods add listeners on targets and sources + */ + protected void addAssociationEndListeners() { + EObject semanticElement = resolveSemanticElement(); + if (semanticElement instanceof Association) { + Association association = (Association) semanticElement; + if (association.getMemberEnds().size() >= 2) { + EObject sourceEnd = getSourceProperty(association); + EObject targetEnd = getTargetProperty(association); + + addListenerFilter(ASSOCIATION_END_LISTENERS_SOURCE, this, sourceEnd); + addListenerFilter(ASSOCIATION_END_LISTENERS_TARGET, this, targetEnd); + } + } + } + + /** + * + * {@inheritDoc} + */ + + @Override + public void deactivate() { + removeAssociationEndListeners(); + super.deactivate(); + } + + /** + * + * {@inheritDoc} + */ + + @Override + protected void handleNotificationEvent(Notification event) { + super.handleNotificationEvent(event); + + // set the good ends for the association figure + if (resolveSemanticElement() != null) { + refreshVisuals(); + } + } + + /** + * + * {@inheritDoc} + */ + @Override + protected void refreshVisuals() { + if (resolveSemanticElement() != null) { + if (getSource() == null || getTarget() == null) { + return; + } + if (((GraphicalEditPart) getSource()).resolveSemanticElement() == null || ((GraphicalEditPart) getTarget()).resolveSemanticElement() == null) { + return; + } + + + // Get the association + if (getUMLElement() instanceof Association) { + Association association = (Association) getUMLElement(); + if (null != association.getMemberEnds() && 2 <= association.getMemberEnds().size()) { + Property source = getSourceProperty(association); + Property target = getTargetProperty(association); + + if (null == source || null == target) { + return; + } + + // If + if (!source.getType().equals(target.getType())) { + Property propertyGet0 = association.getMemberEnds().get(0); + Property propertyGet1 = association.getMemberEnds().get(1); + Type propertyTypeGet0 = propertyGet0.getType(); + if (null != propertyTypeGet0 && propertyTypeGet0.equals(((GraphicalEditPart) getSource()).resolveSemanticElement())) { + source = propertyGet0; + target = propertyGet1; + } else { + source = propertyGet1; + target = propertyGet0; + } + } + + int sourceType = 0; + int targetType = 0; + // to display the dot. + // owned? + if (!source.getOwner().equals(resolveSemanticElement())) { + sourceType += AssociationFigure.owned; + sourceType += AssociationFigure.navigable; + } + if (!target.getOwner().equals(resolveSemanticElement())) { + targetType += AssociationFigure.owned; + targetType += AssociationFigure.navigable; + } + // aggregation? for it the opposite is changed + if (source.getAggregation() == AggregationKind.SHARED_LITERAL) { + targetType += AssociationFigure.aggregation; + } + if (target.getAggregation() == AggregationKind.SHARED_LITERAL) { + sourceType += AssociationFigure.aggregation; + } + // composite? for it the opposite is changed + if (source.getAggregation() == AggregationKind.COMPOSITE_LITERAL) { + targetType += AssociationFigure.composition; + } + if (target.getAggregation() == AggregationKind.COMPOSITE_LITERAL) { + sourceType += AssociationFigure.composition; + } + // navigable? + if (association.getNavigableOwnedEnds().contains(source)) { + sourceType += AssociationFigure.navigable; + } + if (association.getNavigableOwnedEnds().contains(target)) { + targetType += AssociationFigure.navigable; + } + if (getPrimaryShape() instanceof AssociationFigure) { + ((AssociationFigure) getPrimaryShape()).setEnd(sourceType, targetType); + } + } + + } + + } + super.refreshVisuals(); + } + + /** + * Get the source member end of the Association. + * + * @param association + * The Association. + * @return The source member end. + */ + protected Property getSourceProperty(final Association association) { + return AssociationUtil.getSourceFirstEnd(association); + } + + /** + * Get the target member end of the Association. + * + * @param association + * The Association. + * @return The target member end. + */ + protected Property getTargetProperty(final Association association) { + return AssociationUtil.getTargetSecondEnd(association); + } + + /** + * this method is used to remove listener on ends + */ + protected void removeAssociationEndListeners() { + removeListenerFilter(ASSOCIATION_END_LISTENERS_SOURCE); + removeListenerFilter(ASSOCIATION_END_LISTENERS_TARGET); + + } +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.profile/custom-src/org/eclipse/papyrus/uml/diagram/profile/custom/policies/ProfileDiagramDragDropEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.profile/custom-src/org/eclipse/papyrus/uml/diagram/profile/custom/policies/ProfileDiagramDragDropEditPolicy.java index 2380cc47d07..e996ccd20ad 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.profile/custom-src/org/eclipse/papyrus/uml/diagram/profile/custom/policies/ProfileDiagramDragDropEditPolicy.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.profile/custom-src/org/eclipse/papyrus/uml/diagram/profile/custom/policies/ProfileDiagramDragDropEditPolicy.java @@ -12,7 +12,7 @@ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Adapted code from the class diagram * Christian W. Damus - bug 433206 * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 492893 - * + * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.profile.custom.policies; @@ -58,6 +58,7 @@ import org.eclipse.papyrus.infra.gmfdiag.common.commands.CommonDeferredCreateCon import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil; import org.eclipse.papyrus.uml.diagram.common.editpolicies.CommonDiagramDragDropEditPolicy; import org.eclipse.papyrus.uml.diagram.common.strategy.paste.ShowConstraintContextLink; +import org.eclipse.papyrus.uml.diagram.common.util.AssociationUtil; import org.eclipse.papyrus.uml.diagram.common.util.Util; import org.eclipse.papyrus.uml.diagram.profile.custom.commands.SetStereotypeVisibleOnMetaclassCommand; import org.eclipse.papyrus.uml.diagram.profile.custom.helper.MultiAssociationHelper; @@ -84,7 +85,6 @@ import org.eclipse.uml2.uml.Constraint; import org.eclipse.uml2.uml.Dependency; import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.ElementImport; -import org.eclipse.uml2.uml.Property; import org.eclipse.uml2.uml.Type; /** @@ -158,16 +158,9 @@ public class ProfileDiagramDragDropEditPolicy extends CommonDiagramDragDropEditP protected Command dropAssociation(final DropObjectsRequest dropRequest, final Element semanticLink, final String nodeVISUALID) { final List<?> endtypes = new ArrayList<>(ProfileLinkMappingHelper.getInstance().getSource(semanticLink)); if (endtypes.size() == 2) { - Element source = null; - Element target = null; - final List<Property> memberEnds = ((Association) semanticLink).getMemberEnds(); - if (memberEnds.get(0).equals(endtypes.get(0))) { - source = (Element) endtypes.get(0); - target = (Element) endtypes.get(1); - } else { - source = (Element) endtypes.get(1); - target = (Element) endtypes.get(0); - } + // Source link is based on the target property and the target link is based on the source property + Element source = AssociationUtil.getTargetSecondEnd((Association) semanticLink).getType(); + Element target = AssociationUtil.getSourceFirstEnd((Association) semanticLink).getType(); return new ICommandProxy(dropBinaryLink(new CompositeCommand("Drop Association"), source, target, AssociationEditPart.VISUAL_ID, dropRequest.getLocation(), semanticLink)); //$NON-NLS-1$ } if (endtypes.size() > 2) { diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.usecase/custom-src/org/eclipse/papyrus/uml/diagram/usecase/edit/policies/CustomDiagramDragDropEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.usecase/custom-src/org/eclipse/papyrus/uml/diagram/usecase/edit/policies/CustomDiagramDragDropEditPolicy.java index afe3c82b1ae..5e0b6b973a5 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.usecase/custom-src/org/eclipse/papyrus/uml/diagram/usecase/edit/policies/CustomDiagramDragDropEditPolicy.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.usecase/custom-src/org/eclipse/papyrus/uml/diagram/usecase/edit/policies/CustomDiagramDragDropEditPolicy.java @@ -29,13 +29,13 @@ import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest; import org.eclipse.gmf.runtime.emf.type.core.IElementType; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.common.editpolicies.CommonDiagramDragDropEditPolicy; +import org.eclipse.papyrus.uml.diagram.common.util.AssociationUtil; import org.eclipse.papyrus.uml.diagram.usecase.edit.parts.AssociationEditPart; import org.eclipse.papyrus.uml.diagram.usecase.helper.UseCaseLinkMappingHelper; import org.eclipse.papyrus.uml.diagram.usecase.part.UMLVisualIDRegistry; import org.eclipse.papyrus.uml.diagram.usecase.providers.UMLElementTypes; import org.eclipse.uml2.uml.Association; import org.eclipse.uml2.uml.Element; -import org.eclipse.uml2.uml.Property; /** * This class is used to execute the drag and drop from the outline. It can manage the drop of nodes @@ -120,16 +120,9 @@ public class CustomDiagramDragDropEditPolicy extends CommonDiagramDragDropEditPo Element target = (Element) endtypes.get(0); return new ICommandProxy(dropBinaryLink(new CompositeCommand("drop Association"), source, target, linkVISUALID, dropRequest.getLocation(), semanticLink)); //$NON-NLS-1$ } else if (endtypes.size() == 2) { - Element source = null; - Element target = null; - final List<Property> memberEnds = ((Association) semanticLink).getMemberEnds(); - if (memberEnds.get(0).equals(endtypes.get(0))) { - source = (Element) endtypes.get(0); - target = (Element) endtypes.get(1); - } else { - source = (Element) endtypes.get(1); - target = (Element) endtypes.get(0); - } + // Source link is based on the target property and the target link is based on the source property + Element source = AssociationUtil.getTargetSecondEnd((Association) semanticLink).getType(); + Element target = AssociationUtil.getSourceFirstEnd((Association) semanticLink).getType(); return new ICommandProxy(dropBinaryLink(new CompositeCommand("drop Association"), source, target, linkVISUALID, dropRequest.getLocation(), semanticLink)); //$NON-NLS-1$ } else { return UnexecutableCommand.INSTANCE; diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/AssociationEditHelperAdvice.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/AssociationEditHelperAdvice.java index 15ced9578be..5df8a4ad0f0 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/AssociationEditHelperAdvice.java +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/AssociationEditHelperAdvice.java @@ -7,8 +7,8 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * * CEA LIST - Initial API and implementation + * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Bug 493430 * *****************************************************************************/ package org.eclipse.papyrus.uml.service.types.helper.advice; @@ -35,6 +35,7 @@ import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyReferenceRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.ReorientRelationshipRequest; +import org.eclipse.gmf.runtime.emf.type.core.requests.ReorientRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest; import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils; import org.eclipse.papyrus.infra.services.edit.service.IElementEditService; @@ -42,7 +43,6 @@ import org.eclipse.papyrus.uml.service.types.Activator; import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes; import org.eclipse.papyrus.uml.service.types.utils.ClassifierUtils; import org.eclipse.papyrus.uml.service.types.utils.ElementUtil; -import org.eclipse.papyrus.uml.service.types.utils.RequestParameterConstants; import org.eclipse.uml2.uml.Association; import org.eclipse.uml2.uml.Classifier; import org.eclipse.uml2.uml.Property; @@ -57,7 +57,7 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * This method provides the source type provided as {@link ConfigureRequest} parameter. - * + * * @return the target role */ protected Classifier getSourceOwnerType(ConfigureRequest req) { @@ -72,7 +72,7 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * This method provides the target type provided as {@link ConfigureRequest} parameter. - * + * * @return the target role */ protected Classifier getTargetOwnerType(ConfigureRequest req) { @@ -87,7 +87,7 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * Creates a new source {@link Property} from the targetType. - * + * * @param targetType * the type of the {@link Property} * @return the new {@link Property} @@ -105,7 +105,7 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * Creates a new target {@link Property} from the sourceType. - * + * * @param sourceType * the type of the {@link Property} * @return the new {@link Property} @@ -124,7 +124,7 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * Add the source {@link Property} in the correct container. - * + * * @param sourceEnd * the semantic end * @param owner @@ -145,7 +145,7 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * Add the source {@link Property} in the correct container. - * + * * @param targetEnd * the semantic end * @param owner @@ -167,11 +167,11 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * <pre> * {@inheritDoc} - * + * * Complete the {@link Association} creation by: * adding its {@link Property} ends in the model * adding the UML Nature on the {@link Association}. - * + * * </pre> */ @Override @@ -221,17 +221,18 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * <pre> * {@inheritDoc} - * - * Add a command to destroy {@link Association} ends referenced by the {@link Association} + * + * Add a command to destroy {@link Association} ends referenced by the {@link Association} * to delete. - * + * * </pre> */ @Override protected ICommand getBeforeDestroyDependentsCommand(DestroyDependentsRequest req) { List<EObject> dependentsToDestroy = new ArrayList<EObject>(); - List<EObject> dependentsToKeep = (req.getParameter(RequestParameterConstants.DEPENDENTS_TO_KEEP) != null) ? (List<EObject>) req.getParameter(RequestParameterConstants.DEPENDENTS_TO_KEEP) : new ArrayList<EObject>(); + List<EObject> dependentsToKeep = (req.getParameter(org.eclipse.papyrus.infra.services.edit.utils.RequestParameterConstants.DEPENDENTS_TO_KEEP) != null) + ? (List<EObject>) req.getParameter(org.eclipse.papyrus.infra.services.edit.utils.RequestParameterConstants.DEPENDENTS_TO_KEEP) : new ArrayList<EObject>(); Association association = (Association) req.getElementToDestroy(); for (Property end : association.getMemberEnds()) { @@ -251,9 +252,9 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * <pre> * {@inheritDoc} - * + * * Add a command to destroy {@link Association} when only 1 end remains. - * + * * </pre> */ @Override @@ -284,9 +285,9 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * <pre> * {@inheritDoc} - * + * * Add a command to related association end during re-orient. - * + * * </pre> */ @Override @@ -304,7 +305,8 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { // 1 property change its types Property changeContainer = null; Property changeType = getMemberEnd(association, (Classifier) request.getOldRelationshipEnd()); - List<EObject> currentlyRefactoredElements = (request.getParameter(RequestParameterConstants.ASSOCIATION_REFACTORED_ELEMENTS) != null) ? (List<EObject>) request.getParameter(RequestParameterConstants.ASSOCIATION_REFACTORED_ELEMENTS) + List<EObject> currentlyRefactoredElements = (request.getParameter(org.eclipse.papyrus.infra.services.edit.utils.RequestParameterConstants.ASSOCIATION_REFACTORED_ELEMENTS) != null) + ? (List<EObject>) request.getParameter(org.eclipse.papyrus.infra.services.edit.utils.RequestParameterConstants.ASSOCIATION_REFACTORED_ELEMENTS) : new ArrayList<EObject>(); if (currentlyRefactoredElements.contains(association)) { @@ -313,17 +315,30 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { } else { currentlyRefactoredElements.add(association); - request.getParameters().put(RequestParameterConstants.ASSOCIATION_REFACTORED_ELEMENTS, currentlyRefactoredElements); + request.getParameters().put(org.eclipse.papyrus.infra.services.edit.utils.RequestParameterConstants.ASSOCIATION_REFACTORED_ELEMENTS, currentlyRefactoredElements); } // Retrieve property ends of the binary Association - if (association.getMemberEnds().size() == 2) { + if (2 == association.getMemberEnds().size()) { + // Retrieve property ends of the Association (assumed to be binary) + Property semanticSource = association.getMemberEnds().get(0); + Property semanticTarget = association.getMemberEnds().get(1); + if (semanticSource.getType().equals(semanticTarget.getType())) { + if (request.getDirection() == ReorientRequest.REORIENT_SOURCE) { + changeType = semanticTarget; + } + + if (request.getDirection() == ReorientRequest.REORIENT_TARGET) { + changeType = semanticSource; + } + } + // if this a binary // 1 property change its parents, if it is not contains by the association // 1 property change its types - changeContainer = association.getMemberEnds().get(0); - if (changeType.equals(association.getMemberEnds().get(0))) { - changeContainer = association.getMemberEnds().get(1); + changeContainer = semanticSource; + if (changeType.equals(semanticSource)) { + changeContainer = semanticTarget; } if (!association.getOwnedEnds().contains(changeContainer)) { moveRequest = new MoveRequest(request.getNewRelationshipEnd(), changeContainer); @@ -331,12 +346,9 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { setTypeRequest = new SetRequest(changeType, UMLPackage.eINSTANCE.getTypedElement_Type(), request.getNewRelationshipEnd()); - - if (moveRequest != null) { // Propagate parameters to the move request moveRequest.addParameters(request.getParameters()); - IElementEditService provider = ElementEditServiceUtils.getCommandProvider(request.getNewRelationshipEnd()); if (provider != null) { ICommand moveCommand = provider.getEditCommand(moveRequest); @@ -351,7 +363,7 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { // Process nary-association // we do pay attention to change container // Forbid source reorient - if (request.getDirection() == ReorientRelationshipRequest.REORIENT_SOURCE) { + if (request.getDirection() == ReorientRequest.REORIENT_SOURCE) { return UnexecutableCommand.INSTANCE; } @@ -382,7 +394,7 @@ public class AssociationEditHelperAdvice extends AbstractEditHelperAdvice { /** * Find the first memberEnd of an association that is typed by the specified classifier - * + * * @param association * @param classifier * @return diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz.tests/test/org/eclipse/papyrus/uml/diagram/clazz/test/AllTests.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz.tests/test/org/eclipse/papyrus/uml/diagram/clazz/test/AllTests.java index 1195b94b39b..28f7e49b67d 100644 --- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz.tests/test/org/eclipse/papyrus/uml/diagram/clazz/test/AllTests.java +++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz.tests/test/org/eclipse/papyrus/uml/diagram/clazz/test/AllTests.java @@ -18,6 +18,7 @@ import org.eclipse.papyrus.junit.framework.classification.ClassificationSuite.Dy import org.eclipse.papyrus.uml.diagram.clazz.test.canonical.AllCanonicalTests; import org.eclipse.papyrus.uml.diagram.clazz.test.canonical.TestClassDiagram; import org.eclipse.papyrus.uml.diagram.clazz.test.copyPaste.ConstraintPasteStrategyTest; +import org.eclipse.papyrus.uml.diagram.clazz.test.dnd.DragAndDropAssociationsTest; import org.eclipse.papyrus.uml.diagram.clazz.test.legacy.PackageDiagramLegacyTest; import org.eclipse.papyrus.uml.diagram.clazz.test.tests.Bug382954_InstanceSpecificationLink; import org.eclipse.papyrus.uml.diagram.clazz.test.tests.Bug476872_MoveCommandTest; @@ -41,7 +42,8 @@ import org.junit.runners.Suite.SuiteClasses; RoundedCompartmentTest.class, Bug476872_MoveCommandTest.class, Bug481317_MoveGeneralizationTest.class, - MoveContentsTest.class + MoveContentsTest.class, + DragAndDropAssociationsTest.class // load // LoadTests.class diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz.tests/test/org/eclipse/papyrus/uml/diagram/clazz/test/dnd/DragAndDropAssociationsTest.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz.tests/test/org/eclipse/papyrus/uml/diagram/clazz/test/dnd/DragAndDropAssociationsTest.java new file mode 100644 index 00000000000..d5fd2a9e5b8 --- /dev/null +++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.clazz.tests/test/org/eclipse/papyrus/uml/diagram/clazz/test/dnd/DragAndDropAssociationsTest.java @@ -0,0 +1,372 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST and others. + * + * 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: + * Fanch Bonnabesse (ALL4TEC) fanch.bonnabesse@alltec.net - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.uml.diagram.clazz.test.dnd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.RequestConstants; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.requests.ReconnectRequest; +import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest; +import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest; +import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequestFactory; +import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest; +import org.eclipse.gmf.runtime.emf.type.core.IElementType; +import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.AssociationEditPart; +import org.eclipse.papyrus.uml.diagram.clazz.providers.UMLElementTypes; +import org.eclipse.papyrus.uml.diagram.clazz.test.canonical.AbstractPapyrusTestCase; +import org.eclipse.papyrus.uml.diagram.common.editparts.ClassifierEditPart; +import org.eclipse.papyrus.uml.diagram.common.util.AssociationUtil; +import org.eclipse.uml2.uml.Association; +import org.eclipse.uml2.uml.Classifier; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.StructuredClassifier; +import org.junit.Assert; +import org.junit.Test; + +/** + * The test class to verify that there is no regression in relation to Bug 492893. + * Tests of the Drag and Drop via Model Explorer view to Class Diagram. + */ +public class DragAndDropAssociationsTest extends AbstractPapyrusTestCase { + + /** Message to inform that the diagram edit part is null. */ + private static final String DIAGRAM_EDITPART_NOT_NULL = "The Diagram Edit Part must not be null."; //$NON-NLS-1$ + /** Message to inform that the command isn't executable. */ + private static final String COMMAND_EXECUTABLE = "The command must be executable."; //$NON-NLS-1$ + /** Message to inform that the command is null. */ + protected static final String COMMAND_NOT_NULL = "The command must not be null."; //$NON-NLS-1$ + + /** + * Constructor. + */ + public DragAndDropAssociationsTest() { + super(); + } + + /** + * Test drop Association. + */ + @Test + public void testDropAssociationNotInverted() { + IGraphicalEditPart sourceEditPart = createChild(UMLElementTypes.Class_Shape, getDiagramEditPart(), 0); + IGraphicalEditPart targetEditPart = createChild(UMLElementTypes.Class_Shape, getDiagramEditPart(), 1); + Association association = createAssociation(sourceEditPart, targetEditPart); + checkAssociationSemantic(sourceEditPart, targetEditPart, association); + doDrop(association, sourceEditPart, targetEditPart); + } + + + + /** + * Test drop Association after a reorient of the target end. + */ + @Test + public void testDropAssociationAfterReorientTarget() { + IGraphicalEditPart sourceEditPart = createChild(UMLElementTypes.Class_Shape, getDiagramEditPart(), 0); + IGraphicalEditPart targetEditPart = createChild(UMLElementTypes.Class_Shape, getDiagramEditPart(), 1); + Association association = createAssociation(sourceEditPart, targetEditPart); + checkAssociationSemantic(sourceEditPart, targetEditPart, association); + IGraphicalEditPart newTargetEditPart = createChild(UMLElementTypes.Class_Shape, getDiagramEditPart(), 2); + AssociationEditPart firstAssociationEditPart = getFirstAssociationEditPart(); + + ReconnectRequest reconnectReq = new ReconnectRequest(RequestConstants.REQ_RECONNECT_TARGET); + reconnectReq.setConnectionEditPart(firstAssociationEditPart); + reconnectReq.setTargetEditPart(newTargetEditPart); + Command command = newTargetEditPart.getCommand(reconnectReq); + executeOnUIThread(command); + + doDrop(association, sourceEditPart, newTargetEditPart); + } + + /** + * Test drop Association after a reorient of the source end. + */ + @Test + public void testDropAssociationAfterReorientSource() { + IGraphicalEditPart sourceEditPart = createChild(UMLElementTypes.Class_Shape, getDiagramEditPart(), 0); + IGraphicalEditPart targetEditPart = createChild(UMLElementTypes.Class_Shape, getDiagramEditPart(), 1); + Association association = createAssociation(sourceEditPart, targetEditPart); + checkAssociationSemantic(sourceEditPart, targetEditPart, association); + IGraphicalEditPart newSourceEditPart = createChild(UMLElementTypes.Class_Shape, getDiagramEditPart(), 2); + AssociationEditPart firstAssociationEditPart = getFirstAssociationEditPart(); + + ReconnectRequest reconnectReq = new ReconnectRequest(RequestConstants.REQ_RECONNECT_SOURCE); + reconnectReq.setConnectionEditPart(firstAssociationEditPart); + reconnectReq.setTargetEditPart(newSourceEditPart); + Command command = newSourceEditPart.getCommand(reconnectReq); + executeOnUIThread(command); + + doDrop(association, newSourceEditPart, targetEditPart); + } + + /** + * + * @param association + * @param sourceEditPart + * @param targetEditPart + */ + protected void doDrop(final Association association, final IGraphicalEditPart sourceEditPart, final IGraphicalEditPart targetEditPart) { + DropObjectsRequest dropObjectsRequest = new DropObjectsRequest(); + ArrayList<Element> list = new ArrayList<Element>(); + list.add(association); + dropObjectsRequest.setObjects(list); + dropObjectsRequest.setLocation(new Point(20, 20)); + + DiagramEditPart diagramEditPart = getDiagramEditPart(); + assertNotNull(DIAGRAM_EDITPART_NOT_NULL, diagramEditPart); + + List<AssociationEditPart> associationEdges = getAssociationEditParts(association); + assertEquals(1, associationEdges.size()); + checkSourceTarget(associationEdges, (Classifier) sourceEditPart.resolveSemanticElement(), (Classifier) targetEditPart.resolveSemanticElement()); + + Command command = diagramEditPart.getCommand(dropObjectsRequest); + assertNotNull(COMMAND_NOT_NULL, command); + assertTrue(COMMAND_EXECUTABLE, command.canExecute()); + executeOnUIThread(command); + + associationEdges = getAssociationEditParts(association); + assertEquals(2, associationEdges.size()); + checkSourceTarget(associationEdges, (Classifier) sourceEditPart.resolveSemanticElement(), (Classifier) targetEditPart.resolveSemanticElement()); + + command.undo(); + + associationEdges = getAssociationEditParts(association); + assertEquals(1, associationEdges.size()); + checkSourceTarget(associationEdges, (Classifier) sourceEditPart.resolveSemanticElement(), (Classifier) targetEditPart.resolveSemanticElement()); + + command.redo(); + + associationEdges = getAssociationEditParts(association); + assertEquals(2, associationEdges.size()); + checkSourceTarget(associationEdges, (Classifier) sourceEditPart.resolveSemanticElement(), (Classifier) targetEditPart.resolveSemanticElement()); + } + + /** + * Check the source and the tagret end. + * + * @param associationEditParts + * @param expectedSource + * @param expectedTarget + */ + protected void checkSourceTarget(final List<AssociationEditPart> associationEditParts, final Classifier expectedSource, final Classifier expectedTarget) { + for (AssociationEditPart editPart : associationEditParts) { + EditPart sourceEditPart = editPart.getSource(); + assertTrue(sourceEditPart instanceof ClassifierEditPart); + EObject sourceElement = ((ClassifierEditPart) sourceEditPart).resolveSemanticElement(); + assertEquals(expectedSource, sourceElement); + + + EditPart targetEditPart = editPart.getTarget(); + assertTrue(targetEditPart instanceof ClassifierEditPart); + EObject targetElement = ((ClassifierEditPart) targetEditPart).resolveSemanticElement(); + assertEquals(expectedTarget, targetElement); + + checkMemberEnds((Association) editPart.resolveSemanticElement(), expectedSource, expectedTarget); + } + } + + /** + * Validate the source and target MemberEnds of an Edge. + * + * @param edge + * The Edge. + * @param sourceType + * The expected source Type. + * @param targetType + * The expected target Type. + */ + protected void checkMemberEnds(final Association association, final Classifier sourceType, final Classifier targetType) { + Property sourceEnd = AssociationUtil.getSourceFirstEnd(association); + Property targetEnd = AssociationUtil.getTargetSecondEnd(association); + // Target End is based on the source type + assertEquals(sourceType, targetEnd.getType()); + // Source End is based on the target type + assertEquals(targetType, sourceEnd.getType()); + } + + /** + * Get all the AssociationEditPart of an Association element. + * + * @param association + * The Association. + * @return The List of AssociationEdiPart. + */ + protected List<AssociationEditPart> getAssociationEditParts(final Association association) { + List<AssociationEditPart> associationEditParts = new ArrayList<>(); + @SuppressWarnings("unchecked") + List<Object> connections = diagramEditPart.getConnections(); + for (Object connection : connections) { + if (connection instanceof AssociationEditPart) { + if (((AssociationEditPart) connection).resolveSemanticElement().equals(association)) { + associationEditParts.add((AssociationEditPart) connection); + } + } + } + return associationEditParts; + } + + /** + * Get the only one AssociationEditPart of the DiagramEditPart. + * + * @return The AssociationEditPart. + */ + protected AssociationEditPart getFirstAssociationEditPart() { + // tHe diagram contains only one Association + assertEquals(1, getDiagramEditPart().getConnections().size()); + Object connection = getDiagramEditPart().getConnections().get(0); + assertNotNull(connection); + Assert.assertTrue(connection instanceof AssociationEditPart); + return (AssociationEditPart) connection; + } + + /** + * Find the Association contained on a Diagram. + * + * @param source + * The source of the Association. + * @return The Association. + */ + protected Association findAssociation(final IGraphicalEditPart source) { + assertEquals(1, getDiagramEditPart().getConnections().size()); + assertEquals(1, ((Classifier) source.resolveSemanticElement()).getAssociations().size()); + Association associationFromClassifier = ((Classifier) source.resolveSemanticElement()).getAssociations().get(0); + Object connection = getDiagramEditPart().getConnections().get(0); + assertNotNull(connection); + Assert.assertTrue(connection instanceof AssociationEditPart); + EObject associationSemantic = ((AssociationEditPart) connection).resolveSemanticElement(); + assertTrue("Created link is not association.", associationSemantic instanceof Association); //$NON-NLS-1$ + assertTrue("Diagram contains two different associations.", associationSemantic == associationFromClassifier); //$NON-NLS-1$ + return (Association) associationSemantic; + } + + /** + * Check the source and target EditPart of an Association. + * + * @param source + * The expected source EditPart. + * @param target + * The expected target EditPart. + * @param association + * The Association. + */ + protected void checkAssociationSemantic(final IGraphicalEditPart source, final IGraphicalEditPart target, final Association association) { + // check source semantic + EObject sourceSemantic = source.resolveSemanticElement(); + assertTrue("Source should be StructuredClassifier.", sourceSemantic instanceof StructuredClassifier); //$NON-NLS-1$ + List<Property> sourceProperties = ((StructuredClassifier) sourceSemantic).getOwnedAttributes(); + assertEquals("Source owned attributes", 1, sourceProperties.size()); //$NON-NLS-1$ + Property sourceProperty = sourceProperties.get(0); + assertEquals("Source property type", target.resolveSemanticElement(), sourceProperty.getType()); //$NON-NLS-1$ + // check target semantic + EObject targetSemantic = target.resolveSemanticElement(); + assertTrue("Target should be StructuredClassifier.", targetSemantic instanceof StructuredClassifier); //$NON-NLS-1$ + assertEquals("Target owned attributes", 0, ((StructuredClassifier) targetSemantic).getOwnedAttributes().size()); //$NON-NLS-1$ + // check association semantic + List<Property> associationProperties = association.getOwnedEnds(); + assertEquals("Association owned attributes", 1, associationProperties.size()); //$NON-NLS-1$ + Property associationProperty = associationProperties.get(0); + assertEquals("Association property owner", association, associationProperty.eContainer()); //$NON-NLS-1$ + assertEquals("Association property type", sourceSemantic, associationProperty.getType()); //$NON-NLS-1$ + } + + /** + * Create a child on the diagram. + * + * @param childType + * The kind of child. + * @param container + * The container of the new child. + * @param num + * The index of the new child on the list of children. + * @return + */ + protected IGraphicalEditPart createChild(final IElementType childType, final IGraphicalEditPart container, final int num) { + final CreateViewRequest requestcreation = CreateViewRequestFactory.getCreateShapeRequest(childType, container.getDiagramPreferencesHint()); + requestcreation.setSize(new Dimension(1, 1)); + requestcreation.setLocation(new Point(10, 10)); + Command cmd = container.getCommand(requestcreation); + executeOnUIThread(cmd); + assertEquals("Probably, child was not created.", num + 1, getDiagramEditPart().getChildren().size()); //$NON-NLS-1$ + return (IGraphicalEditPart) getDiagramEditPart().getChildren().get(num); + } + + /** + * Create an Association. + * + * @param source + * The source EditPart of the Association. + * @param target + * The target EditPart of the Association. + * @return The new Association. + */ + protected Association createAssociation(final IGraphicalEditPart source, final IGraphicalEditPart target) { + createLink(UMLElementTypes.Association_Edge, source, target); + return findAssociation(source); + } + + /** + * Create a new link. + * + * @param type + * The type of the link + * @param source + * The source EditPart of the link. + * @param target + * The target EditPart of the link. + */ + protected void createLink(final IElementType type, final EditPart source, final EditPart target) { + Command endCommand = target.getCommand(createConnectionViewRequest(type, source, target)); + Assert.assertNotNull(endCommand); + Assert.assertTrue(endCommand.canExecute()); + executeOnUIThread(endCommand); + Assert.assertEquals(1, getDiagramEditPart().getConnections().size()); + } + + /** + * Create the Connection view request. + * + * @param type + * The type of the Connection. + * @param source + * The source EditPart of the Connection. + * @param target + * The Target EditPart of the Connection. + * @return The new CreateConnectionViewRequest. + */ + protected CreateConnectionViewRequest createConnectionViewRequest(final IElementType type, final EditPart source, final EditPart target) { + CreateConnectionViewRequest connectionRequest = CreateViewRequestFactory.getCreateConnectionRequest(type, ((IGraphicalEditPart) getDiagramEditPart()).getDiagramPreferencesHint()); + connectionRequest.setSourceEditPart(null); + connectionRequest.setTargetEditPart(source); + connectionRequest.setType(RequestConstants.REQ_CONNECTION_START); + source.getCommand(connectionRequest); + connectionRequest.setSourceEditPart(source); + connectionRequest.setTargetEditPart(target); + connectionRequest.setType(RequestConstants.REQ_CONNECTION_END); + return connectionRequest; + } + +} |