diff options
| author | Remi Schnekenburger | 2016-05-11 13:58:51 +0000 |
|---|---|---|
| committer | Remi Schnekenburger | 2016-05-17 08:38:14 +0000 |
| commit | 9c823e68677588fa4caa2bf58654d0db605ac402 (patch) | |
| tree | 096e04d09e3c3cdf4e57cc49f7bebc165840011e | |
| parent | 7fad5e1ae10936069dfe90c9a6517d8784f053c4 (diff) | |
| download | org.eclipse.papyrus-rt-9c823e68677588fa4caa2bf58654d0db605ac402.tar.gz org.eclipse.papyrus-rt-9c823e68677588fa4caa2bf58654d0db605ac402.tar.xz org.eclipse.papyrus-rt-9c823e68677588fa4caa2bf58654d0db605ac402.zip | |
Bug 472885: [tooling] Papyrus-RT shall support CapsulePart creation
using drag n drop from model explorer
https://bugs.eclipse.org/bugs/show_bug.cgi?id=472885
- adding a workaround for specific drop strategies: new edit policy
similar to the customizable edit policy, but with a filter on the
available strategies. this should left intact the feature for composite
structure diagrams, and avoid the choice menu with basic element for the
Capsule Structure diagram. A new drop strategy can be created and added
to the capsule structure diagram, the choice menu will still popup.
- exporting the new package at runtime (as internal, this workaround
should be removed when Papyrus has a better support for Drop strategy
customization)
- update tests, to find the drop strategy directly from the edit part
and the drop request rather than specifying the drop with a dedicated
strategy
Change-Id: I367888ee9484628f923395cea4bf392684e57d27
Signed-off-by: Remi Schnekenburger <remi.schnekenburger@cea.fr>
10 files changed, 657 insertions, 48 deletions
diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/META-INF/MANIFEST.MF b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/META-INF/MANIFEST.MF index f281076fc..8c7ec742d 100644 --- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/META-INF/MANIFEST.MF +++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/META-INF/MANIFEST.MF @@ -55,6 +55,7 @@ Export-Package: org.eclipse.papyrusrt.umlrt.tooling.diagram.common, org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies, org.eclipse.papyrusrt.umlrt.tooling.diagram.common.figures, org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.canonical;x-internal:=true, + org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.drop;x-internal:=true, org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.sync;x-internal:=true, org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.sync.statemachine;x-internal:=true, org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.utils;x-internal:=true, diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/plugin.xml b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/plugin.xml index 1449d1e4b..6847f0b65 100644 --- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/plugin.xml +++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/plugin.xml @@ -128,4 +128,13 @@ </enablement> </semanticChildrenStrategy> </extension> + <extension + point="org.eclipse.gmf.runtime.diagram.ui.editpolicyProviders"> + <editpolicyProvider + class="org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.drop.RTCapsuleStructureCompartmentDragDropEditPolicyProvider"> + <Priority + name="High"> + </Priority> + </editpolicyProvider> + </extension> </plugin> diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/AbstractProtocolToRTPortDropStrategy.java b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/AbstractProtocolToRTPortDropStrategy.java index 31fb3c76b..eca30cad3 100644 --- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/AbstractProtocolToRTPortDropStrategy.java +++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/AbstractProtocolToRTPortDropStrategy.java @@ -134,7 +134,6 @@ public abstract class AbstractProtocolToRTPortDropStrategy extends Transactional } } } - return command; } diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editparts/RTClassCompositeEditPart.java b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editparts/RTClassCompositeEditPart.java index 45a1266a9..4f1ebb048 100644 --- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editparts/RTClassCompositeEditPart.java +++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editparts/RTClassCompositeEditPart.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2015, 2016 CEA LIST and others. + * Copyright (c) 2015, 2016 CEA LIST, Christian W. Damus, and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -8,21 +8,19 @@ * * Contributors: * Celine JANSSENS (ALL4TEC) celine.janssens@all4tec.net - Initial API and implementation + * Christian W. Damus - bug 472885 *****************************************************************************/ package org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editparts; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; import org.eclipse.gef.EditPart; -import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeCompartmentEditPart; import org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeEditPart; import org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeNameEditPart; import org.eclipse.papyrus.uml.diagram.composite.edit.parts.PortEditPart; -import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.RTCustomDiagramDragDropEditPolicy; -import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.RTSideAffixedNodesCreationEditPolicy; import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.locator.RTPortPositionLocator; @@ -44,20 +42,6 @@ public class RTClassCompositeEditPart extends ClassCompositeEditPart { } /** - * Add the specific EditPolicies to DND and to Create an RT port - * - * @see org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeEditPart#createDefaultEditPolicies() - * - */ - @Override - protected void createDefaultEditPolicies() { - - super.createDefaultEditPolicies(); - installEditPolicy(EditPolicyRoles.CREATION_ROLE, new RTSideAffixedNodesCreationEditPolicy()); - installEditPolicy(EditPolicyRoles.DRAG_DROP_ROLE, new RTCustomDiagramDragDropEditPolicy()); - } - - /** * Redefine the way the Affixed Child note is added to the EditPart by specifying the Port Position Locator as {@link RTPortPositionLocator}. * * @see org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeEditPart#addFixedChild(org.eclipse.gef.EditPart) diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editparts/RTPropertyPartEditPart.java b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editparts/RTPropertyPartEditPart.java index 56dab1cf4..be104881f 100644 --- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editparts/RTPropertyPartEditPart.java +++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editparts/RTPropertyPartEditPart.java @@ -8,7 +8,7 @@ * * Contributors: * Celine Janssens (ALL4TEC) celine.janssens@all4tec.net - Initial API and implementation - * Christian W. Damus - bugs 477819, 482599 + * Christian W. Damus - bugs 477819, 482599, 472885 * *****************************************************************************/ package org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editparts; @@ -17,16 +17,10 @@ import org.eclipse.draw2d.IFigure; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.impl.AdapterImpl; -import org.eclipse.gef.EditPolicy; -import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.papyrus.uml.diagram.composite.edit.parts.PropertyPartEditPartCN; import org.eclipse.papyrusrt.umlrt.core.types.advice.CapsulePartEditHelperAdvice; import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editparts.providers.RTEditPartProvider; -import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.CanonicalPortDisplayEditPolicy; -import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.RTCustomDiagramDragDropEditPolicy; -import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.RTResizableShapeEditPolicy; -import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.RTSideAffixedNodesCreationEditPolicy; import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.figures.RTPropertyPartFigure; import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.MultiplicityElement; @@ -189,24 +183,6 @@ public class RTPropertyPartEditPart extends PropertyPartEditPartCN { /** * {@inheritDoc} * - * @see org.eclipse.papyrus.uml.diagram.composite.edit.parts.PropertyPartEditPartCN#createDefaultEditPolicies() - * - */ - @Override - protected void createDefaultEditPolicies() { - - super.createDefaultEditPolicies(); - installEditPolicy(EditPolicyRoles.CREATION_ROLE, new RTSideAffixedNodesCreationEditPolicy()); - installEditPolicy(EditPolicyRoles.DRAG_DROP_ROLE, new RTCustomDiagramDragDropEditPolicy()); - installEditPolicy(CanonicalPortDisplayEditPolicy.CANONICAL_PORT_DISPLAY_ROLE, new CanonicalPortDisplayEditPolicy()); - installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new RTResizableShapeEditPolicy()); - - } - - - /** - * {@inheritDoc} - * * @see org.eclipse.papyrus.uml.diagram.composite.edit.parts.PropertyPartEditPartCN#createNodeShape() * */ diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/internal/drop/RTCapsuleStructureCompartmentDragDropEditPolicyProvider.java b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/internal/drop/RTCapsuleStructureCompartmentDragDropEditPolicyProvider.java new file mode 100644 index 000000000..637327e99 --- /dev/null +++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/internal/drop/RTCapsuleStructureCompartmentDragDropEditPolicyProvider.java @@ -0,0 +1,130 @@ +/***************************************************************************** + * Copyright (c) 2016 CEA LIST, Christian W. Damus, 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: + * CEA LIST - Initial API and implementation + * Christian W. Damus - bug 472885 + *****************************************************************************/ +package org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.drop; + +import java.util.function.Supplier; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gmf.runtime.common.core.service.AbstractProvider; +import org.eclipse.gmf.runtime.common.core.service.IOperation; +import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; +import org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.CreateEditPoliciesOperation; +import org.eclipse.gmf.runtime.diagram.ui.services.editpolicy.IEditPolicyProvider; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; +import org.eclipse.papyrus.infra.gmfdiag.common.utils.ServiceUtilsForEditPart; +import org.eclipse.papyrus.infra.gmfdiag.dnd.policy.CustomizableDropEditPolicy; +import org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.CustomDiagramDragDropEditPolicy; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editparts.RTClassCompositeCompartmentEditPart; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editparts.RTClassCompositeEditPart; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editparts.RTPropertyPartEditPart; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.CanonicalPortDisplayEditPolicy; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.RTCustomDiagramDragDropEditPolicy; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.RTResizableShapeEditPolicy; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.RTSideAffixedNodesCreationEditPolicy; + +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ListMultimap; + +/** + * <p> + * Specific Edit policy provider for some elements on the capsule structure diagram to override customizable drag and drop edit policies. + * </p> + * <p> + * This is in part used as a workaround for <a href="http://eclip.se/472885">bug 472885: [tooling] Papyrus-RT shall support CapsulePart creation using drag n drop from model explorer</a>. + * </p> + * + * @see <a href="http://eclip.se/472885">bug 472885</a> + */ +public class RTCapsuleStructureCompartmentDragDropEditPolicyProvider extends AbstractProvider implements IEditPolicyProvider { + + // Ordering is important because some edit-policies look for ones installed previously + private static final ListMultimap<Class<? extends EditPart>, EditPolicyBinding> editPolicies = ImmutableListMultimap.<Class<? extends EditPart>, EditPolicyBinding> builder() + .put(RTClassCompositeEditPart.class, bind(EditPolicyRoles.CREATION_ROLE, RTSideAffixedNodesCreationEditPolicy::new)) + .put(RTClassCompositeEditPart.class, bind(EditPolicyRoles.DRAG_DROP_ROLE, RTCustomDiagramDragDropEditPolicy::new)) + .put(RTClassCompositeCompartmentEditPart.class, bind(EditPolicyRoles.DRAG_DROP_ROLE, CustomDiagramDragDropEditPolicy::new)) + .put(RTPropertyPartEditPart.class, bind(EditPolicyRoles.CREATION_ROLE, RTSideAffixedNodesCreationEditPolicy::new)) + .put(RTPropertyPartEditPart.class, bind(EditPolicyRoles.DRAG_DROP_ROLE, RTCustomDiagramDragDropEditPolicy::new)) + .put(RTPropertyPartEditPart.class, bind(CanonicalPortDisplayEditPolicy.CANONICAL_PORT_DISPLAY_ROLE, CanonicalPortDisplayEditPolicy::new)) + .put(RTPropertyPartEditPart.class, bind(EditPolicy.PRIMARY_DRAG_ROLE, RTResizableShapeEditPolicy::new)) + .build(); + + /** + * {@inheritDoc} + */ + @Override + public boolean provides(IOperation operation) { + CreateEditPoliciesOperation epOperation = (CreateEditPoliciesOperation) operation; + + try { + ServicesRegistry registry = ServiceUtilsForEditPart.getInstance().getServiceRegistry(epOperation.getEditPart()); + if (registry == null) { + return false; + } + + // Do I recognize this edit-part? + EditPart editPart = epOperation.getEditPart(); + return editPolicies.containsKey(editPart.getClass()); + } catch (ServiceException e) { + return false; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void createEditPolicies(EditPart editPart) { + // Install our edit-policies for this edit-part. Critically: including + // the drop policy! + editPolicies.get(editPart.getClass()).forEach(b -> b.apply(editPart)); + + // Unwrap the existing creation policy, if necessary + EditPolicy creation = editPart.getEditPolicy(EditPolicyRoles.CREATION_ROLE); + if (creation instanceof CustomizableDropEditPolicy) { + creation = ((CustomizableDropEditPolicy) creation).getDefaultCreationPolicy(); + } + + // create a new edit policy as it is done in standard diagrams. + CustomizableDropEditPolicy customEditPolicy = new RTCapsuleStructureDiagramDragDropEditPolicy( + editPart.getEditPolicy(EditPolicyRoles.DRAG_DROP_ROLE), + creation); + editPart.installEditPolicy(EditPolicyRoles.DRAG_DROP_ROLE, null); + editPart.installEditPolicy(EditPolicyRoles.CREATION_ROLE, customEditPolicy); + + } + + private static EditPolicyBinding bind(String role, Supplier<? extends EditPolicy> editPolicy) { + return new EditPolicyBinding(role, editPolicy); + } + + // + // Nested types + // + + private static final class EditPolicyBinding { + final String role; + final Supplier<? extends EditPolicy> editPolicySupplier; + + EditPolicyBinding(String role, Supplier<? extends EditPolicy> editPolicySupplier) { + super(); + this.role = role; + this.editPolicySupplier = editPolicySupplier; + } + + void apply(EditPart editPart) { + editPart.installEditPolicy(role, editPolicySupplier.get()); + } + } +} diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/internal/drop/RTCapsuleStructureDiagramDragDropEditPolicy.java b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/internal/drop/RTCapsuleStructureDiagramDragDropEditPolicy.java new file mode 100644 index 000000000..49453b8f6 --- /dev/null +++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/internal/drop/RTCapsuleStructureDiagramDragDropEditPolicy.java @@ -0,0 +1,66 @@ +/***************************************************************************** + * 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: + * CEA LIST - Initial API and implementation + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.drop; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.commands.Command; +import org.eclipse.papyrus.infra.gmfdiag.dnd.policy.CustomizableDropEditPolicy; +import org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy; +import org.eclipse.papyrus.uml.diagram.composite.custom.edit.policies.CustomDiagramDragDropEditPolicy; + +/** + * Edit policy to override {@link CustomDiagramDragDropEditPolicy} for Capsule structure compartment edit part. + * Workaround for the Bug 472885: [tooling] Papyrus-RT shall support CapsulePart creation using drag n drop from model explorer + */ +public class RTCapsuleStructureDiagramDragDropEditPolicy extends CustomizableDropEditPolicy { + + /** key for the specific edit policy that creates a property while dragging a classifier onto the structure compartment of a classifier. */ + private static final String ORG_ECLIPSE_PAPYRUS_UML_DIAGRAM_DND_CLASSIFIER_TO_STRUCTURE_COMP_AS_PROPERTY_DROP = "org.eclipse.papyrus.uml.diagram.dnd.ClassifierToStructureCompAsPropertyDrop"; + + /** + * Constructor. + * + * @param defaultDropEditPolicy + * The default editPolicy, to be called when no custom Drop strategy is available. + * @param defaultCreationEditPolicy + * The default creation edit policy replaced by this {@link CustomizableDropEditPolicy} + */ + public RTCapsuleStructureDiagramDragDropEditPolicy(EditPolicy defaultDropEditPolicy, EditPolicy defaultCreationEditPolicy) { + super(defaultDropEditPolicy, defaultCreationEditPolicy); + } + + /** + * {@inheritDoc} + */ + @Override + protected Map<DropStrategy, List<Command>> findExtendedStrategies(Request request) { + Map<DropStrategy, List<Command>> unfilteredMap = super.findExtendedStrategies(request); + Map<DropStrategy, List<Command>> filteredMap = new HashMap<>(unfilteredMap); + + // remove the unwanted strategy, leaving all other accessible + for (DropStrategy strategy : unfilteredMap.keySet()) { + if (ORG_ECLIPSE_PAPYRUS_UML_DIAGRAM_DND_CLASSIFIER_TO_STRUCTURE_COMP_AS_PROPERTY_DROP.equals(strategy.getID())) { + filteredMap.remove(strategy); + } else if ("default".equals(strategy.getID())) { + filteredMap.remove(strategy); + } + } + return filteredMap; + } + +} diff --git a/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/tests/CapsuleToCapsulePartOnCapsuleDropStrategyTest.java b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/tests/CapsuleToCapsulePartOnCapsuleDropStrategyTest.java new file mode 100644 index 000000000..05002083b --- /dev/null +++ b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/tests/CapsuleToCapsulePartOnCapsuleDropStrategyTest.java @@ -0,0 +1,107 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus 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: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.tooling.diagram.common.drop.tests; + +import static org.eclipse.papyrusrt.junit.matchers.NumberFuzzyMatcher.near; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.gef.EditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; +import org.eclipse.gmf.runtime.notation.Location; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil; +import org.eclipse.papyrus.junit.utils.rules.ActiveDiagram; +import org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture; +import org.eclipse.papyrus.junit.utils.rules.PluginResource; +import org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeCompartmentEditPart; +import org.eclipse.papyrus.uml.diagram.composite.edit.parts.PropertyPartEditPartCN; +import org.eclipse.papyrusrt.junit.rules.UIThreadRule; +import org.eclipse.papyrusrt.junit.rules.UMLRTViewpointRule; +import org.eclipse.papyrusrt.umlrt.core.utils.CapsulePartUtils; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.tests.CapsulePartEditingFixture; +import org.eclipse.uml2.uml.Property; +import org.junit.Assert; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; + +/** + * Test cases for creation of capsuleParts on capsule-parts by dropping protocols + * in the Capsule Structure Diagram. + */ +@ActiveDiagram("Capsule1") +@PluginResource("/resource/capsules/model.di") +public class CapsuleToCapsulePartOnCapsuleDropStrategyTest { + + @ClassRule + public static final TestRule uiThread = new UIThreadRule(); + + @ClassRule + public static final TestRule viewpoint = new UMLRTViewpointRule(); + + @Rule + public final PapyrusEditorFixture editor = new PapyrusEditorFixture(); + + private final CapsulePartEditingFixture capsuleParts = new CapsulePartEditingFixture(editor, "Capsule1", "capsule2"); + + private Point capsuleCompartmentLocation = new Point(41, 70); + + // In the coordinate space of the capsule compartment + private Point pointOnCompartmentLocation = new Point(46, 37).getTranslated(capsuleCompartmentLocation); + + /** + * Initializes me. + */ + public CapsuleToCapsulePartOnCapsuleDropStrategyTest() { + super(); + } + + @Test + public void dropCapsuleOnCapsule() { + DiagramEditPart theDiagram = editor.getActiveDiagram(); + + // Offset by location of the class frame + Property property = capsuleParts.dropCapsule(pointOnCompartmentLocation, + "Capsule2"); + + // Semantics of the port + assertThat(property.getName(), is("capsule2")); + assertThat(property.getType(), instanceOf(org.eclipse.uml2.uml.Class.class)); + assertThat(property.getType().getName(), is("Capsule2")); + Assert.assertTrue(CapsulePartUtils.isCapsulePart(property)); + + EditPart editPart = editor.requireEditPart(editor.getActiveDiagram(), property); + Location location = capsuleParts.requireLocation(editPart); + assertThat(location.getX(), near(245, 5)); // 245 != pointOnCompartmentLocation.x() + assertThat(location.getY(), near(109, 5)); // 109 != pointOnCompartmentLocation.y() + + // Undo the edit + editor.activateDiagram(theDiagram); + editor.undo(); + DiagramEditPartsUtil.getAllEditParts(theDiagram) + .forEach(ep -> { + View view = ep.getNotationView(); + if ((view != null) && ClassCompositeCompartmentEditPart.VISUAL_ID.equals(view.getType())) { + // No capsuleParts on parts + assertThat(ep.getChildBySemanticHint(PropertyPartEditPartCN.VISUAL_ID), nullValue()); + } + }); + } + +} diff --git a/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editpolicies/tests/CapsulePartEditingFixture.java b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editpolicies/tests/CapsulePartEditingFixture.java new file mode 100644 index 000000000..ef40aaf73 --- /dev/null +++ b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editpolicies/tests/CapsulePartEditingFixture.java @@ -0,0 +1,338 @@ +/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus 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: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrusrt.umlrt.tooling.diagram.common.editpolicies.tests; + +import static org.eclipse.papyrus.junit.matchers.MoreMatchers.greaterThan; +import static org.eclipse.papyrusrt.junit.matchers.CommandMatchers.isExecutable; +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; +import org.eclipse.gef.commands.Command; +import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.ITextAwareEditPart; +import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest; +import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest; +import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry; +import org.eclipse.gmf.runtime.emf.type.core.IHintedType; +import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest; +import org.eclipse.gmf.runtime.notation.LayoutConstraint; +import org.eclipse.gmf.runtime.notation.Location; +import org.eclipse.gmf.runtime.notation.Node; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture; +import org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeEditPart; +import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.utils.RelativePortLocation; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.EncapsulatedClassifier; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.UMLPackage; + +/** + * A fixture for assistance with the editing of capsuleparts. + */ +public class CapsulePartEditingFixture { + private final PapyrusEditorFixture editor; + + private String capsuleName; + private String partName; + + /** + * Initializes me with the editor fixture on which I operate. + */ + public CapsulePartEditingFixture(PapyrusEditorFixture editor) { + this(editor, null); + } + + /** + * Initializes me with the editor fixture on which I operate and the + * capsule on which to create ports, by default. + */ + public CapsulePartEditingFixture(PapyrusEditorFixture editor, String defaultCapsuleName) { + this(editor, defaultCapsuleName, null); + } + + /** + * Initializes me with the editor fixture on which I operate and the + * part in a capsule on which to create ports, by default. + */ + public CapsulePartEditingFixture(PapyrusEditorFixture editor, String defaultCapsuleName, String defaultPartName) { + super(); + + this.editor = editor; + this.capsuleName = defaultCapsuleName; + this.partName = defaultPartName; + } + + public Property createCapsulePartWithTool(Point mouse, String elementTypeID) { + return (partName == null) + ? createCapsulePartWithTool(mouse, elementTypeID, capsuleName) + : createCapsulePartWithTool(mouse, elementTypeID, capsuleName, partName); + } + + public Property createCapsulePartWithTool(Point mouse, String elementTypeID, String capsuleName) { + EncapsulatedClassifier capsule = (EncapsulatedClassifier) editor.getModel().getOwnedType( + capsuleName, false, UMLPackage.Literals.ENCAPSULATED_CLASSIFIER, false); + + Command command = getCreateCapsulePartCommand(capsule, mouse, elementTypeID); + assertThat("No executable command obtained from diagram", command, isExecutable()); + editor.execute(command); + + assertThat("No capsule part created", capsule.getOwnedAttributes(), hasItem(anything())); + return capsule.getOwnedAttributes().get(capsule.getOwnedAttributes().size() - 1); + } + + /** + * Obtains a command that creates a port of the specified type at the given {@code mouse} + * location in the {@code capsule} structure diagram. + * + * @param capsule + * a capsule + * @param mouse + * the mouse location in the diagram (in the diagram's overall coordinate system) + * @param elementTypeID + * the type of port to create + * + * @return the command, or {@code null} if none was provided by the diagram + */ + private Command getCreateCapsulePartCommand(EncapsulatedClassifier capsule, Point mouse, String elementTypeID) { + EditPart editPart = editor.getActiveDiagram().getChildBySemanticHint(ClassCompositeEditPart.VISUAL_ID); + assertThat("Class frame not found in diagram", editPart, instanceOf(IGraphicalEditPart.class)); + IGraphicalEditPart classFrame = (IGraphicalEditPart) editPart; + + EditPart underMouse = classFrame.getViewer().findObjectAt(mouse); + + IHintedType typeToCreate = (IHintedType) ElementTypeRegistry.getInstance().getType(elementTypeID); + CreateElementRequest createElement = new CreateElementRequest(capsule, typeToCreate); + CreateElementRequestAdapter createAdapter = new CreateElementRequestAdapter(createElement); + CreateViewAndElementRequest request = new CreateViewAndElementRequest( + new CreateViewAndElementRequest.ViewAndElementDescriptor( + createAdapter, Node.class, typeToCreate.getSemanticHint(), editor.getPreferencesHint())); + request.setType(RequestConstants.REQ_CREATE); + request.setLocation(mouse); + EditPart target = getTargetEditPart(underMouse, request); + + return target.getCommand(request); + } + + public void assertCannotCreateCapsulePartWithTool(Point mouse, String elementTypeID) { + if (partName == null) { + assertCannotCreateCapsulePartWithTool(mouse, elementTypeID, capsuleName); + } else { + assertCannotCreateCapsulePartWithTool(mouse, elementTypeID, capsuleName, partName); + } + } + + public void assertCannotCreateCapsulePartWithTool(Point mouse, String elementTypeID, String capsuleName) { + EncapsulatedClassifier capsule = (EncapsulatedClassifier) editor.getModel().getOwnedType( + capsuleName, false, UMLPackage.Literals.ENCAPSULATED_CLASSIFIER, false); + + Command command = getCreateCapsulePartCommand(capsule, mouse, elementTypeID); + assertThat("An executable command was provided", command, not(isExecutable())); + } + + public void assertCannotCreateCapsulePartWithTool(Point mouse, String elementTypeID, String capsuleName, String partName) { + EncapsulatedClassifier capsule = (EncapsulatedClassifier) editor.getModel().getOwnedType( + capsuleName, false, UMLPackage.Literals.ENCAPSULATED_CLASSIFIER, false); + Property part = capsule.getOwnedAttribute(partName, null); + + Command command = getCreateCapsulePartCommand(part, mouse, elementTypeID); + assertThat("An executable command was provided", command, not(isExecutable())); + } + + public Location requireLocation(EditPart editPart) { + assertThat("Not a graphical edit-part", editPart, instanceOf(IGraphicalEditPart.class)); + View view = ((IGraphicalEditPart) editPart).getNotationView(); + assertThat("View is not a Node", view, instanceOf(Node.class)); + LayoutConstraint constraint = ((Node) view).getLayoutConstraint(); + assertThat("Layout constraint is not a Location", constraint, instanceOf(Location.class)); + return (Location) constraint; + } + + public Property createCapsulePartWithTool(Point mouse, String elementTypeID, String capsuleName, String partName) { + EncapsulatedClassifier capsule = (EncapsulatedClassifier) editor.getModel().getOwnedType( + capsuleName, false, UMLPackage.Literals.ENCAPSULATED_CLASSIFIER, false); + Property part = capsule.getOwnedAttribute(partName, null); + + Command command = getCreateCapsulePartCommand(part, mouse, elementTypeID); + assertThat("No executable command obtained from diagram", command, isExecutable()); + editor.execute(command); + + EncapsulatedClassifier partType = (EncapsulatedClassifier) part.getType(); + assertThat("No port created", partType.getOwnedAttributes(), hasItem(anything())); + return partType.getOwnedAttributes().get(partType.getOwnedAttributes().size() - 1); + } + + /** + * Obtains a command that creates a port of the specified type at the given {@code mouse} + * location on the given {@code part} in a capsule structure diagram. + * + * @param part + * a capsule-part + * @param mouse + * the mouse location in the diagram (in the diagram's overall coordinate system) + * @param elementTypeID + * the type of port to create + * + * @return the command, or {@code null} if none was provided by the diagram + */ + private Command getCreateCapsulePartCommand(Property part, Point mouse, String elementTypeID) { + EditPart editPart = editor.getActiveDiagram().getChildBySemanticHint(ClassCompositeEditPart.VISUAL_ID); + assertThat("Class frame not found in diagram", editPart, instanceOf(IGraphicalEditPart.class)); + IGraphicalEditPart classFrame = (IGraphicalEditPart) editPart; + + EditPart underMouse = classFrame.getViewer().findObjectAt(mouse); + + IHintedType typeToCreate = (IHintedType) ElementTypeRegistry.getInstance().getType(elementTypeID); + CreateElementRequest createElement = new CreateElementRequest(part, typeToCreate); + CreateElementRequestAdapter createAdapter = new CreateElementRequestAdapter(createElement); + CreateViewAndElementRequest request = new CreateViewAndElementRequest( + new CreateViewAndElementRequest.ViewAndElementDescriptor( + createAdapter, Node.class, typeToCreate.getSemanticHint(), editor.getPreferencesHint())); + request.setType(RequestConstants.REQ_CREATE); + request.setLocation(mouse); + EditPart target = getTargetEditPart(underMouse, request); + + return target.getCommand(request); + } + + public RelativePortLocation getRelativeLocation(EditPart port) { + IGraphicalEditPart editPart = (IGraphicalEditPart) port; + IGraphicalEditPart parent = (IGraphicalEditPart) port.getParent(); + + Rectangle portBounds = editPart.getFigure().getBounds().getCopy(); + Rectangle parentBounds = parent.getFigure().getBounds(); + portBounds.translate(parentBounds.getLocation().getNegated()); + + return RelativePortLocation.of(portBounds, parentBounds); + } + + public Property dropCapsule(Point mouse, String capsuleTypeName) { + return dropCapsule(mouse, capsuleName, capsuleTypeName); + } + + public Property dropCapsule(Point mouse, String capsuleName, String capsuleTypeName) { + org.eclipse.uml2.uml.Class capsule = (Class) editor.getModel().getOwnedType( + capsuleName, false, UMLPackage.Literals.CLASS, false); + + org.eclipse.uml2.uml.Class capsuleType = (org.eclipse.uml2.uml.Class) editor.getModel().getOwnedType(capsuleTypeName); + + Command command = getDropCapsuleCommand(capsule, mouse, capsuleType); + assertThat("No executable drop command obtained from diagram", command, isExecutable()); + editor.execute(command); + + assertThat("No capsule Part created", capsule.getOwnedAttributes(), hasItem(anything())); + return capsule.getOwnedAttributes().get(capsule.getOwnedAttributes().size() - 1); + } + + /** + * Obtains a command that drops a {@code protocol} at the given {@code mouse} + * location on the given {@code part} in a capsule structure diagram. + * + * @param part + * a capsule-part + * @param mouse + * the mouse location in the diagram (in the diagram's overall coordinate system) + * @param protocol + * the protocol to drop + * + * @return the command, or {@code null} if none was provided by the diagram + */ + private Command getDropCapsuleCommand(org.eclipse.uml2.uml.Class capsule, Point mouse, org.eclipse.uml2.uml.Class capsuleType) { + return getDropCapsulesCommand(capsule, mouse, Collections.singletonList(capsuleType)); + } + + private Command getDropCapsulesCommand(org.eclipse.uml2.uml.Class capsule, Point mouse, List<? extends org.eclipse.uml2.uml.Class> capsuleTypes) { + EditPart editPart = editor.getActiveDiagram().getChildBySemanticHint(ClassCompositeEditPart.VISUAL_ID); + assertThat("Class frame not found in diagram", editPart, instanceOf(IGraphicalEditPart.class)); + IGraphicalEditPart classFrame = (IGraphicalEditPart) editPart; + + EditPart underMouse = classFrame.getViewer().findObjectAt(mouse); + + + DropObjectsRequest request = new DropObjectsRequest(); + request.setLocation(mouse); + request.setObjects(capsuleTypes); + + EditPart target = getTargetEditPart(underMouse, request); + return target.getCommand(request); + } + + protected EditPart getTargetEditPart(EditPart editPart, Request request) { + EditPart result = editPart; + + // Drill through text compartments + while (result instanceof ITextAwareEditPart) { + result = result.getParent(); + } + + result = result.getTargetEditPart(request); + + return result; + } + + public List<Property> dropCapsules(Point mouse, List<String> capsuleNames) { + return dropCapsules(mouse, capsuleName, partName, capsuleNames); + } + + public List<Property> dropCapsules(Point mouse, String capsuleName, String partName, List<String> capsuleNames) { + Class capsule = (Class) editor.getModel().getOwnedType( + capsuleName, false, UMLPackage.Literals.CLASS, false); + + List<Class> capsuleTypes = capsuleNames.stream() + .map(this::getCapsule) + .collect(Collectors.toList()); + + int initialPartsCount = capsule.getOwnedAttributes().size(); + + Command command = getDropCapsulesCommand(capsule, mouse, capsuleTypes); + assertThat("No executable drop command obtained from diagram", command, isExecutable()); + editor.execute(command); + + assertThat("No ports created", capsule.getOwnedAttributes().size(), greaterThan(initialPartsCount)); + return new ArrayList<>(capsule.getOwnedAttributes().subList(initialPartsCount, capsule.getOwnedAttributes().size())); + } + + private Class getCapsule(String name) { + return (Class) editor.getModel().getOwnedType( + name, false, UMLPackage.Literals.CLASS, false); + } + + public void assertCannotDropCapsule(Point mouse, String protocolName) { + assertCannotDropCapsule(mouse, capsuleName, partName, protocolName); + } + + public void assertCannotDropCapsule(Point mouse, String capsuleName, String partName, String capsuleTypeName) { + Class capsule = (Class) editor.getModel().getOwnedType( + capsuleName, false, UMLPackage.Literals.CLASS, false); + + Class capsuleType = (Class) editor.getModel().getOwnedType(capsuleTypeName); + + Command command = getDropCapsuleCommand(capsule, mouse, capsuleType); + assertThat("An executable drop command was provided", command, not(isExecutable())); + } +} diff --git a/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editpolicies/tests/PortEditingFixture.java b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editpolicies/tests/PortEditingFixture.java index 956427d79..819557d91 100644 --- a/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editpolicies/tests/PortEditingFixture.java +++ b/tests/junit/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common.tests/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/editpolicies/tests/PortEditingFixture.java @@ -44,10 +44,8 @@ import org.eclipse.gmf.runtime.notation.LayoutConstraint; import org.eclipse.gmf.runtime.notation.Location; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.View; -import org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy; import org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture; import org.eclipse.papyrus.uml.diagram.composite.edit.parts.ClassCompositeEditPart; -import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.drop.ProtocolToPortOnPartDropStrategy; import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.internal.utils.RelativePortLocation; import org.eclipse.uml2.uml.Collaboration; import org.eclipse.uml2.uml.EncapsulatedClassifier; @@ -279,13 +277,14 @@ public class PortEditingFixture { EditPart underMouse = classFrame.getViewer().findObjectAt(mouse); - DropStrategy drop = new ProtocolToPortOnPartDropStrategy(); + + // DropStrategy drop = new ProtocolToPortOnPartDropStrategy(); DropObjectsRequest request = new DropObjectsRequest(); request.setLocation(mouse); request.setObjects(protocols); EditPart target = getTargetEditPart(underMouse, request); - return drop.getCommand(request, target); + return target.getCommand(request); } protected EditPart getTargetEditPart(EditPart editPart, Request request) { |
