Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas FAUVERGUE2019-05-23 07:35:06 +0000
committerPatrick Tessier2019-05-23 09:59:57 +0000
commit889f4d8cafc5b2a0225e9fa38be07157daca1e7e (patch)
tree67852b8e975bcef01c4dbbebf782744262dbb02a /plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse
parent4b2cf01b47527be213eedd1f024aba6557873001 (diff)
downloadorg.eclipse.papyrus-889f4d8cafc5b2a0225e9fa38be07157daca1e7e.tar.gz
org.eclipse.papyrus-889f4d8cafc5b2a0225e9fa38be07157daca1e7e.tar.xz
org.eclipse.papyrus-889f4d8cafc5b2a0225e9fa38be07157daca1e7e.zip
Bug 542802: [SequenceDiagram] Undo after message creation removes other
elements from the model - Manage the undo manually because an action was done silently after the command execution that's re-order the items in interaction or interaction operand, so the undo delete the wrong elements. Change-Id: I3507d7ffe744ce19876aa6132312cb181dae3c5b Signed-off-by: Nicolas FAUVERGUE <nicolas.fauvergue@cea.fr>
Diffstat (limited to 'plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse')
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/CreateExecutionSpecificationWithMessage.java139
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/SequenceDeleteHelper.java25
2 files changed, 140 insertions, 24 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/CreateExecutionSpecificationWithMessage.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/CreateExecutionSpecificationWithMessage.java
index cff9fe915d7..8b14d785590 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/CreateExecutionSpecificationWithMessage.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/CreateExecutionSpecificationWithMessage.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2017 CEA LIST and others.
+ * Copyright (c) 2017, 2019 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* CEA LIST - Initial API and implementation
+ * Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Bug 542802
*
*****************************************************************************/
@@ -24,9 +25,12 @@ import java.util.stream.StreamSupport;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
@@ -44,7 +48,9 @@ import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequestFactory;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
+import org.eclipse.gmf.runtime.emf.type.core.commands.DestroyElementCommand;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.papyrus.commands.DestroyElementPapyrusCommand;
@@ -56,17 +62,19 @@ import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.LifelineEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.messages.Messages;
import org.eclipse.papyrus.uml.diagram.sequence.part.UMLDiagramEditorPlugin;
import org.eclipse.papyrus.uml.diagram.sequence.preferences.CustomDiagramGeneralPreferencePage;
+import org.eclipse.papyrus.uml.diagram.sequence.util.SequenceDeleteHelper;
import org.eclipse.papyrus.uml.service.types.element.UMLDIElementTypes;
+import org.eclipse.uml2.uml.DestructionOccurrenceSpecification;
import org.eclipse.uml2.uml.ExecutionSpecification;
+import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.InteractionOperand;
import org.eclipse.uml2.uml.Message;
import org.eclipse.uml2.uml.MessageEnd;
import org.eclipse.uml2.uml.OccurrenceSpecification;
import org.eclipse.uml2.uml.UMLPackage;
/**
- * this class is used to automatically create execution specifications at target
- * from the request in charge of creating a message between lifelines
- * according to the preferences for this message sort
+ * This class is used to automatically create execution specifications at target from the request in charge of creating a message between lifelines according to the preferences for this message sort.
*/
public class CreateExecutionSpecificationWithMessage extends AbstractTransactionalCommand {
@@ -78,6 +86,16 @@ public class CreateExecutionSpecificationWithMessage extends AbstractTransaction
protected boolean createReply;
/**
+ * This allows to stove the created execution specification needed for the undo.
+ */
+ private ExecutionSpecification createdExecutionSpecification;
+
+ /**
+ * This allows to store the created message reply needed for the undo.
+ */
+ private Message createdMessageReply;
+
+ /**
* @param domain
* @param request
* the request that is in charge of creating the message
@@ -93,15 +111,12 @@ public class CreateExecutionSpecificationWithMessage extends AbstractTransaction
}
/**
- * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable)
+ * {@inheritDoc}
*
- * @param monitor
- * @param info
- * @return
- * @throws ExecutionException
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable)
*/
@Override
- protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
// 1. look for the message triggering the creation of the execution specification
Message message = getMessage();
if (message == null) {
@@ -118,6 +133,93 @@ public class CreateExecutionSpecificationWithMessage extends AbstractTransaction
return CommandResult.newOKCommandResult();
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doUndo(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable)
+ */
+ @Override
+ protected IStatus doUndo(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+
+ // Remove the reply message
+ if (null != createdMessageReply) {
+ // First delete the send and receive events
+ final MessageEnd sendEvent = createdMessageReply.getSendEvent();
+ final MessageEnd receiveEvent = createdMessageReply.getReceiveEvent();
+
+ final CompoundCommand compoundCommand = new CompoundCommand();
+ SequenceDeleteHelper.destroyMessageEvent(compoundCommand, sendEvent, getEditingDomain());
+ if (false == receiveEvent instanceof DestructionOccurrenceSpecification) {
+ SequenceDeleteHelper.destroyMessageEvent(compoundCommand, receiveEvent, getEditingDomain());
+ }
+ if (!compoundCommand.isEmpty() && compoundCommand.canExecute()) {
+ compoundCommand.execute();
+ }
+
+ // Destroy the graphical representation first
+ final CompositeTransactionalCommand compositeCommand = new CompositeTransactionalCommand(getEditingDomain(), "Remove message view"); //$NON-NLS-1$
+ SequenceDeleteHelper.deleteView(compositeCommand, createdMessageReply, getEditingDomain());
+ compositeCommand.execute(monitor, info);
+
+ // Remove the reply message
+ final EObject container = createdMessageReply.eContainer();
+ if (container instanceof Interaction) {
+ ((Interaction) container).getMessages().remove(createdMessageReply);
+ }
+ }
+ // Remove the execution specification
+ if (null != createdExecutionSpecification) {
+ // First delete its start and finish
+ final OccurrenceSpecification start = createdExecutionSpecification.getStart();
+ final OccurrenceSpecification finish = createdExecutionSpecification.getFinish();
+ final CompoundCommand compoundCommand = new CompoundCommand();
+
+ if (null != start) {
+ DestroyElementRequest delStart = new DestroyElementRequest(getEditingDomain(), start, false);
+ compoundCommand.add(new ICommandProxy(new DestroyElementCommand(delStart)));
+ }
+ if (null != finish) {
+ DestroyElementRequest delEnd = new DestroyElementRequest(getEditingDomain(), finish, false);
+ compoundCommand.add(new ICommandProxy(new DestroyElementCommand(delEnd)));
+ }
+ if (!compoundCommand.isEmpty() && compoundCommand.canExecute()) {
+ compoundCommand.execute();
+ }
+
+ // Destroy the graphical representation first
+ final CompositeTransactionalCommand compositeCommand = new CompositeTransactionalCommand(getEditingDomain(), "Remove execution specification view"); //$NON-NLS-1$
+ SequenceDeleteHelper.deleteView(compositeCommand, createdExecutionSpecification, getEditingDomain());
+ compositeCommand.execute(monitor, info);
+ // Remove the execution specification
+ final EObject container = createdExecutionSpecification.eContainer();
+ if (container instanceof Interaction) {
+ ((Interaction) container).getFragments().remove(createdExecutionSpecification);
+ } else if (container instanceof InteractionOperand) {
+ ((InteractionOperand) container).getFragments().remove(createdExecutionSpecification);
+ }
+ }
+
+ // Clear the stored values because the redo will fill this fields if needed
+ createdExecutionSpecification = null;
+ createdMessageReply = null;
+
+ setResult(new CommandResult(Status.OK_STATUS));
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doRedo(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable)
+ */
+ @Override
+ protected IStatus doRedo(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
+ // Only re-execute the initial process
+ final CommandResult result = doExecuteWithResult(monitor, info);
+
+ setResult(result);
+ return result.getStatus();
+ }
/**
@@ -131,16 +233,17 @@ public class CreateExecutionSpecificationWithMessage extends AbstractTransaction
requestcreation.setLocation(point);
Command command = lifelineEditPart.getCommand(requestcreation);
command.execute();
+ // Save the created execution specification for the possible undo
+ createdExecutionSpecification = getCreatedElement(command, ExecutionSpecification.class);
// case where a reply message must also be created
if (createReply) {
// Gets the created execution specification
- ExecutionSpecification executionSpecification = getCreatedElement(command, ExecutionSpecification.class);
- if (null != executionSpecification) {
+ if (null != createdExecutionSpecification) {
Point replysourcepoint = point.getCopy();
replysourcepoint.setY(replysourcepoint.y + CustomActionExecutionSpecificationEditPart.DEFAULT_HEIGHT);
// source of the reply message is the end of the execution specification
- createReplyMessage(lifelineEditPart, executionSpecification, replysourcepoint);
+ createReplyMessage(lifelineEditPart, createdExecutionSpecification, replysourcepoint);
}
}
}
@@ -178,9 +281,10 @@ public class CreateExecutionSpecificationWithMessage extends AbstractTransaction
replycommand.execute();
// replace execution Specification finish event by the message reply send event.
- Message messageReply = getCreatedElement(replycommand, Message.class);
- if (null != messageReply) {
- MessageEnd sendEvent = messageReply.getSendEvent();
+ // Save the created execution specification for the possible undo
+ createdMessageReply = getCreatedElement(replycommand, Message.class);
+ if (null != createdMessageReply) {
+ MessageEnd sendEvent = createdMessageReply.getSendEvent();
OccurrenceSpecification finish = executionSpecification.getFinish();
SetCommand setSendEventCommand = new SetCommand(getEditingDomain(), executionSpecification, UMLPackage.eINSTANCE.getExecutionSpecification_Finish(), sendEvent);
setSendEventCommand.execute();
@@ -188,7 +292,8 @@ public class CreateExecutionSpecificationWithMessage extends AbstractTransaction
// delete the old finish os.
DestroyElementPapyrusCommand destroyElementPapyrusCommand = new DestroyElementPapyrusCommand(new DestroyElementRequest(finish, false));
if (destroyElementPapyrusCommand != null && destroyElementPapyrusCommand.canExecute()) {
- getEditingDomain().getCommandStack().execute(new GMFtoEMFCommandWrapper(destroyElementPapyrusCommand));
+ new GMFtoEMFCommandWrapper(destroyElementPapyrusCommand).execute();
+ // getEditingDomain().getCommandStack().execute(new GMFtoEMFCommandWrapper(destroyElementPapyrusCommand));
}
}
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/SequenceDeleteHelper.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/SequenceDeleteHelper.java
index 541196959fe..9274494882b 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/SequenceDeleteHelper.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/SequenceDeleteHelper.java
@@ -1,6 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2010 CEA
- *
+ * Copyright (c) 2010, 2019 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -11,6 +10,7 @@
*
* Contributors:
* Atos Origin - Initial API and implementation
+ * Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Bug 542802
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.sequence.util;
@@ -125,7 +125,7 @@ public class SequenceDeleteHelper {
if (lifelineChild instanceof IBorderItemEditPart) {
final IBorderItemEditPart timePart = (IBorderItemEditPart) lifelineChild;
OccurrenceSpecification start = execution.getStart();
- OccurrenceSpecification finish = execution.getStart();
+ OccurrenceSpecification finish = execution.getFinish();
int positionForStart = SequenceUtil.positionWhereEventIsLinkedToPart(start, timePart);
int positionForFinish = SequenceUtil.positionWhereEventIsLinkedToPart(finish, timePart);
if (positionForStart != PositionConstants.NONE || positionForFinish != PositionConstants.NONE) {
@@ -234,13 +234,24 @@ public class SequenceDeleteHelper {
}
}
- static void destroyMessageEvent(CompoundCommand deleteElementsCommand, MessageEnd event, TransactionalEditingDomain transactionalEditingDomain) {
+ /**
+ * This allows to destroy a message event.
+ *
+ * @param deleteElementsCommand
+ * The compound command to fill.
+ * @param event
+ * The event to delete.
+ * @param transactionalEditingDomain
+ * The editing domain.
+ * @since 5.2
+ */
+ public static void destroyMessageEvent(final CompoundCommand deleteElementsCommand, final MessageEnd event, final TransactionalEditingDomain transactionalEditingDomain) {
if (event != null) {
- DestroyElementRequest myReq = new DestroyElementRequest(transactionalEditingDomain, event, false);
+ final DestroyElementRequest myReq = new DestroyElementRequest(transactionalEditingDomain, event, false);
// Sometimes, the message end is also the end of a execution.
- RestoreExecutionEndAdvice provider = new RestoreExecutionEndAdvice();
+ final RestoreExecutionEndAdvice provider = new RestoreExecutionEndAdvice();
if (provider != null) {
- ICommand editCommand = provider.getAfterEditCommand(myReq);
+ final ICommand editCommand = provider.getAfterEditCommand(myReq);
if (editCommand != null && editCommand.canExecute()) {
deleteElementsCommand.add(new ICommandProxy(editCommand));
}

Back to the top