diff options
9 files changed, 184 insertions, 18 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/activitygroup/editpolicy/InterruptibleActivityRegionCompartmentCreationEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/activitygroup/editpolicy/InterruptibleActivityRegionCompartmentCreationEditPolicy.java new file mode 100644 index 00000000000..d5781d9e148 --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/custom-src/org/eclipse/papyrus/uml/diagram/activity/activitygroup/editpolicy/InterruptibleActivityRegionCompartmentCreationEditPolicy.java @@ -0,0 +1,27 @@ +package org.eclipse.papyrus.uml.diagram.activity.activitygroup.editpolicy; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.papyrus.uml.diagram.common.editpolicies.PapyrusCreationEditPolicy; +import org.eclipse.uml2.uml.Activity; +import org.eclipse.uml2.uml.InterruptibleActivityRegion; + + +public class InterruptibleActivityRegionCompartmentCreationEditPolicy extends PapyrusCreationEditPolicy { + + /** + * Elements graphically shown inside partitions are semantically owned by the activity. + * So default reparenting check (of different semantic containers) should be skipped for partition contents. + */ + @Override + protected boolean shouldReparent(EObject element, EObject newContext) { + if (isInInterruptibleActivityRegionReparent(element, newContext)) + return element != null && + element != newContext; + return super.shouldReparent(element, newContext); + } + + private boolean isInInterruptibleActivityRegionReparent(EObject element, EObject newContext) { + return newContext instanceof InterruptibleActivityRegion && element.eContainer() instanceof Activity; + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/model/activityDiagram.gmfgen b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/model/activityDiagram.gmfgen index 6cee2377e45..a003a279c10 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/model/activityDiagram.gmfgen +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/model/activityDiagram.gmfgen @@ -3608,6 +3608,7 @@ <behaviour xsi:type="gmfgen:CustomBehaviour" key=""RemoveOrphanView"" editPolicyQualifiedClassName="org.eclipse.papyrus.uml.diagram.activity.edit.policies.RemoveOrphanViewPolicy"/> <behaviour xsi:type="gmfgen:CustomBehaviour" key="org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles.SEMANTIC_ROLE" editPolicyQualifiedClassName="org.eclipse.papyrus.uml.diagram.activity.edit.policies.CustomInterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentItemSemanticEditPolicy"/> <behaviour xsi:type="gmfgen:CustomBehaviour" key="org.eclipse.gef.EditPolicy.GRAPHICAL_NODE_ROLE" editPolicyQualifiedClassName="org.eclipse.papyrus.uml.diagram.common.editpolicies.CustomContainerEditPolicy"/> + <behaviour xsi:type="gmfgen:CustomBehaviour" key="org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles.CREATION_ROLE" editPolicyQualifiedClassName="org.eclipse.papyrus.uml.diagram.activity.activitygroup.editpolicy.InterruptibleActivityRegionCompartmentCreationEditPolicy"/> </compartments> <compartments visualID="7014" editPartClassName="ActivityCNParametersCompartmentEditPart" itemSemanticEditPolicyClassName="ActivityCNParametersCompartmentItemSemanticEditPolicy" notationViewFactoryClassName="ActivityActivityParametersCompartmentViewFactory" canonicalEditPolicyClassName="ActivityCNParametersCompartmentCanonicalEditPolicy" childNodes="/0/@diagram/@childNodes.0" title="ActivityFigureParameterCompartment" canCollapse="false" needsTitle="false" node="/0/@diagram/@childNodes.72"> <diagramRunTimeClass href="../../../plugin/org.eclipse.gmf.runtime.notation/model/notation.genmodel#//notation/Node"/> diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/src/org/eclipse/papyrus/uml/diagram/activity/edit/parts/InterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentEditPart.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/src/org/eclipse/papyrus/uml/diagram/activity/edit/parts/InterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentEditPart.java index 7d5062b6b48..613e9aa1b1f 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/src/org/eclipse/papyrus/uml/diagram/activity/edit/parts/InterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentEditPart.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity/src/org/eclipse/papyrus/uml/diagram/activity/edit/parts/InterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentEditPart.java @@ -28,6 +28,7 @@ import org.eclipse.gmf.runtime.diagram.ui.figures.ResizableCompartmentFigure; import org.eclipse.gmf.runtime.draw2d.ui.figures.ConstrainedToolbarLayout;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.uml.diagram.activity.activitygroup.editpolicy.InterruptibleActivityRegionCompartmentCreationEditPolicy;
import org.eclipse.papyrus.uml.diagram.activity.edit.policies.ActivityGroupCustomDragAndDropEditPolicy;
import org.eclipse.papyrus.uml.diagram.activity.edit.policies.CustomInterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentItemSemanticEditPolicy;
import org.eclipse.papyrus.uml.diagram.activity.edit.policies.InterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentItemSemanticEditPolicy;
@@ -92,6 +93,7 @@ public class InterruptibleActivityRegionInterruptibleActivityRegionContentCompar installEditPolicy("RemoveOrphanView", new RemoveOrphanViewPolicy()); //$NON-NLS-1$
installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new CustomInterruptibleActivityRegionInterruptibleActivityRegionContentCompartmentItemSemanticEditPolicy());
installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new CustomContainerEditPolicy());
+ installEditPolicy(EditPolicyRoles.CREATION_ROLE, new InterruptibleActivityRegionCompartmentCreationEditPolicy());
}
/**
diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/plugin.xml b/plugins/uml/org.eclipse.papyrus.uml.service.types/plugin.xml index eddb2e4315b..316550a583c 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/plugin.xml +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/plugin.xml @@ -980,7 +980,8 @@ <metamodelType id="org.eclipse.papyrus.uml.InterruptibleActivityRegion" name="UML::InterruptibleActivityRegion" eclass="InterruptibleActivityRegion" icon="platform:/plugin/org.eclipse.uml2.uml.edit/icons/full/obj16/InterruptibleActivityRegion.gif" - kind="org.eclipse.gmf.runtime.emf.type.core.IHintedType" > + kind="org.eclipse.gmf.runtime.emf.type.core.IHintedType" + edithelper="org.eclipse.papyrus.uml.service.types.helper.InterruptibleActivityRegionHelper"> <param name="semanticHint" value="UML::InterruptibleActivityRegion"/> </metamodelType> diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/command/PartitionMoveCommand.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/command/NotContainmentMoveCommand.java index fee89cfc39e..951f5ee50f9 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/command/PartitionMoveCommand.java +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/command/NotContainmentMoveCommand.java @@ -10,19 +10,24 @@ import org.eclipse.gmf.runtime.emf.type.core.commands.MoveElementsCommand; import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest; /** - * All ActivityPartition semantic children containment Activity. - * Standard command cannot move ActivityPartition children to Activity or - * Activity children to ActivityPartition because command move children - * only from one parent to another. - * + * This command handles the move of the elements from the graphical containers different from + * semantic containers. Examples are {@link ActivityPartition} or + * {@link InterruptibleActivityRegion} which both graphically contains nodes semantically + * contained in {@link Activity}. + * <p/> + * Standard {@link MoveElementsCommand} does not work for these cases because it moves children + * only from one semantic container to another. + * <p/> + * So the main purpose of this command is to override useless check of different source and target + * semantic containers in {@link #canExecute()} method. */ -public class PartitionMoveCommand extends MoveElementsCommand { +public class NotContainmentMoveCommand extends MoveElementsCommand { /** * Default constructor * @param request */ - public PartitionMoveCommand(MoveRequest request) { + public NotContainmentMoveCommand(MoveRequest request) { super(request); } diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ActivityHelper.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ActivityHelper.java index 6531c85180d..db808c8a724 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ActivityHelper.java +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ActivityHelper.java @@ -15,14 +15,14 @@ package org.eclipse.papyrus.uml.service.types.helper; import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest;
-import org.eclipse.papyrus.uml.service.types.command.PartitionMoveCommand;
+import org.eclipse.papyrus.uml.service.types.command.NotContainmentMoveCommand;
public class ActivityHelper extends ElementEditHelper {
@Override
protected ICommand getMoveCommand(MoveRequest req) {
- return new PartitionMoveCommand(req);
+ return new NotContainmentMoveCommand(req);
}
// {
diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ActivityNodeHelper.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ActivityNodeHelper.java index 62fe898886f..c6bd8c158bb 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ActivityNodeHelper.java +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/ActivityNodeHelper.java @@ -33,7 +33,7 @@ import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
-import org.eclipse.papyrus.uml.service.types.command.PartitionMoveCommand;
+import org.eclipse.papyrus.uml.service.types.command.NotContainmentMoveCommand;
import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.ActivityPartition;
@@ -52,6 +52,8 @@ public class ActivityNodeHelper extends ElementEditHelper { */
public static final String IN_PARTITION = "IN_PARTITION";
+ public static final String IN_INTERRUPTIBLE_ACTIVITY_REGION = "IN_INTERRUPTIBLE_ACTIVITY_REGION";
+
@Override
protected ICommand getBasicDestroyElementCommand(DestroyElementRequest req) {
ICommand result = new DestroyActivityNode(req);
@@ -65,7 +67,7 @@ public class ActivityNodeHelper extends ElementEditHelper { if (req.getTargetContainer() instanceof ActivityPartition) {
ActivityPartition partition = (ActivityPartition)req.getTargetContainer();
CompositeCommand result = new CompositeCommand("Move elements in Partition");
- MoveElementsCommand moveCommand = new PartitionMoveCommand(createMoveToPartitionRequest(req));
+ MoveElementsCommand moveCommand = new NotContainmentMoveCommand(createMoveToPartitionRequest(req));
result.add(moveCommand);
for (Object o: req.getElementsToMove().keySet()) {
result.add(new SetValueCommand(new SetRequest(partition, UMLPackage.eINSTANCE.getActivityPartition_Node(), o)));
@@ -127,6 +129,14 @@ public class ActivityNodeHelper extends ElementEditHelper { return UMLPackage.eINSTANCE.getActivity_OwnedNode();
}
+ @Override
+ protected ICommand getConfigureCommand(ConfigureRequest req) {
+ if (req.getParameter(IN_INTERRUPTIBLE_ACTIVITY_REGION) != null) {
+ return new SetValueCommand(new SetRequest((EObject)req.getParameter(IN_INTERRUPTIBLE_ACTIVITY_REGION),UMLPackage.eINSTANCE.getInterruptibleActivityRegion_Node(), req.getElementToConfigure()));
+ }
+ return super.getConfigureCommand(req);
+ }
+
/**
* inner class for the destruction of element
*
diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/InterruptibleActivityRegionHelper.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/InterruptibleActivityRegionHelper.java new file mode 100644 index 00000000000..d72b16e195a --- /dev/null +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/InterruptibleActivityRegionHelper.java @@ -0,0 +1,116 @@ +package org.eclipse.papyrus.uml.service.types.helper; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.edit.command.MoveCommand; +import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; +import org.eclipse.gmf.runtime.common.core.command.ICommand; +import org.eclipse.gmf.runtime.emf.type.core.IElementType; +import org.eclipse.gmf.runtime.emf.type.core.commands.MoveElementsCommand; +import org.eclipse.gmf.runtime.emf.type.core.commands.SetValueCommand; +import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest; +import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest; +import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest; +import org.eclipse.papyrus.uml.service.types.command.NotContainmentMoveCommand; +import org.eclipse.uml2.uml.Activity; +import org.eclipse.uml2.uml.ActivityNode; +import org.eclipse.uml2.uml.InterruptibleActivityRegion; +import org.eclipse.uml2.uml.UMLPackage; + +public class InterruptibleActivityRegionHelper extends ActivityGroupHelper { + + @Override + protected ICommand getCreateCommand(CreateElementRequest req) { + CreateElementRequest createRequest = isActivityNode(req.getElementType()) ? initCreateActivityNodeRequestInInterruptibleRegion(req) : req; + return super.getCreateCommand(createRequest); + } + + /** + * {@link InterruptibleActivityRegion} cannot contain any {@link ActivityNode}. + * That's why we create new element in {@link Activity} and added it to {@link InterruptibleActivityRegion#getNodes()} referenced list + * + * @param baseReq {@link CreateElementRequest} from ItemSemanticEditPolicy with not containment {@link InterruptibleActivityRegion#getNodes()} feature + * @return new {@link CreateElementRequest} with {@link Activity} as container and right containment {@link ActivityNode} feature + */ + protected CreateElementRequest initCreateActivityNodeRequestInInterruptibleRegion(CreateElementRequest baseReq) { + if (baseReq == null) { + return null; + } + CreateElementRequest req = new CreateElementRequest(baseReq.getElementType()); + InterruptibleActivityRegion inrruptibleActivityRegion = ((InterruptibleActivityRegion)baseReq.getContainer()); + req.setContainer(inrruptibleActivityRegion.getInActivity()); + req.setContainmentFeature(findActivityFeature(baseReq.getElementType().getEClass())); + req.setParameter(ActivityNodeHelper.IN_INTERRUPTIBLE_ACTIVITY_REGION, inrruptibleActivityRegion); + return req; + } + + /** + * Find {@link Activity} feature appropriate to {@link InterruptibleActivityRegion} feature. + * + * @return Appropriate feature. + */ + protected EReference findActivityFeature(EClass eClass) { + if (UMLPackage.eINSTANCE.getStructuredActivityNode().isSuperTypeOf(eClass)) { + return UMLPackage.eINSTANCE.getActivity_StructuredNode(); + } + return UMLPackage.eINSTANCE.getActivity_OwnedNode(); + } + + private boolean isActivityNode(IElementType type) { + return UMLPackage.eINSTANCE.getActivityNode().isSuperTypeOf(type.getEClass()); + } + + @Override + protected ICommand getMoveCommand(MoveRequest req) { + if (req != null) { + if (isTargetContainerInterruptibleActivityRegioin(req)) { + return createMoveCommandWithSetReference(req, UMLPackage.eINSTANCE.getInterruptibleActivityRegion_Node()); + } + } + return super.getMoveCommand(req); + } + + private boolean isTargetContainerInterruptibleActivityRegioin(MoveRequest req) { + return req.getTargetContainer() instanceof InterruptibleActivityRegion; + } + + /** + * This method create {@link CompositeCommand}. It contain redirected {@link MoveCommand} to Activity + * and commands to set references on ActivityNodes for base container which can't contain they. + * + * @param req base {@MoveRequest} + * @param featureToSetReference {@link EReference} to set {@link ActivityNode} in base request target container's referenced list + * @return {@link CompositeCommand} which contain {@link MoveCommand} elements to Activity and {@link SetValueCommand}s to base container's referenced list + */ + protected ICommand createMoveCommandWithSetReference(MoveRequest req, EReference featureToSetReference) { + EObject nonContainmentContainer = (EObject)req.getTargetContainer(); + CompositeCommand result = new CompositeCommand("Move elements in non containment Activity container"); + MoveElementsCommand moveCommand = new NotContainmentMoveCommand(createMoveToActivityRequest(req)); + result.add(moveCommand); + for (Object o: req.getElementsToMove().keySet()) { + if (o instanceof ActivityNode) { + result.add(new SetValueCommand(new SetRequest(nonContainmentContainer, featureToSetReference, o))); + } + } + return result; + } + + /** + * @param base move request in which target container can't contain {@link ActivityNode} + * @return {@link MoveRequest} in which replaced base container on {@link Activity}and replaced containment features for it. + */ + protected MoveRequest createMoveToActivityRequest(MoveRequest baseReq) { + if (baseReq == null) { + return null; + } + MoveRequest result = new MoveRequest(baseReq.getEditingDomain(), ((InterruptibleActivityRegion)(baseReq.getTargetContainer())).getInActivity(), baseReq.getElementsToMove()); + for (Object o : baseReq.getElementsToMove().keySet()) { + if (o instanceof ActivityNode) { + ActivityNode node = (ActivityNode)o; + result.setTargetFeature(node ,findActivityFeature(node.eClass())); + } + } + return result; + } +} diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity.tests/src/org/eclipse/papyrus/uml/diagram/activity/tests/canonical/TestActivityGroup.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity.tests/src/org/eclipse/papyrus/uml/diagram/activity/tests/canonical/TestActivityGroup.java index 25d4ba623a0..cfa29900bea 100644 --- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity.tests/src/org/eclipse/papyrus/uml/diagram/activity/tests/canonical/TestActivityGroup.java +++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.activity.tests/src/org/eclipse/papyrus/uml/diagram/activity/tests/canonical/TestActivityGroup.java @@ -56,12 +56,18 @@ import org.junit.Assert; import org.junit.Test; /** - * This class test graphical and semantic part of {@link ActivityGroup} elements: {@link StructuredActivityNode} {@link ConditionalNode} - * {@link ExpansionRegion} {@link LoopNode} {@link SequenceNode} {@link InterruptibleActivityRegion} {@link ActivityPartition} + * This class test graphical and semantic part of {@link ActivityGroup} elements: + * {@link StructuredActivityNode} + * {@link ConditionalNode} + * {@link ExpansionRegion} + * {@link LoopNode} + * {@link SequenceNode} + * {@link InterruptibleActivityRegion} + * {@link ActivityPartition} * * For each {@link ActivityGroup} elements test: - * 1) created child {@link ActivityNode} in {@link ActivityGroup} and drag-drop child to {@link Activity} 2) created child {@link ActivityNode} in - * {@link Activity} and drag-drop child to {@link ActivityGroup} element + * 1) created child {@link ActivityNode} in {@link ActivityGroup} and drag-drop child to {@link Activity} + * 2) created child {@link ActivityNode} in {@link Activity} and drag-drop child to {@link ActivityGroup} element */ public class TestActivityGroup extends AbstractPapyrusTestCase { @@ -103,7 +109,6 @@ public class TestActivityGroup extends AbstractPapyrusTestCase { return findChildBySemanticHint(activityEP, ActivityActivityContentCompartmentEditPart.VISUAL_ID); } - @FailingTest("Bug 440239") @Test public void testFromInterruptibleActivityRegionToActivity() { IGraphicalEditPart regionEP = createChild(InterruptibleActivityRegionEditPart.VISUAL_ID, getActivityCompartmentEditPart()); @@ -114,7 +119,6 @@ public class TestActivityGroup extends AbstractPapyrusTestCase { dd.doTest(); } - @FailingTest("Bug 440239") @Test public void testFromActivityToInterruptibleActivityRegion() { IGraphicalEditPart regionEP = createChild(InterruptibleActivityRegionEditPart.VISUAL_ID, getActivityCompartmentEditPart()); |