diff options
9 files changed, 440 insertions, 17 deletions
diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations b/plugins/uml/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations index b18c277ad2c..b48435ad8b1 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations @@ -1171,6 +1171,6 @@ <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_sk_AgANEEeeK2pILzAGx9w" identifier="org.eclipse.papyrus.uml.advice.Element" target="org.eclipse.papyrus.uml.Element" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrus.uml.service.types.helper.advice.ElementHelperAdvice"/> <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_pUAxYDKLEee2hdQGBOZDMQ" identifier="org.eclipse.papyrus.uml.advice.DurationConstraint" target="org.eclipse.papyrus.uml.DurationConstraint" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrus.uml.service.types.helper.advice.DurationConstraintEditHelperAdvice"/> <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_RDj3kHOtEeer__BSotNaQg" identifier="org.eclipse.papyrus.uml.advice.CombinedFragment" target="org.eclipse.papyrus.uml.CombinedFragment" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrus.uml.service.types.helper.advice.CombinedFragmentEditHelperAdvice"/> - <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_U6DhsETXEeimO7ZhVBpjkg" identifier="org.eclipse.papyrus.uml.advice.InteractionOperand" target="org.eclipse.papyrus.uml.InteractionOperand" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrus.uml.service.types.helper.advice.InteractionFragmentContainerEditHelperAdvice"/> + <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_U6DhsETXEeimO7ZhVBpjkg" identifier="org.eclipse.papyrus.uml.advice.InteractionOperand" target="org.eclipse.papyrus.uml.InteractionOperand" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrus.uml.service.types.helper.advice.InteractionOperandEditHelperAdvice"/> <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_VVC0kETXEeimO7ZhVBpjkg" identifier="org.eclipse.papyrus.uml.advice.Interaction" target="org.eclipse.papyrus.uml.Interaction" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrus.uml.service.types.helper.advice.InteractionFragmentContainerEditHelperAdvice"/> </elementtypesconfigurations:ElementTypeSetConfiguration> diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionContainerDeletionContext.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionContainerDeletionContext.java index 2bf5baa1eb5..8f2f122c2a0 100644 --- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionContainerDeletionContext.java +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionContainerDeletionContext.java @@ -29,7 +29,9 @@ import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; +import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest; +import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyRequest; import org.eclipse.uml2.uml.CombinedFragment; import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.GeneralOrdering; @@ -60,7 +62,7 @@ class InteractionContainerDeletionContext { /** * Initializes me with the initial destroy request. */ - private InteractionContainerDeletionContext(DestroyElementRequest request) { + private InteractionContainerDeletionContext(DestroyRequest request) { super(); this.domain = request.getEditingDomain(); @@ -68,16 +70,24 @@ class InteractionContainerDeletionContext { } static Optional<InteractionContainerDeletionContext> get(DestroyElementRequest request) { + return get(request, request.getElementToDestroy()); + } + + static Optional<InteractionContainerDeletionContext> get(DestroyDependentsRequest request) { + return get(request, request.getElementToDestroy()); + } + + private static Optional<InteractionContainerDeletionContext> get(DestroyRequest request, EObject elementToDestroy) { Optional<InteractionContainerDeletionContext> result = Optional.ofNullable(request.getParameter(PARAMETER_NAME)) .filter(InteractionContainerDeletionContext.class::isInstance) .map(InteractionContainerDeletionContext.class::cast); - if (isInteractionContainer(request.getElementToDestroy())) { + if (isInteractionContainer(elementToDestroy)) { if (!result.isPresent()) { result = Optional.of(new InteractionContainerDeletionContext(request)); } - result.get().add(request); + result.get().add(elementToDestroy); } return result; @@ -96,8 +106,7 @@ class InteractionContainerDeletionContext { || object instanceof Interaction; } - private void add(DestroyElementRequest request) { - EObject elementToDestroy = request.getElementToDestroy(); + private void add(EObject elementToDestroy) { interactionContainersBeingDestroyed.add((InteractionFragment) elementToDestroy); } diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionOperandEditHelperAdvice.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionOperandEditHelperAdvice.java new file mode 100644 index 00000000000..c898ddf5592 --- /dev/null +++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionOperandEditHelperAdvice.java @@ -0,0 +1,68 @@ +/***************************************************************************** + * Copyright (c) 2018 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.papyrus.uml.service.types.helper.advice; + +import static org.eclipse.gmf.runtime.common.core.command.CompositeCommand.compose; + +import java.util.Optional; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gmf.runtime.common.core.command.ICommand; +import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest; +import org.eclipse.uml2.uml.CombinedFragment; +import org.eclipse.uml2.uml.InteractionOperand; + +/** + * Edit-helper advice for {@link InteractionOperand}s. + * + * @since 3.1 + */ +public class InteractionOperandEditHelperAdvice extends InteractionFragmentContainerEditHelperAdvice { + + /** + * Initializes me. + */ + public InteractionOperandEditHelperAdvice() { + super(); + } + + @Override + protected ICommand getAfterDestroyDependentsCommand(DestroyDependentsRequest request) { + ICommand result = super.getAfterDestroyDependentsCommand(request); + + if (request.getElementToDestroy() instanceof InteractionOperand) { + InteractionOperand operand = (InteractionOperand) request.getElementToDestroy(); + CombinedFragment cfrag = (CombinedFragment) operand.getOwner(); + + // Are we deleting all of the operands of this combined fragment? + Optional<InteractionContainerDeletionContext> context = InteractionContainerDeletionContext.get(request); + + result = compose(context.filter(ctx -> deletingAllOperands(ctx, cfrag, request)) + .map(__ -> request.getDestroyDependentCommand(cfrag)) + .orElse(null), result); + } + + return result; + } + + static boolean deletingAllOperands(InteractionContainerDeletionContext ctx, CombinedFragment cfrag, DestroyDependentsRequest req) { + @SuppressWarnings("unchecked") + Set<? extends EObject> destroying = req.getDependentElementsToDestroy(); + + return cfrag.getOperands().stream().allMatch( + operand -> ctx.isBeingDestroyed(operand) || destroying.contains(operand)); + } + +} diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.di b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.di new file mode 100644 index 00000000000..8c549eecdc6 --- /dev/null +++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.di @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<architecture:ArchitectureDescription xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:architecture="http://www.eclipse.org/papyrus/infra/core/architecture" contextId="org.eclipse.papyrus.infra.services.edit.TypeContext"/> diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.notation b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.notation new file mode 100644 index 00000000000..52c39a11fb4 --- /dev/null +++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.notation @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8"?> +<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/gmfdiag/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_QKU0YEMwEeiEZ5Jtfh6-KA" type="PapyrusUMLSequenceDiagram" name="sequence" measurementUnit="Pixel"> + <children xmi:type="notation:Shape" xmi:id="_QKU0YUMwEeiEZ5Jtfh6-KA" type="Interaction_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_QKU0YkMwEeiEZ5Jtfh6-KA" type="Interaction_NameLabel"> + <element xmi:type="uml:Interaction" href="bug533683.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_QKU0Y0MwEeiEZ5Jtfh6-KA" type="Interaction_SubfragmentCompartment"> + <children xmi:type="notation:Shape" xmi:id="_FQ-74ESnEeilLIdbxjHAOw" type="CombinedFragment_Shape"> + <children xmi:type="notation:BasicCompartment" xmi:id="_FRAKAESnEeilLIdbxjHAOw" type="CombinedFragment_SubfragmentCompartment"> + <children xmi:type="notation:Shape" xmi:id="_FRAKBESnEeilLIdbxjHAOw" type="InteractionOperand_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_FRAKBkSnEeilLIdbxjHAOw" type="InteractionOperand_Guard"> + <element xmi:type="uml:InteractionConstraint" href="bug533683.uml#_FQ3nIUSnEeilLIdbxjHAOw"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_FRAKB0SnEeilLIdbxjHAOw" x="5" y="5"/> + </children> + <element xmi:type="uml:InteractionOperand" href="bug533683.uml#_FQ3nIESnEeilLIdbxjHAOw"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_FRAKBUSnEeilLIdbxjHAOw" width="100" height="202"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_kZ88METtEei8-Im8RTxj4A" type="InteractionOperand_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_kZ-KUETtEei8-Im8RTxj4A" type="InteractionOperand_Guard"> + <element xmi:type="uml:InteractionConstraint" href="bug533683.uml#_kZ1AYETtEei8-Im8RTxj4A"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_kZ-xYETtEei8-Im8RTxj4A" x="5" y="5"/> + </children> + <element xmi:type="uml:InteractionOperand" href="bug533683.uml#_kZsdgETtEei8-Im8RTxj4A"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_kZ88MUTtEei8-Im8RTxj4A" y="202" width="100" height="74"/> + </children> + <styles xmi:type="notation:SortingStyle" xmi:id="_FRAKAUSnEeilLIdbxjHAOw"/> + <styles xmi:type="notation:FilteringStyle" xmi:id="_FRAKAkSnEeilLIdbxjHAOw"/> + <element xmi:type="uml:CombinedFragment" href="bug533683.uml#_FQ2ZAESnEeilLIdbxjHAOw"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_FRAKA0SnEeilLIdbxjHAOw"/> + </children> + <element xmi:type="uml:CombinedFragment" href="bug533683.uml#_FQ2ZAESnEeilLIdbxjHAOw"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_FQ-74USnEeilLIdbxjHAOw" x="14" y="40" width="381" height="296"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_RZ4XwEMwEeiEZ5Jtfh6-KA" type="Lifeline_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_RZ4-0EMwEeiEZ5Jtfh6-KA" type="Lifeline_NameLabel"> + <element xmi:type="uml:Lifeline" href="bug533683.uml#_RZwb8EMwEeiEZ5Jtfh6-KA"/> + </children> + <element xmi:type="uml:Lifeline" href="bug533683.uml#_RZwb8EMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_RZ4XwUMwEeiEZ5Jtfh6-KA" x="58" y="10"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_R0X7YEMwEeiEZ5Jtfh6-KA" type="Lifeline_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_R0X7YkMwEeiEZ5Jtfh6-KA" type="Lifeline_NameLabel"> + <element xmi:type="uml:Lifeline" href="bug533683.uml#_R0URAEMwEeiEZ5Jtfh6-KA"/> + </children> + <children xmi:type="notation:BasicCompartment" xmi:id="_R0cM0EMwEeiEZ5Jtfh6-KA" type="compartment_shape_display"> + <styles xmi:type="notation:TitleStyle" xmi:id="_R0cM0UMwEeiEZ5Jtfh6-KA"/> + <element xmi:type="uml:Lifeline" href="bug533683.uml#_R0URAEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_R0cM0kMwEeiEZ5Jtfh6-KA"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_XgABcEMwEeiEZ5Jtfh6-KA" type="BehaviorExecutionSpecification_Shape"> + <children xmi:type="notation:DecorationNode" xmi:id="_XgABckMwEeiEZ5Jtfh6-KA" type="BehaviorExecutionSpecification_Behavior"> + <element xmi:type="uml:BehaviorExecutionSpecification" href="bug533683.uml#_Xf7wAEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Location" xmi:id="_XgAogEMwEeiEZ5Jtfh6-KA" x="18" y="18"/> + </children> + <element xmi:type="uml:BehaviorExecutionSpecification" href="bug533683.uml#_Xf7wAEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XgABcUMwEeiEZ5Jtfh6-KA" x="40" y="90" width="20" height="100"/> + </children> + <children xmi:type="notation:Shape" xmi:id="_n0MOcETtEei8-Im8RTxj4A" type="DestructionOccurrenceSpecification_Shape"> + <element xmi:type="uml:DestructionOccurrenceSpecification" href="bug533683.uml#_nzCX4ETtEei8-Im8RTxj4A"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_n0MOcUTtEei8-Im8RTxj4A" x="57" y="310"/> + </children> + <element xmi:type="uml:Lifeline" href="bug533683.uml#_R0URAEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_R0X7YUMwEeiEZ5Jtfh6-KA" x="237" y="10" height="290"/> + </children> + <element xmi:type="uml:Interaction" href="bug533683.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_QKU0ZEMwEeiEZ5Jtfh6-KA"/> + </children> + <element xmi:type="uml:Interaction" href="bug533683.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Bounds" xmi:id="_QKU0ZUMwEeiEZ5Jtfh6-KA"/> + </children> + <styles xmi:type="notation:StringValueStyle" xmi:id="_QKU0ZkMwEeiEZ5Jtfh6-KA" name="diagram_compatibility_version" stringValue="1.4.0"/> + <styles xmi:type="notation:DiagramStyle" xmi:id="_QKU0Z0MwEeiEZ5Jtfh6-KA"/> + <styles xmi:type="style:PapyrusDiagramStyle" xmi:id="_QKU0aEMwEeiEZ5Jtfh6-KA" diagramKindId="org.eclipse.papyrus.uml.diagram.sequence"> + <owner xmi:type="uml:Class" href="bug533683.uml#_Jqu6wEMwEeiEZ5Jtfh6-KA"/> + </styles> + <element xmi:type="uml:Interaction" href="bug533683.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/> + <edges xmi:type="notation:Connector" xmi:id="_Xfg5QEMwEeiEZ5Jtfh6-KA" type="Message_SynchEdge" source="_RZ4XwEMwEeiEZ5Jtfh6-KA" target="_R0X7YEMwEeiEZ5Jtfh6-KA"> + <children xmi:type="notation:DecorationNode" xmi:id="_Xfg5Q0MwEeiEZ5Jtfh6-KA" type="Message_SynchNameLabel"> + <element xmi:type="uml:Message" href="bug533683.uml#_XfUsAEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Location" xmi:id="_Xfg5REMwEeiEZ5Jtfh6-KA" x="1" y="-13"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_XfhgUEMwEeiEZ5Jtfh6-KA" type="Message_SynchStereotypeLabel"> + <element xmi:type="uml:Message" href="bug533683.uml#_XfUsAEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Location" xmi:id="_XfhgUUMwEeiEZ5Jtfh6-KA" x="1" y="-33"/> + </children> + <styles xmi:type="notation:FontStyle" xmi:id="_Xfg5QUMwEeiEZ5Jtfh6-KA"/> + <styles xmi:type="notation:LineStyle" xmi:id="_XfhgUkMwEeiEZ5Jtfh6-KA"/> + <element xmi:type="uml:Message" href="bug533683.uml#_XfUsAEMwEeiEZ5Jtfh6-KA"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Xfg5QkMwEeiEZ5Jtfh6-KA" points="[0, 0, -179, 0]$[179, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XftGgEMwEeiEZ5Jtfh6-KA" id="(0.5,0.12857142857142856)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XfttkEMwEeiEZ5Jtfh6-KA" id="(0.5,0.3103448275862069)"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_XgIkUEMwEeiEZ5Jtfh6-KA" type="Message_ReplyEdge" source="_R0X7YEMwEeiEZ5Jtfh6-KA" target="_RZ4XwEMwEeiEZ5Jtfh6-KA"> + <children xmi:type="notation:DecorationNode" xmi:id="_XgIkU0MwEeiEZ5Jtfh6-KA" type="Message_ReplyNameLabel"> + <element xmi:type="uml:Message" href="bug533683.uml#_XgGvIEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Location" xmi:id="_XgIkVEMwEeiEZ5Jtfh6-KA" x="1" y="-13"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_XgIkVUMwEeiEZ5Jtfh6-KA" type="Message_ReplyStereotypeLabel"> + <element xmi:type="uml:Message" href="bug533683.uml#_XgGvIEMwEeiEZ5Jtfh6-KA"/> + <layoutConstraint xmi:type="notation:Location" xmi:id="_XgIkVkMwEeiEZ5Jtfh6-KA" x="1" y="-33"/> + </children> + <styles xmi:type="notation:FontStyle" xmi:id="_XgIkUUMwEeiEZ5Jtfh6-KA"/> + <styles xmi:type="notation:LineStyle" xmi:id="_XgIkV0MwEeiEZ5Jtfh6-KA"/> + <element xmi:type="uml:Message" href="bug533683.uml#_XgGvIEMwEeiEZ5Jtfh6-KA"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_XgIkUkMwEeiEZ5Jtfh6-KA" points="[0, 0, 179, 0]$[-179, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XgJycEMwEeiEZ5Jtfh6-KA" id="(0.5,0.6551724137931033)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XgJycUMwEeiEZ5Jtfh6-KA" id="(0.5,0.2714285714285714)"/> + </edges> + <edges xmi:type="notation:Connector" xmi:id="_nzN-EETtEei8-Im8RTxj4A" type="Message_DeleteEdge" source="_RZ4XwEMwEeiEZ5Jtfh6-KA" target="_R0X7YEMwEeiEZ5Jtfh6-KA"> + <children xmi:type="notation:DecorationNode" xmi:id="_nzOlIkTtEei8-Im8RTxj4A" type="Message_DeleteNameLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_nzOlI0TtEei8-Im8RTxj4A" x="1" y="-13"/> + </children> + <children xmi:type="notation:DecorationNode" xmi:id="_nzOlJETtEei8-Im8RTxj4A" type="Message_DeleteStereotypeLabel"> + <layoutConstraint xmi:type="notation:Location" xmi:id="_nzOlJUTtEei8-Im8RTxj4A" x="1" y="-33"/> + </children> + <styles xmi:type="notation:FontStyle" xmi:id="_nzOlIETtEei8-Im8RTxj4A"/> + <styles xmi:type="notation:LineStyle" xmi:id="_nzOlJkTtEei8-Im8RTxj4A"/> + <element xmi:type="uml:Message" href="bug533683.uml#_ny3_0ETtEei8-Im8RTxj4A"/> + <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_nzOlIUTtEei8-Im8RTxj4A" points="[0, 0, -179, 0]$[179, 0, 0, 0]"/> + <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_nztGQETtEei8-Im8RTxj4A" id="(0.5,0.4142857142857143)"/> + <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_nztGQUTtEei8-Im8RTxj4A" id="(0.5,1.0)"/> + </edges> +</notation:Diagram> diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.uml b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.uml new file mode 100644 index 00000000000..84e052969a4 --- /dev/null +++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533683.uml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_HWN6cEMwEeiEZ5Jtfh6-KA" name="bug533673"> + <packageImport xmi:type="uml:PackageImport" xmi:id="_HeHSMEMwEeiEZ5Jtfh6-KA"> + <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/> + </packageImport> + <packagedElement xmi:type="uml:Class" xmi:id="_Jqu6wEMwEeiEZ5Jtfh6-KA" name="Foo" classifierBehavior="_POkWwEMwEeiEZ5Jtfh6-KA"> + <ownedAttribute xmi:type="uml:Property" xmi:id="_LwEPkEMwEeiEZ5Jtfh6-KA" name="a"/> + <ownedAttribute xmi:type="uml:Property" xmi:id="_M6OVkEMwEeiEZ5Jtfh6-KA" name="b"/> + <ownedBehavior xmi:type="uml:Interaction" xmi:id="_POkWwEMwEeiEZ5Jtfh6-KA" name="DoIt"> + <lifeline xmi:type="uml:Lifeline" xmi:id="_RZwb8EMwEeiEZ5Jtfh6-KA" name="a" represents="_LwEPkEMwEeiEZ5Jtfh6-KA" coveredBy="_FQ3nIESnEeilLIdbxjHAOw _kZsdgETtEei8-Im8RTxj4A _XfZkgEMwEeiEZ5Jtfh6-KA _XgH9QEMwEeiEZ5Jtfh6-KA _ny_UkETtEei8-Im8RTxj4A _FQ2ZAESnEeilLIdbxjHAOw"/> + <lifeline xmi:type="uml:Lifeline" xmi:id="_R0URAEMwEeiEZ5Jtfh6-KA" name="b" represents="_M6OVkEMwEeiEZ5Jtfh6-KA" coveredBy="_FQ3nIESnEeilLIdbxjHAOw _kZsdgETtEei8-Im8RTxj4A _XfaLkEMwEeiEZ5Jtfh6-KA _XgHWMEMwEeiEZ5Jtfh6-KA _nzCX4ETtEei8-Im8RTxj4A _Xf7wAEMwEeiEZ5Jtfh6-KA _FQ2ZAESnEeilLIdbxjHAOw"/> + <fragment xmi:type="uml:CombinedFragment" xmi:id="_FQ2ZAESnEeilLIdbxjHAOw" name="cfrag" covered="_RZwb8EMwEeiEZ5Jtfh6-KA _R0URAEMwEeiEZ5Jtfh6-KA" interactionOperator="alt"> + <operand xmi:type="uml:InteractionOperand" xmi:id="_FQ3nIESnEeilLIdbxjHAOw" name="alt1" covered="_RZwb8EMwEeiEZ5Jtfh6-KA _R0URAEMwEeiEZ5Jtfh6-KA"> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XfZkgEMwEeiEZ5Jtfh6-KA" name="request-send" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_XfUsAEMwEeiEZ5Jtfh6-KA"/> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XfaLkEMwEeiEZ5Jtfh6-KA" name="request-recv" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_XfUsAEMwEeiEZ5Jtfh6-KA"/> + <fragment xmi:type="uml:BehaviorExecutionSpecification" xmi:id="_Xf7wAEMwEeiEZ5Jtfh6-KA" name="exec" covered="_R0URAEMwEeiEZ5Jtfh6-KA" finish="_XgHWMEMwEeiEZ5Jtfh6-KA" start="_XfaLkEMwEeiEZ5Jtfh6-KA"/> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XgHWMEMwEeiEZ5Jtfh6-KA" name="reply-send" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_XgGvIEMwEeiEZ5Jtfh6-KA"/> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XgH9QEMwEeiEZ5Jtfh6-KA" name="reply-recv" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_XgGvIEMwEeiEZ5Jtfh6-KA"/> + <guard xmi:type="uml:InteractionConstraint" xmi:id="_FQ3nIUSnEeilLIdbxjHAOw" name="guard"/> + </operand> + <operand xmi:type="uml:InteractionOperand" xmi:id="_kZsdgETtEei8-Im8RTxj4A" name="alt2" covered="_RZwb8EMwEeiEZ5Jtfh6-KA _R0URAEMwEeiEZ5Jtfh6-KA"> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_ny_UkETtEei8-Im8RTxj4A" name="delete-send" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_ny3_0ETtEei8-Im8RTxj4A"/> + <fragment xmi:type="uml:DestructionOccurrenceSpecification" xmi:id="_nzCX4ETtEei8-Im8RTxj4A" name="deleted" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_ny3_0ETtEei8-Im8RTxj4A"/> + <guard xmi:type="uml:InteractionConstraint" xmi:id="_kZ1AYETtEei8-Im8RTxj4A" name="guard"/> + </operand> + </fragment> + <message xmi:type="uml:Message" xmi:id="_XfUsAEMwEeiEZ5Jtfh6-KA" name="request" receiveEvent="_XfaLkEMwEeiEZ5Jtfh6-KA" sendEvent="_XfZkgEMwEeiEZ5Jtfh6-KA"/> + <message xmi:type="uml:Message" xmi:id="_XgGvIEMwEeiEZ5Jtfh6-KA" messageSort="reply" receiveEvent="_XgH9QEMwEeiEZ5Jtfh6-KA" sendEvent="_XgHWMEMwEeiEZ5Jtfh6-KA"/> + <message xmi:type="uml:Message" xmi:id="_ny3_0ETtEei8-Im8RTxj4A" name="delete" messageSort="deleteMessage" receiveEvent="_nzCX4ETtEei8-Im8RTxj4A" sendEvent="_ny_UkETtEei8-Im8RTxj4A"/> + </ownedBehavior> + </packagedElement> +</uml:Model> diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java index 4a3f0f92eda..d6263afc498 100644 --- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java +++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java @@ -20,6 +20,7 @@ import static org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture.sized; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; @@ -54,6 +55,7 @@ import org.junit.Test; * @author Christian W. Damus * @see <a href="http://eclip.se/533670">bug 533670</a> */ +@ActiveDiagram("sequence") public class CombinedFragmentRegressionTest extends AbstractPapyrusTest { @Rule @@ -72,7 +74,6 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest { */ @Test @PluginResource("resource/bugs/bug533673.di") - @ActiveDiagram("sequence") public void defaultInteractionOperand_533673() { EditPart interactionEP = editor.findEditPart("DoIt", Interaction.class); EditPart interactionCompartment = editor.getShapeCompartment(interactionEP); @@ -121,7 +122,6 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest { */ @Test @PluginResource("resource/bugs/bug533682.di") - @ActiveDiagram("sequence") public void deleteInteractionOperand() { EditPart combinedFragmentEP = editor.findEditPart("cfrag", CombinedFragment.class); CombinedFragment cfrag = (CombinedFragment) combinedFragmentEP.getAdapter(EObject.class); @@ -155,7 +155,6 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest { */ @Test @PluginResource("resource/bugs/bug533682.di") - @ActiveDiagram("sequence") public void deleteCombinedFragment() { EditPart combinedFragmentEP = editor.findEditPart("cfrag", CombinedFragment.class); CombinedFragment cfrag = (CombinedFragment) combinedFragmentEP.getAdapter(EObject.class); @@ -182,7 +181,6 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest { */ @Test @PluginResource("resource/bugs/bug533682.di") - @ActiveDiagram("sequence") public void deleteInteractionFragmentInOperand() { EditPart combinedFragmentEP = editor.findEditPart("cfrag", CombinedFragment.class); CombinedFragment cfrag = (CombinedFragment) combinedFragmentEP.getAdapter(EObject.class); @@ -210,7 +208,6 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest { */ @Test @PluginResource("resource/bugs/bug533682.di") - @ActiveDiagram("sequence") public void deleteInteraction() { EditPart combinedFragmentEP = editor.findEditPart("cfrag", CombinedFragment.class); CombinedFragment cfrag = (CombinedFragment) combinedFragmentEP.getAdapter(EObject.class); @@ -227,4 +224,62 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest { assertThat("Execution specification not deleted", exec.eResource(), nullValue()); assertThat("Interaction not deleted", interaction.eResource(), nullValue()); } + + /** + * Verify that the deletion of the only (or last remaining) interaction operand + * in a combined fragment results in deletion of the combined fragment, also. + * + * @see <a href="http://eclip.se/533683">bug 533683</a> + */ + @Test + @PluginResource("resource/bugs/bug533682.di") + public void deleteOnlyInteractionOperand() { + EditPart combinedFragmentEP = editor.findEditPart("cfrag", CombinedFragment.class); + CombinedFragment cfrag = (CombinedFragment) combinedFragmentEP.getAdapter(EObject.class); + Interaction interaction = cfrag.getEnclosingInteraction(); + assumeThat("No interaction", interaction, notNullValue()); + + InteractionOperand operand = cfrag.getOperands().get(0); + EditPart operandEP = editor.requireEditPart(combinedFragmentEP, operand); + + editor.delete(operandEP); + + combinedFragmentEP = editor.findEditPart(cfrag); + + assertThat("Combined fragment not deleted", cfrag.eResource(), nullValue()); + assertThat("Combined fragment still presented in diagram", combinedFragmentEP, nullValue()); + } + + /** + * Verify that the deletion of an interaction operand that leaves at least one + * remaining in a combined fragment does not result in deletion of the combined fragment. + * + * @see <a href="http://eclip.se/533683">bug 533683</a> + */ + @Test + @PluginResource("resource/bugs/bug533683.di") + public void deleteNotOnlyInteractionOperand() { + EditPart combinedFragmentEP = editor.findEditPart("cfrag", CombinedFragment.class); + CombinedFragment cfrag = (CombinedFragment) combinedFragmentEP.getAdapter(EObject.class); + Interaction interaction = cfrag.getEnclosingInteraction(); + assumeThat("No interaction", interaction, notNullValue()); + + InteractionOperand operand = cfrag.getOperands().get(1); + InteractionFragment deleteSend = operand.getFragment("delete-send"); + assumeThat("Lost the delete send event on editor open", deleteSend, notNullValue()); + InteractionFragment deleted = operand.getFragment("deleted"); + assumeThat("Lost the deletion occurrence on editor open", deleted, notNullValue()); + + EditPart operandEP = editor.requireEditPart(combinedFragmentEP, operand); + + editor.delete(operandEP); + + combinedFragmentEP = editor.findEditPart(cfrag); + + assertThat("Combined fragment was deleted", cfrag.getEnclosingInteraction(), is(interaction)); + assertThat("Combined fragment no longer presented in diagram", combinedFragmentEP, notNullValue()); + + assertThat("Fragments of deleted operand not retained", + interaction.getFragments(), hasItems(deleteSend, deleted)); + } } diff --git a/tests/junit/plugins/uml/org.eclipse.papyrus.uml.service.types.tests/resource/interactions/bug533683.uml b/tests/junit/plugins/uml/org.eclipse.papyrus.uml.service.types.tests/resource/interactions/bug533683.uml new file mode 100644 index 00000000000..274e2bcf053 --- /dev/null +++ b/tests/junit/plugins/uml/org.eclipse.papyrus.uml.service.types.tests/resource/interactions/bug533683.uml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_HWN6cEMwEeiEZ5Jtfh6-KA" name="bug533683"> + <packageImport xmi:id="_HeHSMEMwEeiEZ5Jtfh6-KA"> + <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/> + </packageImport> + <packagedElement xmi:type="uml:Class" xmi:id="_Jqu6wEMwEeiEZ5Jtfh6-KA" name="Foo"> + <ownedAttribute xmi:id="_LwEPkEMwEeiEZ5Jtfh6-KA" name="a"/> + <ownedAttribute xmi:id="_M6OVkEMwEeiEZ5Jtfh6-KA" name="b"/> + <ownedBehavior xmi:type="uml:Interaction" xmi:id="_POkWwEMwEeiEZ5Jtfh6-KA" name="DoIt"> + <lifeline xmi:id="_RZwb8EMwEeiEZ5Jtfh6-KA" name="a" represents="_LwEPkEMwEeiEZ5Jtfh6-KA" coveredBy="_FQ3nIESnEeilLIdbxjHAOw _XfZkgEMwEeiEZ5Jtfh6-KA _XgH9QEMwEeiEZ5Jtfh6-KA _FQ2ZAESnEeilLIdbxjHAOw _U_hhIEZDEeisIvDZ4lXvcg"/> + <lifeline xmi:id="_R0URAEMwEeiEZ5Jtfh6-KA" name="b" represents="_M6OVkEMwEeiEZ5Jtfh6-KA" coveredBy="_FQ3nIESnEeilLIdbxjHAOw _XfaLkEMwEeiEZ5Jtfh6-KA _XgHWMEMwEeiEZ5Jtfh6-KA _Xf7wAEMwEeiEZ5Jtfh6-KA _FQ2ZAESnEeilLIdbxjHAOw _U_hhIEZDEeisIvDZ4lXvcg"/> + <fragment xmi:type="uml:CombinedFragment" xmi:id="_FQ2ZAESnEeilLIdbxjHAOw" name="cfrag" covered="_RZwb8EMwEeiEZ5Jtfh6-KA _R0URAEMwEeiEZ5Jtfh6-KA" interactionOperator="alt"> + <operand xmi:id="_FQ3nIESnEeilLIdbxjHAOw" name="alt1" covered="_RZwb8EMwEeiEZ5Jtfh6-KA _R0URAEMwEeiEZ5Jtfh6-KA"> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XfZkgEMwEeiEZ5Jtfh6-KA" name="request-send" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_XfUsAEMwEeiEZ5Jtfh6-KA"/> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XfaLkEMwEeiEZ5Jtfh6-KA" name="request-recv" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_XfUsAEMwEeiEZ5Jtfh6-KA"/> + <fragment xmi:type="uml:BehaviorExecutionSpecification" xmi:id="_Xf7wAEMwEeiEZ5Jtfh6-KA" name="exec" covered="_R0URAEMwEeiEZ5Jtfh6-KA" finish="_XgHWMEMwEeiEZ5Jtfh6-KA" start="_XfaLkEMwEeiEZ5Jtfh6-KA"/> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XgHWMEMwEeiEZ5Jtfh6-KA" name="reply-send" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_XgGvIEMwEeiEZ5Jtfh6-KA"/> + <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XgH9QEMwEeiEZ5Jtfh6-KA" name="reply-recv" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_XgGvIEMwEeiEZ5Jtfh6-KA"/> + <guard xmi:id="_FQ3nIUSnEeilLIdbxjHAOw" name="guard"> + <specification xmi:type="uml:LiteralBoolean" xmi:id="_-EX0AEZCEeisIvDZ4lXvcg"/> + </guard> + </operand> + <operand xmi:id="_U_hhIEZDEeisIvDZ4lXvcg" name="alt2" covered="_RZwb8EMwEeiEZ5Jtfh6-KA _R0URAEMwEeiEZ5Jtfh6-KA"/> + </fragment> + <message xmi:id="_XfUsAEMwEeiEZ5Jtfh6-KA" name="request" receiveEvent="_XfaLkEMwEeiEZ5Jtfh6-KA" sendEvent="_XfZkgEMwEeiEZ5Jtfh6-KA"/> + <message xmi:id="_XgGvIEMwEeiEZ5Jtfh6-KA" messageSort="reply" receiveEvent="_XgH9QEMwEeiEZ5Jtfh6-KA" sendEvent="_XgHWMEMwEeiEZ5Jtfh6-KA"/> + </ownedBehavior> + </packagedElement> +</uml:Model> diff --git a/tests/junit/plugins/uml/org.eclipse.papyrus.uml.service.types.tests/src/org/eclipse/papyrus/uml/service/types/tests/deletion/InteractionDeletionTest.java b/tests/junit/plugins/uml/org.eclipse.papyrus.uml.service.types.tests/src/org/eclipse/papyrus/uml/service/types/tests/deletion/InteractionDeletionTest.java index e9e9800367d..ac0399f566d 100644 --- a/tests/junit/plugins/uml/org.eclipse.papyrus.uml.service.types.tests/src/org/eclipse/papyrus/uml/service/types/tests/deletion/InteractionDeletionTest.java +++ b/tests/junit/plugins/uml/org.eclipse.papyrus.uml.service.types.tests/src/org/eclipse/papyrus/uml/service/types/tests/deletion/InteractionDeletionTest.java @@ -14,26 +14,35 @@ package org.eclipse.papyrus.uml.service.types.tests.deletion; import static org.eclipse.papyrus.junit.matchers.MoreMatchers.greaterThan; +import static org.hamcrest.CoreMatchers.everyItem; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; import static org.junit.Assume.assumeThat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; +import java.util.Map; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.RollbackException; +import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; import org.eclipse.gmf.runtime.common.core.command.ICommand; +import org.eclipse.gmf.runtime.common.core.command.IdentityCommand; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest; import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe; import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils; import org.eclipse.papyrus.infra.services.edit.service.IElementEditService; +import org.eclipse.papyrus.infra.types.core.registries.ElementTypeSetConfigurationRegistry; import org.eclipse.papyrus.junit.utils.rules.ModelSetFixture; import org.eclipse.papyrus.junit.utils.rules.PluginResource; import org.eclipse.uml2.common.util.UML2Util; @@ -45,6 +54,9 @@ import org.eclipse.uml2.uml.InteractionOperand; import org.eclipse.uml2.uml.InteractionOperatorKind; import org.eclipse.uml2.uml.NamedElement; import org.eclipse.uml2.uml.UMLFactory; +import org.hamcrest.CustomTypeSafeMatcher; +import org.hamcrest.Matcher; +import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -157,7 +169,7 @@ public class InteractionDeletionTest { delete(exec); - assertThat("Execution specification not deleted", exec.eResource(), nullValue()); + assertThat("Execution specification not deleted", exec, isDeleted()); assertThat("Operand still has the execution specification", operand.getFragments(), not(hasItem(exec))); assertThat("Interaction has the execution specification", interaction.getFragments(), not(hasItem(exec))); } @@ -176,8 +188,8 @@ public class InteractionDeletionTest { delete(interaction); - assertThat("Execution specification not deleted", exec.eResource(), nullValue()); - assertThat("Interaction not deleted", interaction.eResource(), nullValue()); + assertThat("Execution specification not deleted", exec, isDeleted()); + assertThat("Interaction not deleted", interaction, isDeleted()); } @Test @@ -193,14 +205,79 @@ public class InteractionDeletionTest { delete(interaction); - assertThat("Execution specification not deleted", exec.eResource(), nullValue()); - assertThat("Interaction not deleted", interaction.eResource(), nullValue()); + assertThat("Execution specification not deleted", exec, isDeleted()); + assertThat("Interaction not deleted", interaction, isDeleted()); + } + + /** + * Verify that the deletion of the last operand of a combined fragment results in the + * combined fragment also being deleted. + */ + @Test + @PluginResource("resource/interactions/bug533683.uml") + public void deleteOperandsOfCombinedFragment() { + CombinedFragment cfrag = findElement("cfrag", CombinedFragment.class); + Interaction interaction = cfrag.getEnclosingInteraction(); + assumeThat("No interaction", interaction, notNullValue()); + + InteractionOperand alt1 = cfrag.getOperand("alt1"); + InteractionOperand alt2 = cfrag.getOperand("alt2"); + + // We have at least four message ends and one execution specification + InteractionFragment[] fragments = alt1.getFragments().toArray(new InteractionFragment[0]); + assumeThat("Lost fragments on opening editor", fragments.length, greaterThan(4)); + ExecutionSpecification exec = (ExecutionSpecification) alt1.getFragment("exec"); + assumeThat("No execution specification", exec, notNullValue()); + + delete(alt2); + + assertThat(cfrag.getOperands(), is(Collections.singletonList(alt1))); + + assertThat("Interaction fragments were moved or deleted", alt1.getFragments(), hasItems(fragments)); + + delete(alt1); + + assertThat("Combined fragment not deleted", cfrag, isDeleted()); + + assertThat("Interaction fragments not retained", interaction.getFragments(), hasItems(fragments)); + } + + /** + * Verify that the simultaneous deletion of all operands of a combined fragment results in the + * combined fragment also being deleted. + */ + @Test + @PluginResource("resource/interactions/bug533683.uml") + public void deleteAllOperandsOfCombinedFragment() { + CombinedFragment cfrag = findElement("cfrag", CombinedFragment.class); + Interaction interaction = cfrag.getEnclosingInteraction(); + assumeThat("No interaction", interaction, notNullValue()); + + InteractionOperand alt1 = cfrag.getOperand("alt1"); + InteractionOperand alt2 = cfrag.getOperand("alt2"); + + // We have at least four message ends and one execution specification + InteractionFragment[] fragments = alt1.getFragments().toArray(new InteractionFragment[0]); + assumeThat("Lost fragments on opening editor", fragments.length, greaterThan(4)); + ExecutionSpecification exec = (ExecutionSpecification) alt1.getFragment("exec"); + assumeThat("No execution specification", exec, notNullValue()); + + delete(Arrays.asList(alt1, alt2)); + assertThat(Arrays.asList(alt1, alt2), everyItem(isDeleted())); + + assertThat("Combined fragment not deleted", cfrag, isDeleted()); + assertThat("Interaction fragments not retained", interaction.getFragments(), hasItems(fragments)); } // // Test framework // + @BeforeClass + public static void ensureModeledEditHelperAdvice() { + ElementTypeSetConfigurationRegistry.getInstance().getElementTypeSetConfigurations(); + } + <T extends NamedElement> T findElement(String name, Class<T> type) { Iterator<? extends EObject> eObjects = Iterators.filter(model.getResourceSet().getAllContents(), EObject.class); return type.cast(UML2Util.findEObject(eObjects, eObject -> type.isInstance(eObject) && name.equals(((NamedElement) eObject).getName()))); @@ -211,6 +288,25 @@ public class InteractionDeletionTest { model.execute(command(object.eContainer(), request)); } + void delete(Collection<? extends EObject> objects) { + DestroyElementRequest request = new DestroyElementRequest(model.getEditingDomain(), false); + Map<String, Object> parameters = new HashMap<>(); + + @SuppressWarnings("unchecked") + ICommand command = objects.stream().reduce((ICommand) IdentityCommand.INSTANCE, + (cmd, object) -> { + request.setElementToDestroy(object); + request.addParameters(parameters); + ICommand delete = command(object.eContainer(), request); + parameters.clear(); + parameters.putAll(request.getParameters()); + return cmd.compose(delete); + }, + CompositeCommand::compose); + + model.execute(command.reduce()); + } + ICommand command(EObject object, IEditCommandRequest request) { IElementEditService edit = ElementEditServiceUtils.getCommandProvider(object); assertThat("No edit command provider", edit, notNullValue()); @@ -254,4 +350,13 @@ public class InteractionDeletionTest { return result[0]; } + + static Matcher<EObject> isDeleted() { + return new CustomTypeSafeMatcher<EObject>("is deleted") { + @Override + protected boolean matchesSafely(EObject item) { + return item.eResource() == null; + } + }; + } } |