Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2016-05-10 17:30:22 -0400
committerGerrit Code Review @ Eclipse.org2016-05-13 13:41:08 -0400
commit39b2279c74535bb53d530b48e87c80441695a028 (patch)
tree9e23243219c81b2354ba2bb518f9c81684091487
parent3e461b4650c6b162f9d4392f3ce9d176fc4d1fcd (diff)
downloadorg.eclipse.papyrus-39b2279c74535bb53d530b48e87c80441695a028.tar.gz
org.eclipse.papyrus-39b2279c74535bb53d530b48e87c80441695a028.tar.xz
org.eclipse.papyrus-39b2279c74535bb53d530b48e87c80441695a028.zip
Bug 492482: [Stereotype Display] Undo of "Show all related links" failure for stereotyped connectors (with model corruption)
https://bugs.eclipse.org/bugs/show_bug.cgi?id=492482 Try as much as necessary to make the undo/redo scenario of dropping Capsules to create CapsuleParts in Papyrus-RT Capsule State Machines work. That is, not to fail to undo with an index-out-of-bounds exception in undoing a ListChange in the ChangeDescription. Several things: * add a new mix-in interface for edit-policies that perform automatic edits to the notation model à la CanonicalEditPolicy with operations for execution of commands that prefer to reuse a read/write transaction if available, instead of an unprotected write * use this new protocol in the applied-stereotype edit-policies to try whenever possible to record the changes for correct undo/redo * change the applied-stereotype edit-policies to use a private pre-commit listener on the DiagramEventBroker to react to changes within a transaction instead of post-commit, again to promote the recording of changes as much as possible for undo/redo * update the default canonical child views strategy to enable registration of view types that it should not attempt to manage * use the new view-type filtering mechanism to exclude applied- stereotype views from canonical control * update all of the CommandUtil APIs for command execution that are only used by the applied-stereotype display controllers to piggy- back on the active read/write transaction if there is one, for plausible undo/redo support Note that this patch does include API changes, but not breaking changes, after the Neon M7 feature-freeze milestone. Change-Id: Ibe7978416d26c81474ccc4608e1090de5e5ac473
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AutomaticNotationEditPolicy.java80
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/ShapeCompartmentEditPolicy.java21
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/canonical/DefaultUMLVisualChildrenStrategy.java32
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractAppliedStereotypeDisplayEditPolicy.java99
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AppliedStereotypeExternalNodeEditPolicy.java7
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommentShapeForAppliedStereotypeEditPolicy.java26
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayCommandExecution.java77
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayConstant.java18
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/CommandUtil.java135
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/AppliedStereotypeExternalNodeLabelEditPolicy.java7
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.classpath14
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.settings/org.eclipse.jdt.core.prefs6
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/META-INF/MANIFEST.MF6
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/build.properties3
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/model/stereotype-edit.elementtypesconfigurations23
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/plugin.xml9
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCommentEditPolicy.java162
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCompartmentEditPolicy.java71
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/internal/edithelper/advice/AppliedStereotypeNotationDependentsAdvice.java98
-rw-r--r--plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/listeners/StereotypeElementListener.java128
20 files changed, 625 insertions, 397 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AutomaticNotationEditPolicy.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AutomaticNotationEditPolicy.java
new file mode 100644
index 00000000000..17677a75762
--- /dev/null
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/AutomaticNotationEditPolicy.java
@@ -0,0 +1,80 @@
+/*****************************************************************************
+ * 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.papyrus.infra.gmfdiag.common.editpolicies;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CanonicalEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.util.EditPartUtil;
+import org.eclipse.papyrus.infra.emf.gmf.command.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe;
+import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
+import org.eclipse.papyrus.infra.tools.util.TypeUtils;
+
+/**
+ * A mix-in interface for {@linkplain EditPolicy edit-policies} that perform
+ * automatic updates on the notation model in a similar fashion to the
+ * {@link CanonicalEditPolicy} but that are not the Canonical Edit Policy.
+ */
+public interface AutomaticNotationEditPolicy extends EditPolicy {
+
+ /**
+ * Executes a {@code command} in the context of the host edit-part, preferably
+ * with full undo/redo recording in the active read/write transaction, if there is
+ * one. Otherwise, just execute it as a stand-alone (or nested) unprotected write.
+ * So, in a sense, this is only potentially an "unsafe" execution.
+ *
+ * @param command
+ * a command to execute
+ */
+ default void execute(ICommand command) {
+ execute(GMFtoEMFCommandWrapper.wrap(command));
+ }
+
+ /**
+ * Executes a {@code command} in the context of the host edit-part, preferably
+ * with full undo/redo recording in the active read/write transaction, if there is
+ * one. Otherwise, just execute it as a stand-alone (or nested) unprotected write.
+ * So, in a sense, this is only potentially an "unsafe" execution.
+ *
+ * @param command
+ * a command to execute
+ */
+ default void execute(Command command) {
+ IGraphicalEditPart context = TypeUtils.as(getHost(), IGraphicalEditPart.class);
+
+ if ((context != null) && !EditPartUtil.isWriteTransactionInProgress(context, true, false)) {
+ // Have to go the unprotected route. Hopefully the context is an
+ // edit-part refresh or something else that is not in a higher
+ // recorded edit command scope that needs to be undoable
+ try {
+ GMFUnsafe.write(context.getEditingDomain(), command);
+ } catch (Exception e) {
+ // Failed to create the unprotected transaction or it rolled back
+ Activator.log.error("Unprotected notation change failed.", e); //$NON-NLS-1$
+ }
+ } else {
+ // There's a change recorder in progress or an unprotected write
+ // that can't be overridden with a read/write transaction anyways,
+ // or we're not an edit-part that provides editing domains,
+ // so just roll with it
+ if (command.canExecute()) {
+ command.execute();
+ }
+ }
+ }
+
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/ShapeCompartmentEditPolicy.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/ShapeCompartmentEditPolicy.java
index 8f4393ede29..a7a538c0b1b 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/ShapeCompartmentEditPolicy.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/editpolicies/ShapeCompartmentEditPolicy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2012, 2014 CEA LIST and others.
+ * Copyright (c) 2012, 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
@@ -9,6 +9,7 @@
* Contributors:
* Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
* Christian W. Damus (CEA) - bug 323802
+ * Christian W. Damus - bug 492482
*
*****************************************************************************/
package org.eclipse.papyrus.infra.gmfdiag.common.editpolicies;
@@ -30,7 +31,6 @@ import org.eclipse.papyrus.infra.gmfdiag.common.editpart.IPapyrusEditPart;
import org.eclipse.papyrus.infra.gmfdiag.common.editpart.IShapeCompartmentEditPart;
import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.NotificationManager;
import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.ShapeService;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.GMFUnsafe;
import org.eclipse.swt.widgets.Display;
/**
@@ -38,7 +38,7 @@ import org.eclipse.swt.widgets.Display;
* access to primary figure. the primary figure has to be a {@link IPapyrusNodeUMLElementFigure}.
* This edit policy manage the display of a shape in a new compartment and toggles the compartment display.
*/
-public class ShapeCompartmentEditPolicy extends GraphicalEditPolicy implements NotificationListener, IPapyrusListener {
+public class ShapeCompartmentEditPolicy extends GraphicalEditPolicy implements AutomaticNotationEditPolicy, NotificationListener, IPapyrusListener {
/** constant for this edit policy role */
public final static String SHAPE_COMPARTMENT_EDIT_POLICY = "ShapeCompartmentEditPolicy"; //$NON-NLS-1$
@@ -120,12 +120,9 @@ public class ShapeCompartmentEditPolicy extends GraphicalEditPolicy implements N
// boolean isVisible = hasToDisplayCompartment(editPart.getNotationView());
TransactionalEditingDomain domain = getEditingDomain(editPart);
CreateShapeCompartmentViewCommand command = new CreateShapeCompartmentViewCommand(domain, "Create Compartment", "Command that creates the compartment displaying shapes", editPart.getNotationView(), /* isVisible */false);
- try {
- // This should not change the command stack, as this transaction will only manipulate transient views. Create a transaction manually, if needed
- GMFUnsafe.write(domain, command);
- } catch (Exception e) {
- Activator.log.error(e);
- }
+
+ // This should not change the command stack, as this transaction will only manipulate transient views. Create a transaction manually, if needed
+ execute(command);
} catch (Exception e) {
Activator.log.error(e);
}
@@ -212,11 +209,7 @@ public class ShapeCompartmentEditPolicy extends GraphicalEditPolicy implements N
public void run() {
SetNodeVisibilityCommand setCommand = new SetNodeVisibilityCommand(editPart.getEditingDomain(), view, isVisible);
// use to avoid to put it in the command stack
- try {
- GMFUnsafe.write(editPart.getEditingDomain(), setCommand);
- } catch (Exception e) {
- Activator.log.error(e);
- }
+ execute(setCommand);
}
});
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/canonical/DefaultUMLVisualChildrenStrategy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/canonical/DefaultUMLVisualChildrenStrategy.java
index 92aef80a9a5..845c4c26eb2 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/canonical/DefaultUMLVisualChildrenStrategy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/canonical/DefaultUMLVisualChildrenStrategy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2015 Christian W. Damus and others.
+ * Copyright (c) 2015, 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
@@ -13,8 +13,9 @@
package org.eclipse.papyrus.uml.diagram.common.canonical;
+import java.util.Collection;
import java.util.Collections;
-import java.util.Iterator;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -23,6 +24,7 @@ import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.gmfdiag.canonical.strategy.IVisualChildrenStrategy;
+import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AutomaticNotationEditPolicy;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Stereotype;
@@ -33,11 +35,25 @@ import com.google.common.collect.ImmutableSet;
* that present applied stereotypes, which have nothing to do with model-view synchronization.
*/
public class DefaultUMLVisualChildrenStrategy implements IVisualChildrenStrategy {
+ /** View types that are managed by other edit-policies. */
+ private static final Set<String> excludedViewTypes = new HashSet<>();
public DefaultUMLVisualChildrenStrategy() {
super();
}
+ /**
+ * Registers view types that should be ignored by the CanonicalEditPolicy for
+ * the purposes of view creation and deletion, because (usually) they are managed
+ * {@linkplain AutomaticNotationEditPolicy automatically} by other edit-policies.
+ *
+ * @param viewTypes
+ * view types to be excluded from canonical management
+ */
+ public static void registerExcludedViewTypes(Collection<String> viewTypes) {
+ excludedViewTypes.addAll(viewTypes);
+ }
+
@Override
public List<? extends View> getCanonicalChildren(EditPart editPart, View view) {
List<? extends View> result = DEFAULT.getCanonicalChildren(editPart, view);
@@ -48,15 +64,9 @@ public class DefaultUMLVisualChildrenStrategy implements IVisualChildrenStrategy
? ImmutableSet.copyOf(((Element) semantic).getAppliedStereotypes())
: Collections.<Stereotype> emptySet();
- if (!appliedStereotypes.isEmpty()) {
- for (Iterator<? extends View> iter = result.iterator(); iter.hasNext();) {
- final EObject nextElement = iter.next().getElement();
-
- if (appliedStereotypes.contains(nextElement)) {
- iter.remove();
- }
- }
- }
+ // And the transient views that support CSS-driven presentation
+ result.removeIf(v -> excludedViewTypes.contains(v.getType())
+ || appliedStereotypes.contains(v.getElement()));
return result;
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractAppliedStereotypeDisplayEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractAppliedStereotypeDisplayEditPolicy.java
index 7487aee2bad..55a003a3451 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractAppliedStereotypeDisplayEditPolicy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AbstractAppliedStereotypeDisplayEditPolicy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2009, 2014 CEA LIST and others.
+ * Copyright (c) 2009, 2016 CEA LIST, Christian W. Damus, and others.
*
*
* All rights reserved. This program and the accompanying materials
@@ -13,6 +13,7 @@
* Christian W. Damus (CEA) - bug 440197
* Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Bug 393532
* Celine JANSSENS (ALL4TEC) celine.janssens@all4tec.net - Bug 455311 Stereotype Display
+ * Christian W. Damus - bug 492482
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.editpolicies;
@@ -22,14 +23,17 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand;
import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener;
+import org.eclipse.gmf.runtime.diagram.core.listener.NotificationPreCommitListener;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.gef.ui.internal.editpolicies.GraphicalEditPolicyEx;
import org.eclipse.gmf.runtime.notation.BasicCompartment;
@@ -39,15 +43,16 @@ import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.core.listenerservice.IPapyrusListener;
import org.eclipse.papyrus.infra.gmfdiag.common.editpart.ConnectionEditPart;
+import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.AutomaticNotationEditPolicy;
import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationUtils;
import org.eclipse.papyrus.uml.diagram.common.Activator;
+import org.eclipse.papyrus.uml.diagram.common.canonical.DefaultUMLVisualChildrenStrategy;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.command.CreateAppliedStereotypeCompartmentCommand;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.command.CreateAppliedStereotypePropertyViewCommand;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.command.CreateStereotypeLabelCommand;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper.StereotypeDisplayConstant;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper.StereotypeDisplayUtil;
import org.eclipse.papyrus.uml.diagram.common.stereotype.migration.StereotypeMigrationHelper;
-import org.eclipse.papyrus.uml.diagram.common.util.CommandUtil;
import org.eclipse.papyrus.uml.tools.listeners.StereotypeElementListener.StereotypeExtensionNotification;
import org.eclipse.swt.graphics.Image;
import org.eclipse.uml2.uml.Element;
@@ -59,7 +64,7 @@ import org.eclipse.uml2.uml.Stereotype;
* Specific edit policy for label displaying stereotypes and their properties
* for representing UML elements.
*/
-public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends GraphicalEditPolicyEx implements NotificationListener, IPapyrusListener {
+public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends GraphicalEditPolicyEx implements AutomaticNotationEditPolicy, NotificationListener, IPapyrusListener {
/**
*
@@ -90,8 +95,15 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
protected View hostView = null;
protected List<Stereotype> stereotypeList = Collections.emptyList();
+
+ private final NotificationPreCommitListener precommitListener = this::handlePrecommit;
-
+ static {
+ // Tell the Canonical Edit Policy not to manage applied-stereotype views
+ DefaultUMLVisualChildrenStrategy.registerExcludedViewTypes(StereotypeDisplayConstant.APPLIED_STEREOTYPE_VIEW_TYPES);
+ }
+
+
/**
* Creates a new AppliedStereotype display edit policy
*/
@@ -108,9 +120,9 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
if (getHost() instanceof IGraphicalEditPart) {
initialisation();
- // getDiagramEventBroker().addNotificationListener(view, this);
- getDiagramEventBroker().addNotificationListener(hostSemanticElement, this);
- getDiagramEventBroker().addNotificationListener(hostView, this);
+ // subscribe(view);
+ subscribe(hostSemanticElement);
+ subscribe(hostView);
// Create and Delete nodes if necessary
refreshNotationStructure();
@@ -119,6 +131,27 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
}
+ /**
+ * Subscribes to a {@code notifier} for notifications from the
+ * {@link #getDiagramEventBroker() event broker}.
+ *
+ * @param notifier a notifier to subscribe to
+ */
+ protected void subscribe(EObject notifier) {
+ // Subscribe to pre-commit, not post-commit events
+ getDiagramEventBroker().addNotificationListener(notifier, precommitListener);
+ }
+
+ /**
+ * Unsubscribes from a {@code notifier} for notifications from the
+ * {@link #getDiagramEventBroker() event broker}.
+ *
+ * @param notifier a notifier to unsubscribe from
+ */
+ protected void unsubscribe(EObject notifier) {
+ // Unsubscribe from pre-commit, not post-commit events
+ getDiagramEventBroker().removeNotificationListener(notifier, precommitListener);
+ }
/**
@@ -155,6 +188,26 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
public abstract void refreshDisplay();
+ /**
+ * React to a transaction pre-commit notification by returning a command that
+ * encapsulates follow-up changes in the applied-stereotype visualizaiton of
+ * my host edit-part.
+ *
+ * @param notification
+ * some model or notation change notification
+ *
+ * @return a trigger command that may or may not perform some modifications
+ * to the applied-stereotype notation in consequence
+ */
+ private Command handlePrecommit(Notification notification) {
+ return new RecordingCommand(((IGraphicalEditPart) getHost()).getEditingDomain()) {
+
+ @Override
+ protected void doExecute() {
+ notifyChanged(notification);
+ }
+ };
+ }
/**
*
@@ -287,7 +340,7 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
BasicCompartment compartment = helper.getStereotypeBraceCompartment(hostView, stereotype);
if (compartment == null) { // No Compartment Exists for this Stereotype
createAppliedStereotypeBraceCompartment(stereotype);
- getDiagramEventBroker().addNotificationListener(helper.getStereotypeBraceCompartment(hostView, stereotype), this);
+ subscribe(helper.getStereotypeBraceCompartment(hostView, stereotype));
}
@@ -310,7 +363,7 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
DecorationNode label = helper.getStereotypeLabel(hostView, stereotype);
if (null == label) { // No Label Exist for this Stereotype
createAppliedStereotypeLabel(stereotype);
- getDiagramEventBroker().addNotificationListener(helper.getStereotypeLabel(hostView, stereotype), this);
+ subscribe(helper.getStereotypeLabel(hostView, stereotype));
}
}
@@ -383,7 +436,7 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
EList<Property> properties = stereotype.allAttributes();
for (Property property : properties) {
createAppliedStereotypeBraceProperty(compartment, property);
- getDiagramEventBroker().addNotificationListener(helper.getStereotypePropertyInBrace(hostView, stereotype, property), this);
+ subscribe(helper.getStereotypePropertyInBrace(hostView, stereotype, property));
}
}
@@ -447,8 +500,7 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
*/
protected void executeAppliedStereotypeBraceCompartmentCreation(final IGraphicalEditPart editPart, final Stereotype stereotype) {
CreateAppliedStereotypeCompartmentCommand command = new CreateAppliedStereotypeCompartmentCommand(editPart.getEditingDomain(), editPart.getNotationView(), stereotype, StereotypeDisplayConstant.STEREOTYPE_BRACE_TYPE);
- CommandUtil.executeUnsafeCommand(command, editPart);
-
+ execute(command);
}
@@ -464,8 +516,7 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
*/
protected void executeAppliedStereotypeBracePropertyViewCreation(final IGraphicalEditPart editPart, final Node compartment, final Property stereotypeProperty) {
CreateAppliedStereotypePropertyViewCommand command = new CreateAppliedStereotypePropertyViewCommand(editPart.getEditingDomain(), compartment, stereotypeProperty, StereotypeDisplayConstant.STEREOTYPE_PROPERTY_BRACE_TYPE);
- CommandUtil.executeUnsafeCommand(command, editPart);
-
+ execute(command);
}
/**
@@ -478,9 +529,7 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
*/
protected void executeStereotypeLabelCreation(final IGraphicalEditPart editPart, final Stereotype stereotype) {
CreateStereotypeLabelCommand command = new CreateStereotypeLabelCommand(editPart.getEditingDomain(), editPart.getNotationView(), stereotype);
- CommandUtil.executeUnsafeCommand(command, editPart);
-
-
+ execute(command);
}
/**
@@ -527,10 +576,8 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
* DecorationNode of the Stereotype Label that has to be removed
*/
protected void executeStereotypeViewRemove(final IGraphicalEditPart editPart, final View view) {
-
DeleteCommand command = new DeleteCommand(view);
- CommandUtil.executeUnsafeCommand(command, editPart);
-
+ execute(command);
}
@@ -550,15 +597,15 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
public void removeListener() {
View view = getView();
if (null != view) {
- getDiagramEventBroker().removeNotificationListener(view, this);
+ unsubscribe(view);
if (null != hostSemanticElement) {
// remove listeners to applied stereotyped
for (EObject stereotypeApplication : hostSemanticElement.getStereotypeApplications()) {
- getDiagramEventBroker().removeNotificationListener(stereotypeApplication, this);
+ unsubscribe(stereotypeApplication);
}
// remove notification on element
- getDiagramEventBroker().removeNotificationListener(hostSemanticElement, this);
+ unsubscribe(hostSemanticElement);
// removes the reference to the semantic element
hostSemanticElement = null;
}
@@ -570,18 +617,18 @@ public abstract class AbstractAppliedStereotypeDisplayEditPolicy extends Graphic
// Remove label Listener
View label = helper.getStereotypeLabel(hostView, stereotype);
if (null != label) {
- getDiagramEventBroker().removeNotificationListener(label, this);
+ unsubscribe(label);
}
// Remove Brace Compartment Listener
BasicCompartment compartment = helper.getStereotypeBraceCompartment(hostView, stereotype);
if (null != compartment) {
- getDiagramEventBroker().addNotificationListener(helper.getStereotypeBraceCompartment(hostView, stereotype), this);
+ subscribe(helper.getStereotypeBraceCompartment(hostView, stereotype));
}
// Remove Brace Properties Listener
if (null != compartment && null != stereotype) {
EList<Property> properties = stereotype.allAttributes();
for (Property property : properties) {
- getDiagramEventBroker().removeNotificationListener(helper.getStereotypePropertyInBrace(hostView, stereotype, property), this);
+ unsubscribe(helper.getStereotypePropertyInBrace(hostView, stereotype, property));
}
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AppliedStereotypeExternalNodeEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AppliedStereotypeExternalNodeEditPolicy.java
index 5e5931cc0e4..e07e88c0782 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AppliedStereotypeExternalNodeEditPolicy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/AppliedStereotypeExternalNodeEditPolicy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2009 CEA LIST.
+ * Copyright (c) 2009, 2016 CEA LIST, Christian W. Damus, and others.
*
*
* All rights reserved. This program and the accompanying materials
@@ -11,6 +11,7 @@
* Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
* Patrick Tessier (CEA LIST) - Initial API and implementation
* Celine JANSSENS (ALL4TEC) celine.janssens@all4tec.net - Bug 455311 Stereotype Display
+ * Christian W. Damus - bug 492482
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.editpolicies;
@@ -47,7 +48,7 @@ public class AppliedStereotypeExternalNodeEditPolicy extends AppliedStereotypeLa
EObject parent = view.eContainer();
if (parent instanceof View) {
parentView = (View) parent;
- getDiagramEventBroker().addNotificationListener(parentView, this);
+ subscribe(parentView);
}
@@ -57,7 +58,7 @@ public class AppliedStereotypeExternalNodeEditPolicy extends AppliedStereotypeLa
@Override
public void deactivate() {
if (parentView != null) {
- getDiagramEventBroker().removeNotificationListener(parentView, this);
+ unsubscribe(parentView);
}
super.deactivate();
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommentShapeForAppliedStereotypeEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommentShapeForAppliedStereotypeEditPolicy.java
index 0169460c962..0e742df6772 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommentShapeForAppliedStereotypeEditPolicy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/editpolicies/CommentShapeForAppliedStereotypeEditPolicy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2012, 2014 CEA LIST and others.
+ * Copyright (c) 2012, 2016 CEA LIST, Christian W. Damus, and others.
*
*
* All rights reserved. This program and the accompanying materials
@@ -11,6 +11,7 @@
* Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
* Christian W. Damus (CEA) - bug 323802
* Celine Janssens (ALL4TEC) celine.janssens@all4tec.net - Bug 460356 : Refactor Stereotype Display
+ * Christian W. Damus - bug 492482
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.editpolicies;
@@ -23,10 +24,7 @@ import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand;
-import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
-import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.gmf.runtime.notation.View;
@@ -45,7 +43,7 @@ import org.eclipse.uml2.uml.util.UMLUtil;
* and launch command of deletion if it detect that no property of applied stereotype are displayed.
*
*/
-public class CommentShapeForAppliedStereotypeEditPolicy extends AbstractAppliedStereotypeDisplayEditPolicy implements NotificationListener, IPapyrusListener {
+public class CommentShapeForAppliedStereotypeEditPolicy extends AbstractAppliedStereotypeDisplayEditPolicy implements IPapyrusListener {
/**
@@ -139,7 +137,7 @@ public class CommentShapeForAppliedStereotypeEditPolicy extends AbstractAppliedS
// adds a listener on the view and the element controlled by the
// editpartrefr
- getDiagramEventBroker().addNotificationListener(view, this);
+ subscribe(view);
}
@@ -155,21 +153,7 @@ public class CommentShapeForAppliedStereotypeEditPolicy extends AbstractAppliedS
return;
}
- getDiagramEventBroker().removeNotificationListener(view, this);
- }
-
- /**
- * Gets the diagram event broker from the editing domain.
- *
- * @return the diagram event broker
- */
- @Override
- protected DiagramEventBroker getDiagramEventBroker() {
- TransactionalEditingDomain theEditingDomain = ((IGraphicalEditPart) getHost()).getEditingDomain();
- if (null != theEditingDomain) {
- return DiagramEventBroker.getInstance(theEditingDomain);
- }
- return null;
+ unsubscribe(view);
}
/**
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayCommandExecution.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayCommandExecution.java
index 745baa1bc12..c0490fa0a4c 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayCommandExecution.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayCommandExecution.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2015 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
@@ -9,6 +9,7 @@
* Contributors:
* Celine Janssens (ALL4TEC) celine.janssens@all4tec.net - Initial API and implementation
* Celine Janssens (ALL4TEC) celine.janssens@all4tec.net - Bug 455311 : Refactor Stereotype Display
+ * Christian W. Damus - bug 492482
*
*****************************************************************************/
@@ -59,36 +60,6 @@ public final class StereotypeDisplayCommandExecution {
}
/**
- * Runnable class for setting visibility of a View
- * Required if no Command has to be added into the stack
- */
- class SetVisibilityRunnable implements Runnable {
-
- private boolean visible;
- private View view;
-
- /**
- * Constructor.
- *
- */
- public SetVisibilityRunnable(boolean visible, View view) {
- this.visible = visible;
- this.view = view;
- }
-
- /**
- * @see java.lang.Runnable#run()
- *
- */
- @Override
- public void run() {
- if (view.isVisible() != visible) {
- view.setVisible(visible);
- }
- }
- }
-
- /**
* Set the visibility of a view
*
* @param view
@@ -97,12 +68,11 @@ public final class StereotypeDisplayCommandExecution {
* True to make the Compartment visible
*/
public void setVisibility(final TransactionalEditingDomain domain, final View view, final boolean isVisible, final boolean inCommandStack) {
-
+ SetNodeVisibilityCommand visibility = new SetNodeVisibilityCommand(domain, view, isVisible);
if (!inCommandStack) {
- CommandUtil.executeUnsafeCommand(new SetVisibilityRunnable(isVisible, view), domain);
+ CommandUtil.executeCommand(visibility, domain);
} else {
- SetNodeVisibilityCommand visibility = new SetNodeVisibilityCommand(domain, view, isVisible);
CommandUtil.executeCommandInStack(visibility, domain);
}
}
@@ -117,23 +87,11 @@ public final class StereotypeDisplayCommandExecution {
* True to make the Compartment visible
*/
public void setPersistency(final TransactionalEditingDomain domain, final View view, boolean inCommandStack) {
- if (!inCommandStack) {
+ SetPersistentViewCommand persitence = new SetPersistentViewCommand(domain, view);
- class SetPersistencyRunnable implements Runnable {
-
- /**
- * @see java.lang.Runnable#run()
- *
- */
- @Override
- public void run() {
- makeViewPersistant(view);
- }
-
- }
- CommandUtil.executeUnsafeCommand(new SetPersistencyRunnable(), domain);
+ if (!inCommandStack) {
+ CommandUtil.executeCommand(persitence, domain);
} else {
- SetPersistentViewCommand persitence = new SetPersistentViewCommand(domain, view);
CommandUtil.executeCommandInStack(persitence, domain);
}
@@ -148,24 +106,11 @@ public final class StereotypeDisplayCommandExecution {
* True to make the Compartment visible
*/
public void unsetPersistency(final TransactionalEditingDomain domain, final View view, boolean inCommandStack) {
+ UnsetPersistentViewCommand persistence = new UnsetPersistentViewCommand(domain, view);
if (!inCommandStack) {
-
- class UnsetPersistencyRunnable implements Runnable {
-
- /**
- * @see java.lang.Runnable#run()
- *
- */
- @Override
- public void run() {
- removeViewPersistant(view);
- }
-
- }
- CommandUtil.executeUnsafeCommand(new UnsetPersistencyRunnable(), domain);
+ CommandUtil.executeCommand(persistence, domain);
} else {
- UnsetPersistentViewCommand persitence = new UnsetPersistentViewCommand(domain, view);
- CommandUtil.executeCommandInStack(persitence, domain);
+ CommandUtil.executeCommandInStack(persistence, domain);
}
}
@@ -228,7 +173,7 @@ public final class StereotypeDisplayCommandExecution {
if (inCommandStack) {
CommandUtil.executeCommandInStack(command, domain);
} else {
- CommandUtil.executeUnsafeCommand(command, domain);
+ CommandUtil.executeCommand(command, domain);
}
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayConstant.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayConstant.java
index b03aa885035..e83aaeeb5cc 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayConstant.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/stereotype/display/helper/StereotypeDisplayConstant.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2015 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
@@ -9,13 +9,18 @@
* Contributors:
* Celine Janssens (ALL4TEC) celine.janssens@all4tec.net - Initial API and implementation
* Celine Janssens (ALL4TEC) celine.janssens@all4tec.net - Bug 455311 : Refactor Stereotypes Display
+ * Christian W. Damus - bug 492482
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper;
+import java.util.Set;
+
import org.eclipse.papyrus.uml.diagram.common.Activator;
+import com.google.common.collect.ImmutableSet;
+
/**
@@ -43,6 +48,17 @@ public class StereotypeDisplayConstant {
public static final String STEREOTYPE_COMMENT_TYPE = "StereotypeComment";//$NON-NLS-1$
public static final String STEREOTYPE_COMMENT_LINK_TYPE = "StereotypeCommentLink";
+
+ /**
+ * The applied-stereotype view types.
+ */
+ public static final Set<String> APPLIED_STEREOTYPE_VIEW_TYPES = ImmutableSet.of(
+ STEREOTYPE_LABEL_TYPE,
+ STEREOTYPE_BRACE_TYPE,
+ STEREOTYPE_COMPARTMENT_TYPE,
+ STEREOTYPE_COMMENT_TYPE, STEREOTYPE_COMMENT_LINK_TYPE,
+ STEREOTYPE_PROPERTY_TYPE, STEREOTYPE_PROPERTY_BRACE_TYPE);
+
// Name notation value
public static final String STEREOTYPE_LABEL_NAME = "stereotype";//$NON-NLS-1$
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/CommandUtil.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/CommandUtil.java
index 05422fbc1f3..b40821a493f 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/CommandUtil.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.common/src/org/eclipse/papyrus/uml/diagram/common/util/CommandUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Obeo.
+ * Copyright (c) 2008, 2016 Obeo, 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
@@ -8,6 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
* Celine Janssens (ALL4TEC) celine.janssens@all4tec.net - Enrich Execution Command
+ * Christian W. Damus - bug 492482
*******************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.util;
@@ -24,6 +25,7 @@ import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
import org.eclipse.emf.workspace.AbstractEMFOperation;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
@@ -32,8 +34,9 @@ import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer;
import org.eclipse.gmf.runtime.diagram.ui.util.EditPartUtil;
import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.emf.gmf.command.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe;
import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.GMFUnsafe;
import org.eclipse.papyrus.uml.diagram.common.Activator;
/**
@@ -88,15 +91,15 @@ public class CommandUtil {
}
/**
- * Execute a command as unsafe.
- * Consequence: the command doesn't appear in the Command Stack and does not make the diagram dirty.
+ * Executes a {@code command} in the safest possible way within the context of
+ * an {@code object}. This is as a (possibly nested)
+ * read/write transaction if there is already a read/write transaction active,
+ * otherwise in a (possibly nested) "unprotected write" transaction.
*
* @param command
- * The command to execute unsafe
+ * the command to execute
* @param object
- * The EObject that is required to define the Transactional domain.
- * @param synch
- * Define if the command should be execute synchronously or not.
+ * the contextual object from which to infer the editing domain
* @see {@link #resolveEditingDomain}
*/
public static void executeUnsafeCommand(final ICommand command, final Object object) {
@@ -109,15 +112,15 @@ public class CommandUtil {
}
/**
- * Execute a command as unsafe.
- * Consequence: the command doesn't appear in the Command Stack and does not make the diagram dirty.
+ * Executes a {@code command} in the safest possible way within the context of
+ * an {@code object}. This is as a (possibly nested)
+ * read/write transaction if there is already a read/write transaction active,
+ * otherwise in a (possibly nested) "unprotected write" transaction.
*
* @param command
- * The command to execute unsafe
+ * the command to execute
* @param object
- * The EObject that is required to define the Transactional domain.
- * @param synch
- * Define if the command should be execute synchronously or not.
+ * the contextual object from which to infer the editing domain
* @see {@link #resolveEditingDomain}
*/
public static void executeUnsafeCommand(final Command command, final Object object) {
@@ -129,15 +132,15 @@ public class CommandUtil {
}
/**
- * Execute a command as unsafe.
- * Consequence: the command doesn't appear in the Command Stack and does not make the diagram dirty.
+ * Executes a {@code command} in the safest possible way within the context of
+ * an {@code object}. This is as a (possibly nested)
+ * read/write transaction if there is already a read/write transaction active,
+ * otherwise in a (possibly nested) "unprotected write" transaction.
*
* @param command
- * The command to execute unsafe
+ * the command to execute
* @param object
- * The EObject that is required to define the Transactional domain.
- * @param synch
- * Define if the command should be execute synchronously or not.
+ * the contextual object from which to infer the editing domain
* @see {@link #resolveEditingDomain}
*/
public static void executeUnsafeCommand(final Runnable command, final Object object) {
@@ -150,21 +153,25 @@ public class CommandUtil {
}
/**
- * Execute a command as unsafe.
- * Consequence: the command doesn't appear in the Command Stack and does not make the diagram dirty.
+ * Execute a {@code command} in the command stack as usual, unless there's
+ * already a write transaction in progress, then just execute it directly.
*
* @param command
- * The command to execute unsafe
+ * The command to execute
* @param object
* The EObject that is required to define the Transactional domain.
*
* @see {@link #resolveEditingDomain}
*/
public static void executeCommandInStack(final org.eclipse.emf.common.command.Command command, final Object object) {
-
TransactionalEditingDomain domain = resolveEditingDomain(object);
- domain.getCommandStack().execute(command);
+ if (canWrite(domain) && command.canExecute()) {
+ // Just re-use the existing transaction
+ command.execute();
+ } else {
+ domain.getCommandStack().execute(command);
+ }
}
/**
@@ -196,58 +203,90 @@ public class CommandUtil {
}
/**
- * Run the Command Asynchronously
+ * Executes a {@code command} in the safest possible way within the context of
+ * a transactional editing {@code domain}. This is as a (possibly nested)
+ * read/write transaction if there is already a read/write transaction active,
+ * otherwise in a (possibly nested) "unprotected write" transaction.
*
* @param command
- * The command to execute
+ * the command to execute
* @param domain
- * The Transactional Editing Domain
- *
+ * the editing domain in which to execute a command
*/
public static void executeCommand(final Command command, final TransactionalEditingDomain domain) {
-
+ if (!canWrite(domain)) {
+ // Have to go the unprotected route. Hopefully the context is an
+ // edit-part refresh or something else that is not in a higher
+ // recorded edit command scope that needs to be undoable
try {
GMFUnsafe.write(domain, command);
} catch (Exception e) {
- Activator.log.error(e);
+ // Failed to create the unprotected transaction or it rolled back
+ Activator.log.error("Unprotected command execution failed.", e); //$NON-NLS-1$
+ }
+ } else {
+ // There's a change recorder in progress or an unprotected write
+ // that can't be overridden with a read/write transaction anyways,
+ // or we're not an edit-part that provides editing domains,
+ // so just roll with it
+ if (command.canExecute()) {
+ command.execute();
+ }
+ }
+ }
+
+ private static boolean canWrite(TransactionalEditingDomain domain) {
+ Transaction activeTransaction = null;
+ if (domain instanceof InternalTransactionalEditingDomain) {
+ activeTransaction = ((InternalTransactionalEditingDomain) domain).getActiveTransaction();
}
+ return (activeTransaction != null) && !activeTransaction.isReadOnly();
}
/**
- * Run the Command Asynchronously
+ * Executes a {@code command} in the safest possible way within the context of
+ * a transactional editing {@code domain}. This is as a (possibly nested)
+ * read/write transaction if there is already a read/write transaction active,
+ * otherwise in a (possibly nested) "unprotected write" transaction.
*
* @param command
- * The command to execute
+ * the command to execute
* @param domain
- * The Transactional Editing Domain
- *
+ * the editing domain in which to execute a command
*/
private static void executeCommand(final ICommand command, final TransactionalEditingDomain domain) {
- try {
- GMFUnsafe.write(domain, command);
- } catch (Exception e) {
- Activator.log.error(e);
+ executeCommand(GMFtoEMFCommandWrapper.wrap(command), domain);
}
- }
/**
- * Run the Command Asynchronously
+ * Executes a {@code command} in the safest possible way within the context of
+ * a transactional editing {@code domain}. This is as a (possibly nested)
+ * read/write transaction if there is already a read/write transaction active,
+ * otherwise in a (possibly nested) "unprotected write" transaction.
*
* @param command
- * The command to execute
+ * the command to execute
* @param domain
- * The Transactional Editing Domain
- *
+ * the editing domain in which to execute a command
*/
private static void executeCommand(final Runnable command, final TransactionalEditingDomain domain) {
- // use to avoid to put it in the command stack
+ if (!canWrite(domain)) {
+ // Have to go the unprotected route. Hopefully the context is an
+ // edit-part refresh or something else that is not in a higher
+ // recorded edit command scope that needs to be undoable
try {
GMFUnsafe.write(domain, command);
} catch (Exception e) {
- Activator.log.error(e);
+ // Failed to create the unprotected transaction or it rolled back
+ Activator.log.error("Unprotected command execution failed.", e); //$NON-NLS-1$
+ }
+ } else {
+ // There's a change recorder in progress or an unprotected write
+ // that can't be overridden with a read/write transaction anyways,
+ // or we're not an edit-part that provides editing domains,
+ // so just roll with it
+ command.run();
}
}
-
-
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/AppliedStereotypeExternalNodeLabelEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/AppliedStereotypeExternalNodeLabelEditPolicy.java
index 3f447635dce..24b03fef792 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/AppliedStereotypeExternalNodeLabelEditPolicy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/policies/AppliedStereotypeExternalNodeLabelEditPolicy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2013 CEA
+ * Copyright (c) 2013, 2016 CEA, Christian W. Damus, and others
*
*
* All rights reserved. This program and the accompanying materials
@@ -9,6 +9,7 @@
*
* Contributors:
* Soyatec - Initial API and implementation
+ * Christian W. Damus - bug 492482
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.sequence.edit.policies;
@@ -63,7 +64,7 @@ public class AppliedStereotypeExternalNodeLabelEditPolicy extends AppliedStereot
hostView = (View) parent;
}
}
- getDiagramEventBroker().addNotificationListener(hostView, this);
+ subscribe(hostView);
refreshDisplay();
@@ -72,7 +73,7 @@ public class AppliedStereotypeExternalNodeLabelEditPolicy extends AppliedStereot
@Override
public void deactivate() {
if (hostView != null) {
- getDiagramEventBroker().removeNotificationListener(hostView, this);
+ unsubscribe(hostView);
}
super.deactivate();
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.classpath b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.classpath
index 2d1a4302f04..eca7bdba8f0 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.classpath
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.classpath
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.settings/org.eclipse.jdt.core.prefs b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.settings/org.eclipse.jdt.core.prefs
index 4759947300a..62a08f4494d 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.settings/org.eclipse.jdt.core.prefs
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/.settings/org.eclipse.jdt.core.prefs
@@ -1,10 +1,10 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/META-INF/MANIFEST.MF b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/META-INF/MANIFEST.MF
index ff439fa68bd..31a868b0a97 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/META-INF/MANIFEST.MF
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/META-INF/MANIFEST.MF
@@ -1,10 +1,12 @@
Manifest-Version: 1.0
Export-Package: org.eclipse.papyrus.uml.diagram.stereotype.edition.editpart,
org.eclipse.papyrus.uml.diagram.stereotype.edition.editpolicies,
+ org.eclipse.papyrus.uml.diagram.stereotype.edition.internal.edithelper.advice;x-internal:=true,
org.eclipse.papyrus.uml.diagram.stereotype.edition.provider
Require-Bundle: org.eclipse.papyrus.uml.diagram.common;bundle-version="[2.0.0,3.0.0)";visibility:=reexport,
org.eclipse.papyrus.uml.appearance;bundle-version="[1.2.0,2.0.0)",
- org.eclipse.papyrus.uml.profile;bundle-version="[2.0.0,3.0.0)"
+ org.eclipse.papyrus.uml.profile;bundle-version="[2.0.0,3.0.0)",
+ org.eclipse.papyrus.infra.types;bundle-version="[2.0.0,3.0.0)"
Bundle-Vendor: %providerName
Bundle-ActivationPolicy: lazy
Bundle-Version: 1.2.0.qualifier
@@ -14,4 +16,4 @@ Bundle-Activator: org.eclipse.papyrus.uml.diagram.stereotype.edition.Activator
Bundle-ManifestVersion: 2
Bundle-Description: %pluginDescription
Bundle-SymbolicName: org.eclipse.papyrus.uml.diagram.stereotype.edition;singleton:=true
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/build.properties b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/build.properties
index bc40c8bd26b..85541d0f03d 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/build.properties
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/build.properties
@@ -4,6 +4,7 @@ bin.includes = META-INF/,\
.,\
plugin.xml,\
about.html,\
- plugin.properties
+ plugin.properties,\
+ model/
src.includes = about.html,\
docs/,\
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/model/stereotype-edit.elementtypesconfigurations b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/model/stereotype-edit.elementtypesconfigurations
new file mode 100644
index 00000000000..865e3bc537f
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/model/stereotype-edit.elementtypesconfigurations
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="ASCII"?>
+<elementtypesconfigurations:ElementTypeSetConfiguration
+ xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:elementtypesconfigurations="http://www.eclipse.org/papyrus/infra/elementtypesconfigurations/1.1"
+ xmi:id="_ScP1oFYCEeS0WsAAtVmToA"
+ name="Stereotype Editing Advice"
+ description="Advice definitions supporting the editing of stereotypes."
+ identifier="org.eclipse.papyrus.uml.diagram.stereotype.edition.advice"
+ metamodelNsURI="http://www.eclipse.org/uml2/5.0.0/UML">
+ <adviceBindingsConfigurations
+ xsi:type="elementtypesconfigurations:AdviceBindingConfiguration"
+ xmi:id="_4rSa8Dm8EeWMHpLNzlgfaQ"
+ description="Adds applied-stereotype views to the dependents of a notation view that is being deleted."
+ identifier="org.eclipse.papyrus.uml.diagram.stereotype.edition.advice.AppliedStereotypeNotationDependents"
+ editHelperAdviceClassName="org.eclipse.papyrus.uml.diagram.stereotype.edition.internal.edithelper.advice.AppliedStereotypeNotationDependentsAdvice"
+ inheritance="all">
+ <target
+ xsi:type="elementtypesconfigurations:MetamodelTypeConfiguration"
+ href="../../org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations#_ScgUUFYCEeS0WsAAtVmToA"/>
+ </adviceBindingsConfigurations>
+</elementtypesconfigurations:ElementTypeSetConfiguration>
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/plugin.xml b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/plugin.xml
index 6ec94f1bff2..4eeaf1f1345 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/plugin.xml
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/plugin.xml
@@ -30,4 +30,13 @@
</object>
</editpartProvider>
</extension>
+
+ <extension
+ point="org.eclipse.papyrus.infra.types.core.elementTypeSetConfiguration">
+ <elementTypeSet
+ clientContextID="org.eclipse.papyrus.infra.services.edit.TypeContext"
+ path="model/stereotype-edit.elementtypesconfigurations">
+ </elementTypeSet>
+ </extension>
+
</plugin>
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCommentEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCommentEditPolicy.java
index a6c48b59a85..4e43436339c 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCommentEditPolicy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCommentEditPolicy.java
@@ -11,7 +11,7 @@
* Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
* Christian W. Damus (CEA) - bug 323802
* Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.fr - Bug 393532
- * Christian W. Damus - bug 492407
+ * Christian W. Damus - bugs 492407, 492482
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.stereotype.edition.editpolicies;
@@ -34,15 +34,12 @@ import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.LayoutConstraint;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.GMFUnsafe;
-import org.eclipse.papyrus.uml.diagram.common.Activator;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.AppliedStereotypeNodeLabelDisplayEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.command.CreateAppliedStereotypeCommentViewCommand;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.command.CreateAppliedStereotypeCompartmentCommand;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.command.CreateAppliedStereotypePropertyViewCommand;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper.StereotypeDisplayConstant;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper.StereotypeDisplayUtil;
-import org.eclipse.swt.widgets.Display;
import org.eclipse.uml2.uml.Extension;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;
@@ -72,7 +69,7 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
@Override
public void activate() {
super.activate();
- getDiagramEventBroker().addNotificationListener(hostView.eContainer(), this);
+ subscribe(hostView.eContainer());
};
@@ -82,7 +79,7 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
*/
@Override
public void deactivate() {
- getDiagramEventBroker().removeNotificationListener(hostView.eContainer(), this);
+ unsubscribe(hostView.eContainer());
super.deactivate();
}
@@ -114,20 +111,20 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
@Override
public void notifyChanged(Notification notification) {
super.notifyChanged(notification);
-
+
// Don't react if the comment is not attached to a diagram
if ((comment != null) && (comment.getDiagram() != null)) {
int eventType = notification.getEventType();
EObject object = StereotypeDisplayUtil.getInstance().getCommentSemanticElement(comment);
// If the reference object of the comment is removed, delete the Comment node itself.
if (eventType == Notification.REMOVE && notification.getOldValue().equals(hostView) && object == null) {
- executeAppliedStereotypeCommentDeletion(hostEditPart.getEditingDomain(), comment);
+ executeAppliedStereotypeCommentDeletion(comment);
}
if (comment.getTargetEdges() != null) {
// If the Target View is null then remove the Comment View
if (eventType == Notification.REMOVE && notification.getOldValue().equals(hostView) && comment.getTargetEdges().size() == 0) {
- executeAppliedStereotypeCommentDeletion(hostEditPart.getEditingDomain(), comment);
+ executeAppliedStereotypeCommentDeletion(comment);
}
}
}
@@ -152,12 +149,10 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
for (Stereotype stereotype : stereotypeList) {
refreshStereotypeCompartmentStructure(stereotype);
- getDiagramEventBroker().addNotificationListener(helper.getStereotypeCompartment(comment, stereotype), this);
+ subscribe(helper.getStereotypeCompartment(comment, stereotype));
refreshStereotypeBraceStructure(stereotype);
- getDiagramEventBroker().addNotificationListener(helper.getStereotypeBraceCompartment(comment, stereotype), this);
-
-
+ subscribe(helper.getStereotypeBraceCompartment(comment, stereotype));
}
}
}
@@ -175,8 +170,8 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
if (!stereotypeList.isEmpty()) {
if (null != comment) {
for (Stereotype stereotype : stereotypeList) {
- getDiagramEventBroker().removeNotificationListener(helper.getStereotypeCompartment(comment, stereotype), this);
- getDiagramEventBroker().removeNotificationListener(helper.getStereotypeBraceCompartment(comment, stereotype), this);
+ unsubscribe(helper.getStereotypeCompartment(comment, stereotype));
+ unsubscribe(helper.getStereotypeBraceCompartment(comment, stereotype));
}
}
}
@@ -193,7 +188,7 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
super.refreshStereotypeDisplay();
// If no more Compartment, delete the Comment
if (comment != null && getAppliedStereotypeCompartmentNumber(comment) == 0) {
- executeAppliedStereotypeCommentDeletion(hostEditPart.getEditingDomain(), comment);
+ executeAppliedStereotypeCommentDeletion(comment);
}
}
@@ -376,30 +371,10 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
*/
protected void executeAppliedStereotypeCompartmentCreation(final IGraphicalEditPart editPart, final Stereotype stereotype, final String type) {
- try {
- editPart.getEditingDomain().runExclusive(new Runnable() {
-
- public void run() {
- Display.getCurrent().syncExec(new Runnable() {
-
-
- public void run() {
- CreateAppliedStereotypeCompartmentCommand command = new CreateAppliedStereotypeCompartmentCommand(editPart.getEditingDomain(), comment, stereotype, type);
-
- // use to avoid to put it in the command stack
- try {
- GMFUnsafe.write(editPart.getEditingDomain(), command);
- } catch (Exception e) {
- Activator.log.error(e);
- }
- }
- });
+ CreateAppliedStereotypeCompartmentCommand command = new CreateAppliedStereotypeCompartmentCommand(editPart.getEditingDomain(), comment, stereotype, type);
- }
- });
- } catch (Exception e) {
- Activator.log.error(e);
- }
+ // Record for undo if possible, otherwise unprotected
+ execute(command);
}
@@ -415,29 +390,9 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
*/
protected void executeAppliedStereotypePropertyViewCreation(final IGraphicalEditPart editPart, final Node compartment, final Property stereotypeProperty) {
- try {
- editPart.getEditingDomain().runExclusive(new Runnable() {
-
- public void run() {
- Display.getCurrent().syncExec(new Runnable() {
-
- public void run() {
-
- // use to avoid to put it in the command stack
- CreateAppliedStereotypePropertyViewCommand command = new CreateAppliedStereotypePropertyViewCommand(editPart.getEditingDomain(), compartment, stereotypeProperty, StereotypeDisplayConstant.STEREOTYPE_PROPERTY_TYPE);
- try {
- GMFUnsafe.write(editPart.getEditingDomain(), command);
- } catch (Exception e) {
- Activator.log.error(e);
- }
- }
- });
- }
- });
-
- } catch (Exception e) {
- Activator.log.error(e);
- }
+ // Record for undo if possible, otherwise unprotected
+ CreateAppliedStereotypePropertyViewCommand command = new CreateAppliedStereotypePropertyViewCommand(editPart.getEditingDomain(), compartment, stereotypeProperty, StereotypeDisplayConstant.STEREOTYPE_PROPERTY_TYPE);
+ execute(command);
}
@@ -454,71 +409,50 @@ public class AppliedStereotypeCommentEditPolicy extends AppliedStereotypeNodeLab
protected void executeAppliedStereotypeCommentCreation(final EObject node) {
final TransactionalEditingDomain domain = hostEditPart.getEditingDomain();
- Display.getCurrent().syncExec(new Runnable() {
-
- public void run() {
- int x = 200;
- int y = 100;
- if (hostEditPart.getModel() instanceof Node) {
- LayoutConstraint constraint = ((Node) hostEditPart.getModel()).getLayoutConstraint();
- if (constraint instanceof Bounds) {
- x = x + ((Bounds) constraint).getX();
- y = ((Bounds) constraint).getY();
- }
- }
- if (hostEditPart.getModel() instanceof Edge && ((((Edge) hostEditPart.getModel()).getSource()) instanceof Node)) {
+ int x = 200;
+ int y = 100;
+ if (hostEditPart.getModel() instanceof Node) {
+ LayoutConstraint constraint = ((Node) hostEditPart.getModel()).getLayoutConstraint();
+ if (constraint instanceof Bounds) {
+ x = x + ((Bounds) constraint).getX();
+ y = ((Bounds) constraint).getY();
+ }
- LayoutConstraint constraint = ((Node) ((Edge) hostEditPart.getModel()).getSource()).getLayoutConstraint();
- if (constraint instanceof Bounds) {
- x = x + ((Bounds) constraint).getX();
- y = ((Bounds) constraint).getY() - 100;
- }
+ }
+ if (hostEditPart.getModel() instanceof Edge && ((((Edge) hostEditPart.getModel()).getSource()) instanceof Node)) {
- }
- boolean isBorderElement = false;
- if (hostEditPart instanceof BorderedBorderItemEditPart) {
- isBorderElement = true;
- }
- if (helper.getStereotypeComment((View) getHost().getModel()) == null) {
- CreateAppliedStereotypeCommentViewCommand command = new CreateAppliedStereotypeCommentViewCommand(domain, (View) hostEditPart.getModel(), x, y, node, isBorderElement);
- // use to avoid to put it in the command stack
- try {
- GMFUnsafe.write(domain, command);
- } catch (Exception e) {
- Activator.log.error(e);
- }
- }
+ LayoutConstraint constraint = ((Node) ((Edge) hostEditPart.getModel()).getSource()).getLayoutConstraint();
+ if (constraint instanceof Bounds) {
+ x = x + ((Bounds) constraint).getX();
+ y = ((Bounds) constraint).getY() - 100;
}
- });
+ }
+ boolean isBorderElement = false;
+ if (hostEditPart instanceof BorderedBorderItemEditPart) {
+ isBorderElement = true;
+ }
+ if (helper.getStereotypeComment((View) getHost().getModel()) == null) {
+ CreateAppliedStereotypeCommentViewCommand command = new CreateAppliedStereotypeCommentViewCommand(domain, (View) hostEditPart.getModel(), x, y, node, isBorderElement);
+ // Record for undo if possible, otherwise unprotected
+ execute(command);
+ }
}
/**
* In Charge to delete the Comment Node.
*
- * @param domain
- * the transactional editing domain
* @param commentNode
* the view that represent the comment of stereotype
*/
-
- protected void executeAppliedStereotypeCommentDeletion(final TransactionalEditingDomain domain, final View commentNode) {
- Display.getCurrent().syncExec(new Runnable() {
-
- public void run() {
- // because it is asynchrony the comment node maybe become s null
- if (commentNode != null && TransactionUtil.getEditingDomain(commentNode) != null) {
- DeleteCommand command = new DeleteCommand(commentNode);
- // use to avoid to put it in the command stack
- try {
- GMFUnsafe.write(domain, command);
- } catch (Exception e) {
- Activator.log.error(e);
- }
- }
- }
- });
+ protected void executeAppliedStereotypeCommentDeletion(final View commentNode) {
+ // because it is asynchronous the comment node maybe become s null
+ if (commentNode != null && TransactionUtil.getEditingDomain(commentNode) != null) {
+ DeleteCommand command = new DeleteCommand(commentNode);
+ // Record for undo if possible, otherwise unprotected
+ execute(command);
+ }
}
/**
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCompartmentEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCompartmentEditPolicy.java
index 200eb779d27..28a8dc6b181 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCompartmentEditPolicy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/editpolicies/AppliedStereotypeCompartmentEditPolicy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2012, 2014 CEA LIST and others.
+ * Copyright (c) 2012, 2016 CEA LIST, Christian W. Damus, and others.
*
*
* All rights reserved. This program and the accompanying materials
@@ -12,6 +12,7 @@
* Christian W. Damus (CEA) - bug 323802
* Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.fr - Bug 393532
* Celine Janssens (ALL4TEC) celine.janssens@all4tec.net - Bug 455311 : Refactor Stereotypes Display
+ * Christian W. Damus - bug 492482
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.stereotype.edition.editpolicies;
@@ -22,14 +23,11 @@ import org.eclipse.gmf.runtime.notation.BasicCompartment;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.gmfdiag.common.editpart.IPapyrusEditPart;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.GMFUnsafe;
-import org.eclipse.papyrus.uml.diagram.common.Activator;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.AppliedStereotypeNodeLabelDisplayEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.figure.node.IPapyrusNodeUMLElementFigure;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.command.CreateAppliedStereotypeCompartmentCommand;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.command.CreateAppliedStereotypePropertyViewCommand;
import org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper.StereotypeDisplayConstant;
-import org.eclipse.swt.widgets.Display;
import org.eclipse.uml2.uml.Extension;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;
@@ -66,7 +64,7 @@ public class AppliedStereotypeCompartmentEditPolicy extends AppliedStereotypeNod
if (!stereotypeList.isEmpty()) {
for (Stereotype stereotype : stereotypeList) {
refreshStereotypeCompartmentStructure(stereotype);
- getDiagramEventBroker().addNotificationListener(helper.getStereotypeCompartment(hostView, stereotype), this);
+ subscribe(helper.getStereotypeCompartment(hostView, stereotype));
}
}
@@ -93,11 +91,10 @@ public class AppliedStereotypeCompartmentEditPolicy extends AppliedStereotypeNod
Node compartment = helper.getStereotypeCompartment(hostView, stereotype);
if (null != compartment && null != stereotype) {
- getDiagramEventBroker().removeNotificationListener(compartment, this);
+ unsubscribe(compartment);
EList<Property> properties = stereotype.allAttributes();
for (Property property : properties) {
- getDiagramEventBroker().removeNotificationListener(helper.getStereotypeProperty(hostView, stereotype, property), this);
-
+ unsubscribe(helper.getStereotypeProperty(hostView, stereotype, property));
}
@@ -154,7 +151,7 @@ public class AppliedStereotypeCompartmentEditPolicy extends AppliedStereotypeNod
EList<Property> properties = stereotype.allAttributes();
for (Property property : properties) {
createAppliedStereotypeProperty(compartment, property);
- getDiagramEventBroker().addNotificationListener(helper.getStereotypeProperty(hostView, stereotype, property), this);
+ subscribe(helper.getStereotypeProperty(hostView, stereotype, property));
}
@@ -193,33 +190,11 @@ public class AppliedStereotypeCompartmentEditPolicy extends AppliedStereotypeNod
* @param appliedstereotype
* the stereotype application
*/
-
protected void executeAppliedStereotypeCompartmentCreation(final IGraphicalEditPart editPart, final Stereotype stereotype) {
- try {
- editPart.getEditingDomain().runExclusive(new Runnable() {
-
-
- public void run() {
- Display.getCurrent().syncExec(new Runnable() {
-
+ CreateAppliedStereotypeCompartmentCommand command = new CreateAppliedStereotypeCompartmentCommand(editPart.getEditingDomain(), editPart.getNotationView(), stereotype, StereotypeDisplayConstant.STEREOTYPE_COMPARTMENT_TYPE);
- public void run() {
- CreateAppliedStereotypeCompartmentCommand command = new CreateAppliedStereotypeCompartmentCommand(editPart.getEditingDomain(), editPart.getNotationView(), stereotype, StereotypeDisplayConstant.STEREOTYPE_COMPARTMENT_TYPE);
-
- // use to avoid to put it in the command stack
- try {
- GMFUnsafe.write(editPart.getEditingDomain(), command);
- } catch (Exception e) {
- Activator.log.error(e);
- }
- }
- });
-
- }
- });
- } catch (Exception e) {
- Activator.log.error(e);
- }
+ // Record for undo if possible, otherwise unprotected
+ execute(command);
}
@@ -233,33 +208,11 @@ public class AppliedStereotypeCompartmentEditPolicy extends AppliedStereotypeNod
* @param stereotype
* the stereotype associated to compartment node
*/
-
protected void executeAppliedStereotypePropertyViewCreation(final IGraphicalEditPart editPart, final Node compartment, final Property stereotypeProperty) {
- try {
- editPart.getEditingDomain().runExclusive(new Runnable() {
-
-
- public void run() {
- Display.getCurrent().syncExec(new Runnable() {
-
+ CreateAppliedStereotypePropertyViewCommand command = new CreateAppliedStereotypePropertyViewCommand(editPart.getEditingDomain(), compartment, stereotypeProperty, StereotypeDisplayConstant.STEREOTYPE_PROPERTY_TYPE);
- public void run() {
-
- // use to avoid to put it in the command stack
- CreateAppliedStereotypePropertyViewCommand command = new CreateAppliedStereotypePropertyViewCommand(editPart.getEditingDomain(), compartment, stereotypeProperty, StereotypeDisplayConstant.STEREOTYPE_PROPERTY_TYPE);
- try {
- GMFUnsafe.write(editPart.getEditingDomain(), command);
- } catch (Exception e) {
- Activator.log.error(e);
- }
- }
- });
- }
- });
-
- } catch (Exception e) {
- Activator.log.error(e);
- }
+ // Record for undo if possible, otherwise unprotected
+ execute(command);
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/internal/edithelper/advice/AppliedStereotypeNotationDependentsAdvice.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/internal/edithelper/advice/AppliedStereotypeNotationDependentsAdvice.java
new file mode 100644
index 00000000000..bbe2f46fd96
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.stereotype.edition/src/org/eclipse/papyrus/uml/diagram/stereotype/edition/internal/edithelper/advice/AppliedStereotypeNotationDependentsAdvice.java
@@ -0,0 +1,98 @@
+/*****************************************************************************
+ * 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.papyrus.uml.diagram.stereotype.edition.internal.edithelper.advice;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
+import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
+import org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper.StereotypeDisplayUtil;
+import org.eclipse.uml2.uml.Element;
+
+/**
+ * Dependents advice for deletion of the applied-stereotype views associated with
+ * UML elements being deleted.
+ */
+public class AppliedStereotypeNotationDependentsAdvice extends AbstractEditHelperAdvice {
+
+ /**
+ * Initializes me.
+ */
+ public AppliedStereotypeNotationDependentsAdvice() {
+ super();
+ }
+
+ @Override
+ protected ICommand getAfterDestroyDependentsCommand(DestroyDependentsRequest request) {
+ ICommand result = super.getAfterDestroyDependentsCommand(request);
+
+ EObject element = request.getElementToDestroy();
+ if (element instanceof Element) {
+ Collection<View> appliedStereotypeViews = getAppliedStereotypeViews(element);
+ if (!appliedStereotypeViews.isEmpty()) {
+ ICommand destroy = request.getDestroyDependentsCommand(appliedStereotypeViews);
+
+ if (result == null) {
+ result = destroy;
+ } else {
+ result = result.compose(destroy);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ protected Collection<View> getAppliedStereotypeViews(EObject object) {
+ Collection<View> result = null;
+
+ @SuppressWarnings("unchecked")
+ List<View> views = (List<View>) DiagramEditPartsUtil.getEObjectViews(object);
+ if (!views.isEmpty()) {
+ // Assume three applied-stereotype views for each and on average
+ // one and a half child views also to consider
+ result = new ArrayList<View>(views.size() * 3 * 3 / 2);
+
+ collectAppliedStereotypeViews(new LinkedList<View>(views), result, StereotypeDisplayUtil.getInstance());
+ }
+
+
+ return (result == null) ? Collections.<View> emptyList() : result;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void collectAppliedStereotypeViews(Queue<View> views, Collection<? super View> result, StereotypeDisplayUtil helper) {
+ for (View next = views.poll(); next != null; next = views.poll()) {
+ Node comment = helper.getStereotypeComment(next);
+ if (comment != null) {
+ result.add(comment);
+ result.addAll(comment.getSourceEdges());
+ result.addAll(comment.getTargetEdges());
+ }
+
+ // Add its children to the work queue
+ views.addAll(next.getChildren());
+ }
+ }
+}
diff --git a/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/listeners/StereotypeElementListener.java b/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/listeners/StereotypeElementListener.java
index 5b035036e75..7505329b864 100644
--- a/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/listeners/StereotypeElementListener.java
+++ b/plugins/uml/tools/org.eclipse.papyrus.uml.tools/src/org/eclipse/papyrus/uml/tools/listeners/StereotypeElementListener.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014 CEA LIST, Christian W. Damus, and others.
+ * Copyright (c) 2014, 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
@@ -9,15 +9,22 @@
* Contributors:
* Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Initial API and implementation
* Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.fr - Bug 393532
- * Christian W. Damus - bug 450523
- * Christian W. Damus - bug 399859
+ * Christian W. Damus - bugs 450523, 399859, 492482
*
*****************************************************************************/
package org.eclipse.papyrus.uml.tools.listeners;
+import java.util.ArrayList;
import java.util.List;
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.notify.impl.NotificationChainImpl;
+import org.eclipse.emf.common.notify.impl.NotificationImpl;
+import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
@@ -30,6 +37,7 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.transaction.NotificationFilter;
import org.eclipse.emf.transaction.ResourceSetChangeEvent;
import org.eclipse.emf.transaction.ResourceSetListenerImpl;
+import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Extension;
@@ -76,24 +84,79 @@ public class StereotypeElementListener extends ResourceSetListenerImpl {
}
/**
- * Resource set changed.
+ * I am a pre-commit listener. Trigger listeners need to be able to react to
+ * these events. And they will be captured and automatically distributed again
+ * when the transaction commits (if it doesn't roll back).
*
- * @param event
- * the event
- * @see org.eclipse.emf.transaction.ResourceSetListenerImpl#resourceSetChanged(org.eclipse.emf.transaction.ResourceSetChangeEvent)
+ * @return {@code true}
*/
@Override
- public void resourceSetChanged(ResourceSetChangeEvent event) {
+ public boolean isPrecommitOnly() {
+ return true;
+ }
- // Get filtered notifications
- List<Notification> filteredNotificationsList = event.getNotifications();
+ @Override
+ public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException {
+ Command result = null;
- // Handle each filtered notification
- for (Notification notification : filteredNotificationsList) {
- handleFilteredNotification(notification);
- }
+ if (!event.getNotifications().isEmpty()) {
+ // Get filtered notifications
+ final NotificationChain chain = new NotificationChainImpl();
+ List<Notification> filteredNotificationsList = new ArrayList<Notification>(event.getNotifications());
+
+ // Handle each filtered notification
+ for (Notification notification : filteredNotificationsList) {
+ handleFilteredNotification(notification, chain);
+ }
+
+ result = new AbstractCommand("Inject Stereotype Notifications") {
+ private NotificationChain notifications;
+
+ @Override
+ protected boolean prepare() {
+ this.notifications = chain;
+ return true;
+ }
+
+ @Override
+ public void execute() {
+ dispatchAndInvert();
+ }
+
+ @Override
+ public void undo() {
+ dispatchAndInvert();
+ }
+
+ @Override
+ public void redo() {
+ dispatchAndInvert();
+ }
+
+ private void dispatchAndInvert() {
+ notifications.dispatch();
+ this.notifications = invertNotifications(notifications);
+ }
+
+ private NotificationChain invertNotifications(NotificationChain notifications) {
+ // The chain is implemented as an EList
+ @SuppressWarnings("unchecked")
+ EList<Notification> list = (EList<Notification>) notifications;
+ // Reverse the order
+ ECollections.reverse(list);
+ // And flip the type from applied <--> unapplied
+ for (Notification next : list) {
+ ((StereotypeExtensionNotification) next).invert();
+ }
+
+ return notifications;
+ }
+ };
+ }
+
+ return result;
}
/**
@@ -101,9 +164,10 @@ public class StereotypeElementListener extends ResourceSetListenerImpl {
*
* @param notification
* the notification
+ * @param notifications
+ * a notification chain on which to collect notifications for later dispatch. If {@code null}, then dispatch immediately
*/
- private void handleFilteredNotification(Notification notification) {
-
+ private void handleFilteredNotification(Notification notification, NotificationChain notifications) {
final Object notifier = notification.getNotifier();
Element extendedElement = null;
@@ -150,6 +214,7 @@ public class StereotypeElementListener extends ResourceSetListenerImpl {
case StereotypeExtensionNotification.MODIFIED_STEREOTYPE_OF_ELEMENT:
// New value is the modified element
newValue = notification.getNewValue();
+ oldValue = notification.getOldValue();
break;
default:
// Nothing to do
@@ -158,8 +223,13 @@ public class StereotypeElementListener extends ResourceSetListenerImpl {
// Bug 450523: If element is null, the notification has already been sent. Simply ignore this case
if (element != null) {
- element.eNotify(
- new StereotypeExtensionNotification(element, eventType, oldValue, newValue, stereotype));
+ NotificationImpl newNotification = new StereotypeExtensionNotification(element, eventType, oldValue, newValue, stereotype);
+ if (notifications == null) {
+ // Dispatch it now
+ newNotification.dispatch();
+ } else {
+ notifications.add(newNotification);
+ }
}
}
@@ -398,6 +468,28 @@ public class StereotypeElementListener extends ResourceSetListenerImpl {
public Stereotype getStereotype() {
return stereotype;
}
+
+ /**
+ * Flips an "applied" notification to "unapplied" and vice versa.
+ */
+ void invert() {
+ switch (getEventType()) {
+ case STEREOTYPE_APPLIED_TO_ELEMENT:
+ eventType = STEREOTYPE_UNAPPLIED_FROM_ELEMENT;
+ break;
+ case STEREOTYPE_UNAPPLIED_FROM_ELEMENT:
+ eventType = STEREOTYPE_APPLIED_TO_ELEMENT;
+ break;
+ default:
+ // Stereotype-modified events are their own inverses
+ break;
+ }
+
+ // Swap the old and new values
+ Object swap = oldValue;
+ oldValue = newValue;
+ newValue = swap;
+ }
}
}

Back to the top