Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2018-04-19 09:56:54 -0400
committerChristian W. Damus2018-04-25 09:44:17 -0400
commitfa3a1409f7f679d42834a4e89e1d22dd9c115ebe (patch)
treee89f6aac840c72506c453bbced6bfe810dc02a5b
parentc1206346c848bb4316a8fbfe0d4e788d7f8004eb (diff)
downloadorg.eclipse.papyrus-fa3a1409f7f679d42834a4e89e1d22dd9c115ebe.tar.gz
org.eclipse.papyrus-fa3a1409f7f679d42834a4e89e1d22dd9c115ebe.tar.xz
org.eclipse.papyrus-fa3a1409f7f679d42834a4e89e1d22dd9c115ebe.zip
Bug 533673: [Sequence Diagram] CombinedFragment should be created with one InteractionOperand
Add an edit-helper advice to resize the default operand of a new combined fragment to fill the available space in the combined fragment. As this needs to use the edit-part controlling the operand's presentation to obtain a command that resizes the operand and captures the interaction fragments within its bounds, the execution of this advice command is deferred and captured back into the original context for undo/redo. Change-Id: Ifebab84b5b2181bea36d1cd60bf1f9f61adc4fe3 Signed-off-by: Christian W. Damus <give.a.damus@gmail.com>
-rw-r--r--plugins/uml/architecture/org.eclipse.papyrus.uml.architecture/model/uml.architecture1
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/AsynchronousCommand.java142
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java120
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/RetryingDeferredAction.java200
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/SequenceDiagram.elementtypesconfigurations6
-rw-r--r--tests/junit/framework/org.eclipse.papyrus.junit.utils/META-INF/MANIFEST.MF2
-rw-r--r--tests/junit/framework/org.eclipse.papyrus.junit.utils/pom.xml2
-rw-r--r--tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/matchers/DiagramMatchers.java94
-rw-r--r--tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java128
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.classpath2
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.settings/org.eclipse.jdt.core.prefs6
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/META-INF/MANIFEST.MF4
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.di2
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.notation66
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.uml21
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java30
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java111
17 files changed, 908 insertions, 29 deletions
diff --git a/plugins/uml/architecture/org.eclipse.papyrus.uml.architecture/model/uml.architecture b/plugins/uml/architecture/org.eclipse.papyrus.uml.architecture/model/uml.architecture
index b052358d667..fa717597fd8 100644
--- a/plugins/uml/architecture/org.eclipse.papyrus.uml.architecture/model/uml.architecture
+++ b/plugins/uml/architecture/org.eclipse.papyrus.uml.architecture/model/uml.architecture
@@ -31,6 +31,7 @@
<elementTypes href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/StandardProfile.elementtypesconfigurations#_jfoLkGT_EeSEqNuV3JpFCA"/>
<elementTypes href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/umldi.elementtypesconfigurations#_ScP1oFYCEeS0WsAAtVmToA"/>
<elementTypes href="platform:/plugin/org.eclipse.papyrus.uml.service.types.ui/model/uml-advice.elementtypesconfigurations#_ScP1oFYCEeS0WsAAtVmToA"/>
+ <elementTypes href="platform:/plugin/org.eclipse.papyrus.uml.diagram.sequence/model/SequenceDiagram.elementtypesconfigurations#_uuwoQENKEeimO7ZhVBpjkg"/>
<representationKinds xsi:type="gmfdiagrepresentation:PapyrusDiagram" xmi:id="_UzcgsHDtEeWh-MssWmCB_A" id="org.eclipse.papyrus.uml.diagram.activity" name="Activity Diagram" icon="platform:/plugin/org.eclipse.papyrus.uml.diagram.activity/icons/obj16/Diagram_Activity.gif" concerns="_HQhf5MSYEeaKZJ_pGfaSiA" implementationID="PapyrusUMLActivityDiagram" creationCommandClass="org.eclipse.papyrus.uml.diagram.activity.CreateActivityDiagramCommand">
<modelRules xmi:id="_UzcgsXDtEeWh-MssWmCB_A">
<element href="http://www.eclipse.org/uml2/5.0.0/UML#//Activity"/>
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/AsynchronousCommand.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/AsynchronousCommand.java
new file mode 100644
index 00000000000..a82671e62f1
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/command/AsynchronousCommand.java
@@ -0,0 +1,142 @@
+/*****************************************************************************
+ * Copyright (c) 2018 Christian W. Damus and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.diagram.sequence.command;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.transaction.RollbackException;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.AbstractCommand;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.common.core.command.UnexecutableCommand;
+import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe;
+import org.eclipse.papyrus.uml.diagram.sequence.part.UMLDiagramEditorPlugin;
+import org.eclipse.papyrus.uml.diagram.sequence.util.RetryingDeferredAction;
+
+/**
+ * A command that posts its execution asynchronously on the UI thread
+ * and captures its undoable action in the original context to support
+ * undo/redo.
+ *
+ * @since 5.0
+ */
+public class AsynchronousCommand extends AbstractCommand {
+
+ private final TransactionalEditingDomain editingDomain;
+ private Supplier<ICommand> futureCommand;
+ private ICommand actualCommand;
+
+ /**
+ * Initializes me with my label and an asynchronous supplier of the command
+ * to be executed.
+ *
+ * @param label
+ * my label
+ * @param editingDomain
+ * my contextual editing domain
+ * @param futureCommand
+ * a supplier of the command. It will be invoked later on
+ * the UI thread to compute the command to be executed then and captured
+ * back into the original context of this GMF command. If the supplied
+ * command is {@code null}, then it will be asynchronously re-tried
+ * up to three times
+ */
+ public AsynchronousCommand(String label, TransactionalEditingDomain editingDomain, Supplier<ICommand> futureCommand) {
+ super(label);
+
+ this.editingDomain = editingDomain;
+ this.futureCommand = futureCommand;
+ }
+
+ /**
+ * Initializes me with my label, affected filesm, and an asynchronous supplier of the command
+ * to be executed.
+ *
+ * @param label
+ * my label
+ * @param affectedFiles
+ * my affected files
+ * @param editingDomain
+ * my contextual editing domain
+ * @param futureCommand
+ * a supplier of the command. It will be invoked later on
+ * the UI thread to compute the command to be executed then and captured
+ * back into the original context of this GMF command. If the supplied
+ * command is {@code null}, then it will be asynchronously re-tried
+ * up to three times
+ */
+ public AsynchronousCommand(String label, @SuppressWarnings("rawtypes") List affectedFiles, TransactionalEditingDomain editingDomain, Supplier<ICommand> futureCommand) {
+ super(label, affectedFiles);
+
+ this.editingDomain = editingDomain;
+ this.futureCommand = futureCommand;
+ }
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException {
+ RetryingDeferredAction.defer(this::captureCommand);
+ return CommandResult.newOKCommandResult();
+ }
+
+ private boolean captureCommand() {
+ this.actualCommand = futureCommand.get();
+
+ if (actualCommand != null) {
+ if (!actualCommand.canExecute()) {
+ // Don't try again
+ actualCommand = UnexecutableCommand.INSTANCE;
+ } else {
+ try {
+ // Execute it, now
+ GMFUnsafe.write(editingDomain, actualCommand);
+ } catch (InterruptedException | RollbackException | ExecutionException e) {
+ UMLDiagramEditorPlugin.log.error("Asynchronous command failed.", e);
+ // Don't try again
+ actualCommand = UnexecutableCommand.INSTANCE;
+ }
+ }
+ }
+
+ return actualCommand != null;
+ }
+
+ @Override
+ protected CommandResult doRedoWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException {
+ if (actualCommand == null) {
+ return CommandResult.newErrorCommandResult("Command execution was not captured"); //$NON-NLS-1$
+ } else if (!actualCommand.canRedo()) {
+ return CommandResult.newCancelledCommandResult();
+ }
+ actualCommand.redo(progressMonitor, info);
+ return actualCommand.getCommandResult();
+ }
+
+ @Override
+ protected CommandResult doUndoWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException {
+ if (actualCommand == null) {
+ return CommandResult.newErrorCommandResult("Command execution was not captured"); //$NON-NLS-1$
+ } else if (!actualCommand.canUndo()) {
+ return CommandResult.newCancelledCommandResult();
+ }
+
+ actualCommand.undo(progressMonitor, info);
+ return actualCommand.getCommandResult();
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java
new file mode 100644
index 00000000000..9dec13b09e2
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java
@@ -0,0 +1,120 @@
+/*****************************************************************************
+ * Copyright (c) 2018 Christian W. Damus and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.diagram.sequence.edit.helpers.advice;
+
+import static org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil.getChildByEObject;
+
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.requests.ChangeBoundsRequest;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
+import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;
+import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.infra.ui.util.EditorHelper;
+import org.eclipse.papyrus.uml.diagram.sequence.UmlSequenceDiagramForMultiEditor;
+import org.eclipse.papyrus.uml.diagram.sequence.command.AsynchronousCommand;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.uml2.uml.CombinedFragment;
+import org.eclipse.uml2.uml.InteractionOperand;
+
+/**
+ * Advice for the configuration of the view of the default interaction operand
+ * in a new combined fragment.
+ */
+public class DefaultInteractionOperandAdvice extends AbstractEditHelperAdvice {
+
+ /**
+ * Initializes me.
+ */
+ public DefaultInteractionOperandAdvice() {
+ super();
+ }
+
+ @Override
+ protected ICommand getAfterConfigureCommand(ConfigureRequest request) {
+ ICommand result = null;
+
+ DiagramEditPart sequenceDiagram = getActiveSequenceDiagram();
+
+ if (sequenceDiagram != null) {
+ CombinedFragment cfrag = (CombinedFragment) request.getElementToConfigure();
+ result = new AsynchronousCommand("Configure Default Operand", request.getEditingDomain(),
+ () -> configureOperand(cfrag, sequenceDiagram));
+ }
+
+ return result;
+ }
+
+ protected DiagramEditPart getActiveSequenceDiagram() {
+ DiagramEditPart result = null;
+
+ IEditorPart editor = EditorHelper.getCurrentEditor();
+ if (editor instanceof IMultiDiagramEditor) {
+ editor = ((IMultiDiagramEditor) editor).getActiveEditor();
+ }
+
+ if (editor instanceof UmlSequenceDiagramForMultiEditor) {
+ result = ((UmlSequenceDiagramForMultiEditor) editor).getDiagramEditPart();
+ }
+
+ return result;
+ }
+
+ protected ICommand configureOperand(CombinedFragment cfrag, DiagramEditPart diagram) {
+ if (cfrag.getOperands().size() != 1) {
+ return null;
+ }
+ InteractionOperand operand = cfrag.getOperands().get(0);
+
+ IGraphicalEditPart cfragShape = getChildByEObject(cfrag, diagram, false);
+ if (cfragShape == null) {
+ return null;
+ }
+
+ IGraphicalEditPart operandShape = getChildByEObject(operand, cfragShape, false);
+ if (operandShape == null) {
+ return null;
+ }
+
+ return fill(operandShape, cfragShape);
+ }
+
+ protected ICommand fill(IGraphicalEditPart operand, IGraphicalEditPart cfrag) {
+ Rectangle cfragBounds = cfrag.getFigure().getBounds();
+ Rectangle operandBounds = operand.getFigure().getBounds();
+
+ if (cfragBounds.height() <= 0 || operandBounds.height() <= 0) {
+ // Initial layout not computed, yet
+ return null;
+ }
+
+ // Subtract one to avoid scroll bars
+ int operandHeight = cfragBounds.y() + cfragBounds.height() - operandBounds.y() - 1;
+
+ ChangeBoundsRequest request = new ChangeBoundsRequest(RequestConstants.REQ_RESIZE);
+ request.setSizeDelta(new Dimension(0, operandHeight - operandBounds.height()));
+ request.setResizeDirection(PositionConstants.SOUTH);
+ request.setSnapToEnabled(false);
+ request.setEditParts(operand);
+ org.eclipse.gef.commands.Command command = operand.getCommand(request);
+ return (command == null) ? null : new CommandProxy(command);
+ }
+
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/RetryingDeferredAction.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/RetryingDeferredAction.java
new file mode 100644
index 00000000000..6c38f53e55c
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/util/RetryingDeferredAction.java
@@ -0,0 +1,200 @@
+/*****************************************************************************
+ * Copyright (c) 2018 Christian W. Damus and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.diagram.sequence.util;
+
+import java.util.function.BooleanSupplier;
+
+import org.eclipse.papyrus.uml.diagram.sequence.part.UMLDiagramEditorPlugin;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A deferred action that posts itself asynchronously on the {@link Display} thread
+ * and re-tries some limited number of times if its initial conditions are not met.
+ *
+ * @since 5.0
+ */
+public abstract class RetryingDeferredAction {
+ private static final int DEFAULT_RETRY_LIMIT = 3;
+
+ private final Display display;
+ private final int retryLimit;
+ private volatile int retries;
+
+ /**
+ * Initializes me.
+ *
+ * @param display
+ * the display on which I post myself for delayed execution
+ * @param retryLimit
+ * the number of times I may retry
+ *
+ * @throws IllegalArgumentException
+ * if the retry limit is non-positive
+ */
+ public RetryingDeferredAction(Display display, int retryLimit) {
+ super();
+
+ if (retryLimit <= 0) {
+ throw new IllegalArgumentException("retry limit must be positive"); //$NON-NLS-1$
+ }
+
+ this.display = display;
+ this.retryLimit = retryLimit;
+ }
+
+ /**
+ * Initializes me with the default number (three) of retries.
+ *
+ * @param display
+ * the display on which I post myself for delayed execution
+ */
+ public RetryingDeferredAction(Display display) {
+ this(display, DEFAULT_RETRY_LIMIT);
+ }
+
+ /**
+ * Initializes me with the current display.
+ *
+ * @param retryLimit
+ * the number of times I may retry
+ *
+ * @throws IllegalArgumentException
+ * if the retry limit is non-positive
+ */
+ public RetryingDeferredAction(int retryLimit) {
+ this(Display.getCurrent(), retryLimit);
+ }
+
+ /**
+ * Initializes me with the current display and the default number (three) of retries.
+ */
+ public RetryingDeferredAction() {
+ this(Display.getCurrent(), DEFAULT_RETRY_LIMIT);
+ }
+
+ /**
+ * Try an {@code action} up to the given number of times, deferred on the {@code display} thread.
+ * This is useful for the simple case where it is only necessary to attempt to perform the
+ * action and there is no need for an explicit preparation step.
+ *
+ * @param display
+ * the display on which thread to defer the {@code action}
+ * @param retryLimit
+ * the maximal number of times to tr-try the {@code action}
+ * @param action
+ * the action to perform. If it returns {@code false}, then it will
+ * be re-tried (unless the limit is exceeded, of course)
+ *
+ * @throws IllegalArgumentException
+ * if the retry limit is non-positive
+ */
+ public static void defer(Display display, int retryLimit, BooleanSupplier action) {
+ new Wrapper(display, retryLimit, action).post();
+ }
+
+ /**
+ * Try an {@code action} up to the default number (three) of times, deferred on the {@code display} thread.
+ *
+ * @param display
+ * the display on which thread to defer the {@code action}
+ * @param action
+ * the action to perform
+ */
+ public static void defer(Display display, BooleanSupplier action) {
+ defer(display, DEFAULT_RETRY_LIMIT, action);
+ }
+
+ /**
+ * Try an {@code action} up to the given number of times, deferred on the current display thread.
+ *
+ * @param retryLimit
+ * the maximal number of times to tr-try the {@code action}
+ * @param action
+ * the action to perform
+ *
+ * @throws IllegalArgumentException
+ * if the retry limit is non-positive
+ */
+ public static void defer(int retryLimit, BooleanSupplier action) {
+ defer(Display.getCurrent(), retryLimit, action);
+ }
+
+ /**
+ * Try an {@code action} up to the default number (three) of times, deferred on the current display thread.
+ *
+ * @param action
+ * the action to perform
+ */
+ public static void defer(BooleanSupplier action) {
+ defer(Display.getCurrent(), DEFAULT_RETRY_LIMIT, action);
+ }
+
+ /**
+ * Prepares me for execution, testing my initial conditions and setting up any
+ * required state.
+ *
+ * @return {@code true} if my initial conditions are satisfied and I may {@link #perform()};
+ * {@code false}, otherwise
+ */
+ protected abstract boolean prepare();
+
+ /**
+ * Performs me. Will not be called unless {@link #prepare()} returned {@code true}.
+ */
+ protected abstract void perform();
+
+ private void run() {
+ if (prepare()) {
+ perform();
+ } else {
+ retries = retries + 1;
+ post();
+ }
+ }
+
+ /**
+ * Post me for deferred execution.
+ */
+ public void post() {
+ if (retries < retryLimit) {
+ display.asyncExec(this::run);
+ } else {
+ UMLDiagramEditorPlugin.log.warn("Retry limit exceeded for " + this); //$NON-NLS-1$
+ }
+ }
+
+ //
+ // Nested types
+ //
+
+ private static final class Wrapper extends RetryingDeferredAction {
+ private final BooleanSupplier action;
+
+ Wrapper(Display display, int retryLimit, BooleanSupplier action) {
+ super(display, retryLimit);
+
+ this.action = action;
+ }
+
+ @Override
+ protected boolean prepare() {
+ return action.getAsBoolean();
+ }
+
+ @Override
+ protected void perform() {
+ // Already done in the preparation step
+ }
+ }
+}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/SequenceDiagram.elementtypesconfigurations b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/SequenceDiagram.elementtypesconfigurations
new file mode 100644
index 00000000000..c9a64b7b7b2
--- /dev/null
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/SequenceDiagram.elementtypesconfigurations
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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.2" xmi:id="_uuwoQENKEeimO7ZhVBpjkg" description="Notational edit-helper advices for the Sequence Diagram." identifier="org.eclipse.papyrus.uml.diagram.sequence.advice" name="Sequence Diagram Advice" metamodelNsURI="http://www.eclipse.org/uml2/5.0.0/UML">
+ <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_BvoRIENLEeimO7ZhVBpjkg" description="Advice for configuration of the view for the default operand of a new combined fragment." identifier="org.eclipse.papyrus.uml.diagram.sequence.edit.helpers.advice.defaultInteractionOperand" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrus.uml.diagram.sequence.edit.helpers.advice.DefaultInteractionOperandAdvice">
+ <target xsi:type="elementtypesconfigurations:SpecializationTypeConfiguration" href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/umldi.elementtypesconfigurations#org.eclipse.papyrus.umldi.CombinedFragment_Shape"/>
+ </adviceBindingsConfigurations>
+</elementtypesconfigurations:ElementTypeSetConfiguration>
diff --git a/tests/junit/framework/org.eclipse.papyrus.junit.utils/META-INF/MANIFEST.MF b/tests/junit/framework/org.eclipse.papyrus.junit.utils/META-INF/MANIFEST.MF
index ae9fb6a3aea..4aa07cbba3d 100644
--- a/tests/junit/framework/org.eclipse.papyrus.junit.utils/META-INF/MANIFEST.MF
+++ b/tests/junit/framework/org.eclipse.papyrus.junit.utils/META-INF/MANIFEST.MF
@@ -18,7 +18,7 @@ Export-Package: org.eclipse.papyrus.junit.matchers,
org.eclipse.papyrus.junit.utils.tests
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
-Bundle-Version: 2.1.100.qualifier
+Bundle-Version: 2.2.0.qualifier
Bundle-Name: %Bundle-Name
Bundle-ManifestVersion: 2
Bundle-Activator: org.eclipse.papyrus.junit.utils.Activator
diff --git a/tests/junit/framework/org.eclipse.papyrus.junit.utils/pom.xml b/tests/junit/framework/org.eclipse.papyrus.junit.utils/pom.xml
index fc9d6273c58..6fe2b567abc 100644
--- a/tests/junit/framework/org.eclipse.papyrus.junit.utils/pom.xml
+++ b/tests/junit/framework/org.eclipse.papyrus.junit.utils/pom.xml
@@ -7,6 +7,6 @@
</parent>
<groupId>org.eclipse.papyrus</groupId>
<artifactId>org.eclipse.papyrus.junit.utils</artifactId>
- <version>2.1.100-SNAPSHOT</version>
+ <version>2.2.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project> \ No newline at end of file
diff --git a/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/matchers/DiagramMatchers.java b/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/matchers/DiagramMatchers.java
index b78720e078a..f46dd40d599 100644
--- a/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/matchers/DiagramMatchers.java
+++ b/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/matchers/DiagramMatchers.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 CEA and others.
+ * Copyright (c) 2014, 2018 CEA, Christian W. Damus, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,17 +8,21 @@
*
* Contributors:
* Christian W. Damus (CEA) - Initial API and implementation
+ * Christian W. Damus - bug 533673
*
*/
package org.eclipse.papyrus.junit.matchers;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.ui.palette.PaletteViewer;
+import org.eclipse.gmf.runtime.notation.View;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
/**
@@ -51,6 +55,86 @@ public class DiagramMatchers {
return new DrawerExpansion(viewer, false);
}
+ /**
+ * Match an edit-part by some condition of its notation view.
+ *
+ * @param viewMatcher
+ * view matcher condition
+ *
+ * @since 2.2
+ */
+ public static Matcher<EditPart> viewThat(Matcher<? super View> viewMatcher) {
+ return new TypeSafeDiagnosingMatcher<EditPart>() {
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("view that ").appendDescriptionOf(viewMatcher);
+ }
+
+ @Override
+ protected boolean matchesSafely(EditPart item, Description mismatchDescription) {
+ boolean result = false;
+
+ if (!(item.getModel() instanceof View)) {
+ mismatchDescription.appendText("edit-part model is not a notation view");
+ } else {
+ View view = (View) item.getModel();
+ result = viewMatcher.matches(view);
+ if (!result) {
+ viewMatcher.describeMismatch(view, mismatchDescription);
+ }
+ }
+
+ return result;
+ }
+ };
+ }
+
+ /**
+ * Match a notation view by some condition of its semantic element.
+ *
+ * @param elementMatcher
+ * element matcher condition
+ *
+ * @since 2.2
+ */
+ public static Matcher<View> elementThat(Matcher<? super EObject> elementMatcher) {
+ return new TypeSafeDiagnosingMatcher<View>() {
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("element that ").appendDescriptionOf(elementMatcher);
+ }
+
+ @Override
+ protected boolean matchesSafely(View item, Description mismatchDescription) {
+ boolean result = false;
+
+ EObject element = item.getElement();
+ if (element == null) {
+ mismatchDescription.appendText("view has no semantic element");
+ } else {
+ result = elementMatcher.matches(element);
+ if (!result) {
+ elementMatcher.describeMismatch(element, mismatchDescription);
+ }
+ }
+
+ return result;
+ }
+ };
+ }
+
+ /**
+ * Match an edit-part by some condition of its semantic element.
+ *
+ * @param elementMatcher
+ * element matcher condition
+ *
+ * @since 2.2
+ */
+ public static Matcher<EditPart> semanticThat(Matcher<? super EObject> elementMatcher) {
+ return viewThat(elementThat(elementMatcher));
+ }
+
//
// Nested types
//
@@ -63,12 +147,14 @@ public class DiagramMatchers {
super();
}
+ @Override
public void describeTo(Description description) {
description.appendText("edit-part is selected");
}
+ @Override
public boolean matches(Object item) {
- return (item instanceof EditPart) && isSelected((EditPart)item);
+ return (item instanceof EditPart) && isSelected((EditPart) item);
}
boolean isSelected(EditPart editPart) {
@@ -88,13 +174,15 @@ public class DiagramMatchers {
this.expanded = expanded;
}
+ @Override
public void describeTo(Description description) {
description.appendText("drawer is ");
description.appendText(expanded ? "expanded" : "collapsed");
}
+ @Override
public boolean matches(Object item) {
- return (item instanceof PaletteDrawer) && (isExpanded((PaletteDrawer)item) == expanded);
+ return (item instanceof PaletteDrawer) && (isExpanded((PaletteDrawer) item) == expanded);
}
boolean isExpanded(PaletteDrawer drawer) {
diff --git a/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java b/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java
index a061a4b3240..4a972e13e7e 100644
--- a/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java
+++ b/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014, 2017 CEA, Christian W. Damus, and others.
+ * Copyright (c) 2014, 2018 CEA, Christian W. Damus, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,7 +8,7 @@
*
* Contributors:
* Christian W. Damus (CEA) - Initial API and implementation
- * Christian W. Damus - bugs 433206, 465416, 434983, 483721, 469188, 485220, 491542, 497865
+ * Christian W. Damus - bugs 433206, 465416, 434983, 483721, 469188, 485220, 491542, 497865, 533673
* Thanh Liem PHAN (ALL4TEC) thanhliem.phan@all4tec.net - Bug 521550
*****************************************************************************/
package org.eclipse.papyrus.junit.utils.rules;
@@ -23,6 +23,10 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IOperationHistoryListener;
@@ -64,10 +68,16 @@ import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.commands.SetBoundsCommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IDiagramPreferenceSupport;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeCompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditorWithFlyOutPalette;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequestFactory;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.Shape;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
@@ -122,6 +132,7 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
/**
@@ -430,7 +441,7 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
List<IMultiDiagramEditor> result = Lists.newArrayList();
for (Resource resource : initModelResources(description)) {
- if(resource.getURI().fileExtension().equals(UmlModel.UML_FILE_EXTENSION)){
+ if (resource.getURI().fileExtension().equals(UmlModel.UML_FILE_EXTENSION)) {
IFile papyrusModel = getProject().getFile(resource.getURI().trimFileExtension().appendFileExtension(DiModel.DI_FILE_EXTENSION));
modelFiles.put(description, papyrusModel);
result.add(open(papyrusModel));
@@ -927,6 +938,51 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
return findEditPart(diagram, modelElement);
}
+ /**
+ * Get the shape compartment of an edit-part. Fails if the edit-part has no
+ * shape compartment.
+ *
+ * @param shapeEditPart
+ * a shape edit part
+ * @return its shape compartment
+ *
+ * @since 2.2
+ */
+ public EditPart getShapeCompartment(EditPart shapeEditPart) {
+ return stream(shapeEditPart.getChildren(), EditPart.class)
+ .filter(ShapeCompartmentEditPart.class::isInstance)
+ .findFirst().orElseGet(failOnAbsence("No shape compartment"));
+ }
+
+ /**
+ * Obtain a typed stream over a raw-typed collection from a legacy pre-generics API
+ * such as GEF.
+ *
+ * @param rawCollection
+ * a raw-typed collection
+ * @param type
+ * the expected element type of the collection
+ * @return the typed stream
+ */
+ private static <T> Stream<T> stream(@SuppressWarnings("rawtypes") Collection rawCollection, Class<T> type) {
+ return ((Collection<?>) rawCollection).stream()
+ .filter(type::isInstance).map(type::cast);
+ }
+
+ /**
+ * Obtain a fake supplier that just fails the test with the given {@code message}
+ * instead of supplying a result.
+ *
+ * @param message
+ * the failure message
+ * @return the fake supplier
+ */
+ private static <T> Supplier<T> failOnAbsence(String message) {
+ return () -> {
+ fail(message);
+ return null;
+ };
+ }
/**
* Find orphan edit part with a type.
@@ -1104,6 +1160,7 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
}
public void execute(org.eclipse.gef.commands.Command command) {
+ assertThat("No command", command, notNullValue());
assertThat("Command not executable", command.canExecute(), is(true));
getActiveDiagramEditor().getDiagramEditDomain().getDiagramCommandStack().execute(command);
flushDisplayEvents();
@@ -1154,7 +1211,7 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
public void flushDisplayEvents() {
for (;;) {
try {
- if (Display.getCurrent()!=null && !Display.getCurrent().readAndDispatch()) {
+ if (Display.getCurrent() != null && !Display.getCurrent().readAndDispatch()) {
break;
}
} catch (Exception e) {
@@ -1412,4 +1469,67 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
}
});
}
+
+ /**
+ * Create a new shape in the {@code parent}. Fails if the shape cannot be created or
+ * cannot be found in the diagram after creation.
+ *
+ * @param parent
+ * the parent edit-part in which to create a shape
+ * @param type
+ * the type of shape to create
+ * @param location
+ * the location (mouse pointer) at which to create the shape
+ * @param size
+ * the size of the shape to create
+ * @return the newly created shape edit-part
+ *
+ * @since 2.2
+ */
+ public EditPart createShape(EditPart parent, IElementType type, Point location, Dimension size) {
+ CreateViewRequest request = CreateViewRequestFactory.getCreateShapeRequest(type, ((IGraphicalEditPart) parent).getDiagramPreferencesHint());
+
+ // Collect existing children
+ Set<EditPart> initialChildren = stream(parent.getChildren(), EditPart.class).collect(Collectors.toSet());
+ request.setLocation(location);
+ request.setSize(size);
+ org.eclipse.gef.commands.Command command = parent.getCommand(request);
+ execute(command);
+
+ // Find the new edit-part
+ Set<EditPart> children = stream(parent.getChildren(), EditPart.class).collect(Collectors.toSet());
+ return Sets.difference(children, initialChildren).stream()
+ .filter(ep -> ep.getModel() instanceof Shape)
+ .findAny().orElseGet(failOnAbsence("Could not find new shape edit-part"));
+ }
+
+ /**
+ * Create a point location (useful as a static import for test readability).
+ *
+ * @param x
+ * the x co├Ârdinate
+ * @param y
+ * the y co├Ârdinate
+ * @return the point
+ *
+ * @since 2.2
+ */
+ public static Point at(int x, int y) {
+ return new Point(x, y);
+ }
+
+ /**
+ * Create a size dimension (useful as a static import for test readability).
+ *
+ * @param width
+ * the size width
+ * @param height
+ * the the size height
+ * @return the size
+ *
+ * @since 2.2
+ */
+ public static Dimension sized(int width, int height) {
+ return new Dimension(width, height);
+ }
}
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.classpath b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.classpath
index 098194ca4b7..eca7bdba8f0 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.classpath
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.classpath
@@ -1,6 +1,6 @@
<?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.7"/>
+ <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"/>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.settings/org.eclipse.jdt.core.prefs b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.settings/org.eclipse.jdt.core.prefs
index f08be2b06c4..b3aa6d60f94 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/.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.7
-org.eclipse.jdt.core.compiler.compliance=1.7
+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.7
+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/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/META-INF/MANIFEST.MF b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/META-INF/MANIFEST.MF
index 31e524ee2b1..1198a3d4a76 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/META-INF/MANIFEST.MF
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/META-INF/MANIFEST.MF
@@ -14,7 +14,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.papyrus.infra.emf.appearance;bundle-version="[2.0.0,3.0.0)",
org.eclipse.papyrus.infra.viewpoints.policy;bundle-version="[3.0.0,4.0.0)",
org.eclipse.papyrus.junit.framework;bundle-version="[1.2.0,2.0.0)",
- org.eclipse.papyrus.junit.utils;bundle-version="[2.0.0,3.0.0)",
+ org.eclipse.papyrus.junit.utils;bundle-version="[2.2.0,3.0.0)",
org.eclipse.papyrus.infra.properties.ui;bundle-version="[3.0.0,4.0.0)",
org.eclipse.xtend.lib;bundle-version="2.8.1",
org.eclipse.papyrus.infra.ui;bundle-version="[2.0.0,3.0.0)",
@@ -29,4 +29,4 @@ Bundle-Name: %Bundle-Name
Bundle-ManifestVersion: 2
Bundle-Activator: org.eclipse.papyrus.uml.diagram.sequence.tests.Activator
Bundle-SymbolicName: org.eclipse.papyrus.uml.diagram.sequence.tests;singleton:=true
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.di b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.di
new file mode 100644
index 00000000000..8c549eecdc6
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<architecture:ArchitectureDescription xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:architecture="http://www.eclipse.org/papyrus/infra/core/architecture" contextId="org.eclipse.papyrus.infra.services.edit.TypeContext"/>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.notation b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.notation
new file mode 100644
index 00000000000..ca0cea5f5c9
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.notation
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/gmfdiag/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_QKU0YEMwEeiEZ5Jtfh6-KA" type="PapyrusUMLSequenceDiagram" name="sequence" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_QKU0YUMwEeiEZ5Jtfh6-KA" type="Interaction_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_QKU0YkMwEeiEZ5Jtfh6-KA" type="Interaction_NameLabel"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_QKU0Y0MwEeiEZ5Jtfh6-KA" type="Interaction_SubfragmentCompartment">
+ <children xmi:type="notation:Shape" xmi:id="_RZ4XwEMwEeiEZ5Jtfh6-KA" type="Lifeline_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_RZ4-0EMwEeiEZ5Jtfh6-KA" type="Lifeline_NameLabel"/>
+ <element xmi:type="uml:Lifeline" href="bug533673.uml#_RZwb8EMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_RZ4XwUMwEeiEZ5Jtfh6-KA" x="58" y="10"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_R0X7YEMwEeiEZ5Jtfh6-KA" type="Lifeline_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_R0X7YkMwEeiEZ5Jtfh6-KA" type="Lifeline_NameLabel"/>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_R0cM0EMwEeiEZ5Jtfh6-KA" type="compartment_shape_display">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_R0cM0UMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_R0cM0kMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_XgABcEMwEeiEZ5Jtfh6-KA" type="BehaviorExecutionSpecification_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_XgABckMwEeiEZ5Jtfh6-KA" type="BehaviorExecutionSpecification_Behavior">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_XgAogEMwEeiEZ5Jtfh6-KA" x="18" y="18"/>
+ </children>
+ <element xmi:type="uml:BehaviorExecutionSpecification" href="bug533673.uml#_Xf7wAEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XgABcUMwEeiEZ5Jtfh6-KA" x="40" y="90" width="20" height="100"/>
+ </children>
+ <element xmi:type="uml:Lifeline" href="bug533673.uml#_R0URAEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_R0X7YUMwEeiEZ5Jtfh6-KA" x="237" y="10"/>
+ </children>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_QKU0ZEMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <element xmi:type="uml:Interaction" href="bug533673.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_QKU0ZUMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_QKU0ZkMwEeiEZ5Jtfh6-KA" name="diagram_compatibility_version" stringValue="1.4.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_QKU0Z0MwEeiEZ5Jtfh6-KA"/>
+ <styles xmi:type="style:PapyrusDiagramStyle" xmi:id="_QKU0aEMwEeiEZ5Jtfh6-KA" diagramKindId="org.eclipse.papyrus.uml.diagram.sequence">
+ <owner xmi:type="uml:Class" href="bug533673.uml#_Jqu6wEMwEeiEZ5Jtfh6-KA"/>
+ </styles>
+ <element xmi:type="uml:Interaction" href="bug533673.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/>
+ <edges xmi:type="notation:Connector" xmi:id="_Xfg5QEMwEeiEZ5Jtfh6-KA" type="Message_SynchEdge" source="_RZ4XwEMwEeiEZ5Jtfh6-KA" target="_R0X7YEMwEeiEZ5Jtfh6-KA">
+ <children xmi:type="notation:DecorationNode" xmi:id="_Xfg5Q0MwEeiEZ5Jtfh6-KA" type="Message_SynchNameLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Xfg5REMwEeiEZ5Jtfh6-KA" x="1" y="-13"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_XfhgUEMwEeiEZ5Jtfh6-KA" type="Message_SynchStereotypeLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_XfhgUUMwEeiEZ5Jtfh6-KA" x="1" y="-33"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_Xfg5QUMwEeiEZ5Jtfh6-KA"/>
+ <styles xmi:type="notation:LineStyle" xmi:id="_XfhgUkMwEeiEZ5Jtfh6-KA"/>
+ <element xmi:type="uml:Message" href="bug533673.uml#_XfUsAEMwEeiEZ5Jtfh6-KA"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Xfg5QkMwEeiEZ5Jtfh6-KA" points="[0, 0, -179, 0]$[179, 0, 0, 0]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XftGgEMwEeiEZ5Jtfh6-KA" id="(0.5,0.12857142857142856)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XfttkEMwEeiEZ5Jtfh6-KA" id="(0.5,0.12857142857142856)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_XgIkUEMwEeiEZ5Jtfh6-KA" type="Message_ReplyEdge" source="_R0X7YEMwEeiEZ5Jtfh6-KA" target="_RZ4XwEMwEeiEZ5Jtfh6-KA">
+ <children xmi:type="notation:DecorationNode" xmi:id="_XgIkU0MwEeiEZ5Jtfh6-KA" type="Message_ReplyNameLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_XgIkVEMwEeiEZ5Jtfh6-KA" x="1" y="-13"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_XgIkVUMwEeiEZ5Jtfh6-KA" type="Message_ReplyStereotypeLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_XgIkVkMwEeiEZ5Jtfh6-KA" x="1" y="-33"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_XgIkUUMwEeiEZ5Jtfh6-KA"/>
+ <styles xmi:type="notation:LineStyle" xmi:id="_XgIkV0MwEeiEZ5Jtfh6-KA"/>
+ <element xmi:type="uml:Message" href="bug533673.uml#_XgGvIEMwEeiEZ5Jtfh6-KA"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_XgIkUkMwEeiEZ5Jtfh6-KA" points="[0, 0, 179, 0]$[-179, 0, 0, 0]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XgJycEMwEeiEZ5Jtfh6-KA" id="(0.5,0.2714285714285714)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XgJycUMwEeiEZ5Jtfh6-KA" id="(0.5,0.2714285714285714)"/>
+ </edges>
+</notation:Diagram>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.uml b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.uml
new file mode 100644
index 00000000000..7b4c16b1d2e
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533673.uml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_HWN6cEMwEeiEZ5Jtfh6-KA" name="bug533673">
+ <packageImport xmi:id="_HeHSMEMwEeiEZ5Jtfh6-KA">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Class" xmi:id="_Jqu6wEMwEeiEZ5Jtfh6-KA" name="Foo" classifierBehavior="_POkWwEMwEeiEZ5Jtfh6-KA">
+ <ownedAttribute xmi:id="_LwEPkEMwEeiEZ5Jtfh6-KA" name="a"/>
+ <ownedAttribute xmi:id="_M6OVkEMwEeiEZ5Jtfh6-KA" name="b"/>
+ <ownedBehavior xmi:type="uml:Interaction" xmi:id="_POkWwEMwEeiEZ5Jtfh6-KA" name="DoIt">
+ <lifeline xmi:id="_RZwb8EMwEeiEZ5Jtfh6-KA" name="a" represents="_LwEPkEMwEeiEZ5Jtfh6-KA" coveredBy="_XfZkgEMwEeiEZ5Jtfh6-KA _XgH9QEMwEeiEZ5Jtfh6-KA"/>
+ <lifeline xmi:id="_R0URAEMwEeiEZ5Jtfh6-KA" name="b" represents="_M6OVkEMwEeiEZ5Jtfh6-KA" coveredBy="_XfaLkEMwEeiEZ5Jtfh6-KA _XgHWMEMwEeiEZ5Jtfh6-KA _Xf7wAEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XfZkgEMwEeiEZ5Jtfh6-KA" name="request-send" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_XfUsAEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XfaLkEMwEeiEZ5Jtfh6-KA" name="request-recv" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_XfUsAEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:BehaviorExecutionSpecification" xmi:id="_Xf7wAEMwEeiEZ5Jtfh6-KA" name="exec" covered="_R0URAEMwEeiEZ5Jtfh6-KA" finish="_XgHWMEMwEeiEZ5Jtfh6-KA" start="_XfaLkEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XgHWMEMwEeiEZ5Jtfh6-KA" name="reply-send" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_XgGvIEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XgH9QEMwEeiEZ5Jtfh6-KA" name="reply-recv" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_XgGvIEMwEeiEZ5Jtfh6-KA"/>
+ <message xmi:id="_XfUsAEMwEeiEZ5Jtfh6-KA" name="request" receiveEvent="_XfaLkEMwEeiEZ5Jtfh6-KA" sendEvent="_XfZkgEMwEeiEZ5Jtfh6-KA"/>
+ <message xmi:id="_XgGvIEMwEeiEZ5Jtfh6-KA" messageSort="reply" receiveEvent="_XgH9QEMwEeiEZ5Jtfh6-KA" sendEvent="_XgHWMEMwEeiEZ5Jtfh6-KA"/>
+ </ownedBehavior>
+ </packagedElement>
+</uml:Model>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java
index 8b1200fdc6d..dd5c472bd39 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/BugTests.java
@@ -1,6 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2012 CEA LIST.
- *
+ * Copyright (c) 2012, 2018 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,29 +8,32 @@
*
* Contributors:
* CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 533673
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.sequence.tests.bug;
-import org.junit.runner.RunWith;
import org.eclipse.papyrus.junit.framework.classification.ClassificationSuite;
+import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;
/**
* All tests for bug.
*/
@RunWith(ClassificationSuite.class)
-@SuiteClasses({
- TestCombinedFragmentKind_364710.class,
- TestCombinedFragmentOperand_364701.class,
- TestMessagesDeletion_364828.class,
- TestNestedCombinedFragment_364795.class,
- TestSynchronousMessageCreation_364827.class,
- /** TestCombinedFragmentGates_364816.class,
- * TestCombinedFragmentDeletion_364804.class,
- */
- TestAdvancedDragDrop_364696.class,
- TestGuardEdition_364808.class
+@SuiteClasses({
+ TestCombinedFragmentKind_364710.class,
+ TestCombinedFragmentOperand_364701.class,
+ TestMessagesDeletion_364828.class,
+ TestNestedCombinedFragment_364795.class,
+ TestSynchronousMessageCreation_364827.class,
+ /**
+ * TestCombinedFragmentGates_364816.class,
+ * TestCombinedFragmentDeletion_364804.class,
+ */
+ TestAdvancedDragDrop_364696.class,
+ TestGuardEdition_364808.class,
+ CombinedFragmentRegressionTest.class,
})
public class BugTests {
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java
new file mode 100644
index 00000000000..c5febc7935d
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java
@@ -0,0 +1,111 @@
+/*****************************************************************************
+ * Copyright (c) 2018 Christian W. Damus and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.diagram.sequence.tests.bug;
+
+import static org.eclipse.papyrus.junit.matchers.MoreMatchers.greaterThan;
+import static org.eclipse.papyrus.junit.matchers.MoreMatchers.isEmpty;
+import static org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture.at;
+import static org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture.sized;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.function.Consumer;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.papyrus.junit.framework.classification.tests.AbstractPapyrusTest;
+import org.eclipse.papyrus.junit.matchers.DiagramMatchers;
+import org.eclipse.papyrus.junit.utils.rules.ActiveDiagram;
+import org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture;
+import org.eclipse.papyrus.junit.utils.rules.PluginResource;
+import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes;
+import org.eclipse.uml2.uml.CombinedFragment;
+import org.eclipse.uml2.uml.Interaction;
+import org.eclipse.uml2.uml.InteractionOperand;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Regression tests specifically for {@link CombinedFragment}s in the sequence diagram
+ * editor, especially those tracked under the umbrella of <a href="http://eclip.se/533670">bug 533670</a>.
+ *
+ * @author Christian W. Damus
+ * @see <a href="http://eclip.se/533670">bug 533670</a>
+ */
+public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
+
+ @Rule
+ public final PapyrusEditorFixture editor = new PapyrusEditorFixture();
+
+ /**
+ * Initializes me.
+ */
+ public CombinedFragmentRegressionTest() {
+ super();
+ }
+
+ /**
+ * Verify the creation and extent of a default interaction operand in a newly
+ * created combined fragment.
+ */
+ @Test
+ @PluginResource("resource/bugs/bug533673.di")
+ @ActiveDiagram("sequence")
+ public void defaultInteractionOperand_533673() {
+ EditPart interactionEP = editor.findEditPart("DoIt", Interaction.class);
+ EditPart interactionCompartment = editor.getShapeCompartment(interactionEP);
+
+ EditPart combinedFragment = editor.createShape(interactionCompartment, UMLElementTypes.CombinedFragment_Shape, at(15, 60), sized(360, 200));
+
+ assertThat(combinedFragment, DiagramMatchers.semanticThat(instanceOf(CombinedFragment.class)));
+ CombinedFragment cf = (CombinedFragment) combinedFragment.getAdapter(EObject.class);
+
+ assertThat("No interaction operand", cf.getOperands(), not(isEmpty()));
+
+ InteractionOperand operand = cf.getOperands().get(0);
+ EditPart operandEP = editor.requireEditPart(combinedFragment, operand);
+
+ assertThat(operandEP, instanceOf(GraphicalEditPart.class));
+ IFigure figure = ((GraphicalEditPart) operandEP).getFigure();
+
+ Consumer<Rectangle> verifyBounds = bounds -> {
+ // Account for margins
+ assertThat("Width too small", bounds.width, greaterThan(350));
+ // Account for some space for the combined fragment operator label
+ // and some extra for font size variance across platforms (esp.
+ // Linux and Windows, which seem to be bigger than MacOS)
+ assertThat("Height too small", bounds.height, greaterThan(160));
+ };
+
+ verifyBounds.accept(figure.getBounds());
+
+ editor.undo();
+
+ operandEP = editor.findEditPart(operand);
+ assertThat("Operand still present in the diagram", operandEP, nullValue());
+
+ editor.redo();
+
+ operandEP = editor.findEditPart(operand);
+ assertThat(operandEP, instanceOf(GraphicalEditPart.class));
+ figure = ((GraphicalEditPart) operandEP).getFigure();
+ verifyBounds.accept(figure.getBounds());
+ }
+
+}

Back to the top