Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2016-05-03 21:19:36 +0000
committerGerrit Code Review @ Eclipse.org2016-05-04 18:07:41 +0000
commitc08a1afb207370fb97552e9968e2a04483be43ea (patch)
tree4ccc2d1f14791359236ca84d76598e33ad46d6fb
parent13c27182baefb297a82695c97d93a1aac1ccb986 (diff)
downloadorg.eclipse.papyrus-rt-c08a1afb207370fb97552e9968e2a04483be43ea.tar.gz
org.eclipse.papyrus-rt-c08a1afb207370fb97552e9968e2a04483be43ea.tar.xz
org.eclipse.papyrus-rt-c08a1afb207370fb97552e9968e2a04483be43ea.zip
Bug 474481: [Core] Default naming for CapsuleParts and Ports should be enhanced
https://bugs.eclipse.org/bugs/show_bug.cgi?id=474481 Ensure correct UMLRTish default names for new ports and parts according to their types by: * factoring the set-type advice out of the base edit-helper so that it can be inherited by all derived types (the specific port types didn't inherit it because they have their own edit-helpers) * adding a facility by which the naming advice can determine that an object is newly created and so override the name already set by another particle of advice (problem with external port naming) * adding a UML-RT-specific naming utility, because the Papyrus default implementation does not conform to UML-RT requirements and cannot be tweaked by clients that wish to reuse it * removing setting of name from the CreateCapsulePartAndDisplayCommand because setting the default name is the exclusive responsibility of edit-helper advice This includes a post-transaction executor facility that can be useful in a variety of situations. Change-Id: Ieac9d4ff139f5ba493cb270a4490a7138bfc2f86
-rw-r--r--plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/elementtypes/uml-rt.elementtypesconfigurations4
-rw-r--r--plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartEditHelperAdvice.java77
-rw-r--r--plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartSetTypeAdvice.java98
-rw-r--r--plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortEditHelperAdvice.java49
-rw-r--r--plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortSetTypeAdvice.java99
-rw-r--r--plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/utils/NewElementUtil.java139
-rw-r--r--plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/utils/PostTransactionExecutor.java130
-rw-r--r--plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CapsuleToCapsulePartDropStrategy.java19
-rw-r--r--plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CreateCapsulePartAndDisplayCommand.java25
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.classpath2
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.settings/org.eclipse.jdt.core.prefs6
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/META-INF/MANIFEST.MF3
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.di2
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.notation66
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.uml34
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/types/advice/CapsulePartDefaultNameTest.java136
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/types/advice/PortDefaultNameTest.java158
-rw-r--r--tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/utils/PostTransactionExecutorTest.java353
18 files changed, 1248 insertions, 152 deletions
diff --git a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/elementtypes/uml-rt.elementtypesconfigurations b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/elementtypes/uml-rt.elementtypesconfigurations
index 675f06fe1..f381f9730 100644
--- a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/elementtypes/uml-rt.elementtypesconfigurations
+++ b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/elementtypes/uml-rt.elementtypesconfigurations
@@ -266,7 +266,9 @@
<adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_B4-ngFYiEeW5U97f0qNNMQ" identifier="org.eclipse.papyrusrt.umlrt.core.types.advice.EnumerationEditHelperAdvice" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrusrt.umlrt.core.types.advice.EnumerationEditHelperAdvice">
<target xsi:type="elementtypesconfigurations:MetamodelTypeConfiguration" href="../../../plugin/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations#_ScgUVlYCEeS0WsAAtVmToA"/>
</adviceBindingsConfigurations>
- <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_jAsoYF1LEeWhkeBZ-5J_3Q" description="Advice for Call Event in Papyrus RT" identifier="org.eclipse.papyrusrt.umlrt.core.types.advice.CallEventEditHelperAdvice" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrusrt.umlrt.core.types.advice.CallEventEditHelperAdvice">
+ <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_jAsoYF1LEeWhkeBZ-5J_3Q" identifier="org.eclipse.papyrusrt.umlrt.core.types.advice.CallEventEditHelperAdvice" description="Advice for Call Event in Papyrus RT" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrusrt.umlrt.core.types.advice.CallEventEditHelperAdvice">
<target xsi:type="elementtypesconfigurations:MetamodelTypeConfiguration" href="../../../plugin/org.eclipse.papyrus.uml.service.types/model/uml.elementtypesconfigurations#_ScaNylYCEeS0WsAAtVmToA"/>
</adviceBindingsConfigurations>
+ <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_lY6U0BFkEeaM3pwxY5WOXQ" identifier="org.eclipse.papyrusrt.umlrt.core.types.RTPort.setTypeAdvice" description="Advice on the setting of the type of an RTPort." target="_ubJcuqeUEeSUR5jX0TaAcA" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrusrt.umlrt.core.types.advice.RTPortSetTypeAdvice"/>
+ <adviceBindingsConfigurations xsi:type="elementtypesconfigurations:AdviceBindingConfiguration" xmi:id="_uepxUBFkEeaM3pwxY5WOXQ" identifier="org.eclipse.papyrusrt.umlrt.core.types.CapsulePart.setTypeAdvice" description="Advice on the setting of the type of a CapsulePart." target="_ubJctKeUEeSUR5jX0TaAcA" inheritance="all" editHelperAdviceClassName="org.eclipse.papyrusrt.umlrt.core.types.advice.CapsulePartSetTypeAdvice"/>
</elementtypesconfigurations:ElementTypeSetConfiguration>
diff --git a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartEditHelperAdvice.java b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartEditHelperAdvice.java
index ca7563b75..6ea16028a 100644
--- a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartEditHelperAdvice.java
+++ b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartEditHelperAdvice.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014 CEA LIST.
+ * 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
@@ -8,35 +8,30 @@
*
* Contributors:
* CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 474481
*****************************************************************************/
package org.eclipse.papyrusrt.umlrt.core.types.advice;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.type.core.commands.ConfigureElementCommand;
-import org.eclipse.gmf.runtime.emf.type.core.commands.SetValueCommand;
import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest;
-import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.infra.services.edit.utils.RequestParameterConstants;
-import org.eclipse.papyrusrt.umlrt.core.utils.CapsuleUtils;
+import org.eclipse.papyrusrt.umlrt.core.utils.NewElementUtil;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart;
import org.eclipse.uml2.uml.AggregationKind;
-import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.LiteralInteger;
import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
import org.eclipse.uml2.uml.Property;
-import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.VisibilityKind;
@@ -63,37 +58,6 @@ public class CapsulePartEditHelperAdvice extends AbstractEditHelperAdvice {
/**
* {@inheritDoc}
*
- * @see org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice#approveRequest(org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest)
- *
- */
- @Override
- public boolean approveRequest(IEditCommandRequest request) {
- // check that the type of the RTPort is a protocol, and nothing else
- if (request instanceof SetRequest) {
- SetRequest setRequest = (SetRequest) request;
- EStructuralFeature feature = setRequest.getFeature();
- if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(feature)) {
- // new value should be a protocol or null
- Object newValue = ((SetRequest) request).getValue();
- if (newValue instanceof Classifier) {
- if (CapsuleUtils.isCapsule((Classifier) newValue)) {
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
- return super.approveRequest(setRequest);
-
- }
- return super.approveRequest(request);
- }
-
- /**
- * {@inheritDoc}
- *
* @see org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice#getAfterConfigureCommand(org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest)
*
*/
@@ -122,35 +86,6 @@ public class CapsulePartEditHelperAdvice extends AbstractEditHelperAdvice {
};
}
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice#getAfterSetCommand(org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest)
- */
- @Override
- protected ICommand getAfterSetCommand(SetRequest request) {
- ICommand command = null;
- EStructuralFeature feature = request.getFeature();
- if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(feature)) {
- // if element is unnamed, set a name according to the new Type name
- Object newValue = request.getValue();
- EObject elementToEdit = request.getElementToEdit();
- if (newValue instanceof Type && elementToEdit instanceof Property && ((Property) elementToEdit).getName() == null) {
- String name = ((Type) newValue).getName();
- if (name != null && !name.isEmpty()) {
- String newName = Character.toLowerCase(name.charAt(0)) + name.substring(1);
- command = new SetValueCommand(new SetRequest(request.getElementToEdit(), UMLPackage.eINSTANCE.getNamedElement_Name(), newName));
- }
- }
- } else {
- command = super.getAfterSetCommand(request);
- }
-
- return command;
- }
-
-
/**
* {@inheritDoc}
*
@@ -159,7 +94,11 @@ public class CapsulePartEditHelperAdvice extends AbstractEditHelperAdvice {
@Override
protected ICommand getBeforeConfigureCommand(ConfigureRequest request) {
final Property property = (Property) request.getElementToConfigure();
- CompositeCommand compositeCommand = new CompositeCommand("Before Configure RTPort");
+
+ // This capsule-part is new if it is being configured
+ NewElementUtil.elementCreated(property);
+
+ CompositeCommand compositeCommand = new CompositeCommand("Before Configure CapsulePart");
// If the newly create Port has no multiplicity set it to the default Value
if (null == property.getLowerValue()) {
diff --git a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartSetTypeAdvice.java b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartSetTypeAdvice.java
new file mode 100644
index 000000000..b83d82dd7
--- /dev/null
+++ b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/CapsulePartSetTypeAdvice.java
@@ -0,0 +1,98 @@
+/*****************************************************************************
+ * 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 474481
+ *****************************************************************************/
+package org.eclipse.papyrusrt.umlrt.core.types.advice;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.type.core.commands.SetValueCommand;
+import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
+import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrusrt.umlrt.core.utils.CapsuleUtils;
+import org.eclipse.papyrusrt.umlrt.core.utils.NewElementUtil;
+import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLPackage;
+
+import com.google.common.base.Strings;
+
+/**
+ * Advice for {@link CapsulePart} on the setting of its
+ * {@link UMLPackage.Literals#TYPED_ELEMENT__TYPE type}.
+ */
+public class CapsulePartSetTypeAdvice extends AbstractEditHelperAdvice {
+
+ public CapsulePartSetTypeAdvice() {
+ super();
+ }
+
+ @Override
+ public boolean approveRequest(IEditCommandRequest request) {
+ // check that the type of the CapsulePart is a capsule, and nothing else
+ if (request instanceof SetRequest) {
+ SetRequest setRequest = (SetRequest) request;
+ EStructuralFeature feature = setRequest.getFeature();
+ if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(feature)) {
+ // new value should be a protocol or null
+ Object newValue = ((SetRequest) request).getValue();
+ if (newValue instanceof Classifier) {
+ if (CapsuleUtils.isCapsule((Classifier) newValue)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ return super.approveRequest(setRequest);
+
+ }
+ return super.approveRequest(request);
+ }
+
+ /**
+ * React to the setting of the initial type of an unnamed capsule-part by
+ * initializing its name.
+ */
+ @Override
+ protected ICommand getAfterSetCommand(SetRequest request) {
+ ICommand result = null;
+ EStructuralFeature feature = request.getFeature();
+
+ if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(feature)) {
+ // if element is unnamed or is itself a new element, set a name
+ // åaccording to the new Type name
+ Object newValue = request.getValue();
+ EObject elementToEdit = request.getElementToEdit();
+ if ((newValue instanceof Type)
+ && (elementToEdit instanceof Property)
+ && (Strings.isNullOrEmpty(((Property) elementToEdit).getName())
+ || NewElementUtil.isCreatedElement(elementToEdit))) {
+
+ Property property = (Property) elementToEdit;
+ String name = ((Type) newValue).getName();
+ if (!Strings.isNullOrEmpty(name)) {
+ String newName = NewElementUtil.getUniqueName(property, (Type) newValue);
+ result = new SetValueCommand(new SetRequest(request.getElementToEdit(), UMLPackage.eINSTANCE.getNamedElement_Name(), newName));
+ }
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortEditHelperAdvice.java b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortEditHelperAdvice.java
index d27b45d2b..ea2ec66c5 100644
--- a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortEditHelperAdvice.java
+++ b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortEditHelperAdvice.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014 CEA LIST.
+ * 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
@@ -8,6 +8,7 @@
*
* Contributors:
* CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 474481
*****************************************************************************/
package org.eclipse.papyrusrt.umlrt.core.types.advice;
@@ -25,19 +26,18 @@ import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.commands.ConfigureElementCommand;
-import org.eclipse.gmf.runtime.emf.type.core.commands.SetValueCommand;
import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
-import org.eclipse.papyrus.commands.wrappers.EMFtoGMFCommandWrapper;
+import org.eclipse.papyrus.infra.emf.gmf.command.EMFtoGMFCommandWrapper;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrusrt.umlrt.core.types.ElementTypeUtils;
import org.eclipse.papyrusrt.umlrt.core.types.IUMLRTElementTypes;
-import org.eclipse.papyrusrt.umlrt.core.utils.ProtocolUtils;
+import org.eclipse.papyrusrt.umlrt.core.utils.NewElementUtil;
import org.eclipse.papyrusrt.umlrt.core.utils.RTPortKindEnum;
import org.eclipse.papyrusrt.umlrt.core.utils.RTPortUtils;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort;
@@ -45,7 +45,6 @@ import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage;
import org.eclipse.uml2.uml.LiteralInteger;
import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
import org.eclipse.uml2.uml.Port;
-import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.VisibilityKind;
@@ -59,26 +58,8 @@ public class RTPortEditHelperAdvice extends AbstractEditHelperAdvice {
@Override
public boolean approveRequest(IEditCommandRequest request) {
boolean result = false;
- // check that the type of the RTPort is a protocol, and nothing else
- if (request instanceof SetRequest) {
- SetRequest setRequest = (SetRequest) request;
- EStructuralFeature feature = setRequest.getFeature();
- if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(feature)) {
- // new value should be a protocol or null
- Object newValue = ((SetRequest) request).getValue();
- if (newValue instanceof EObject) {
- if (ProtocolUtils.isProtocol((EObject) newValue)) {
- result = true;
- } else {
- result = false;
- }
- } else {
- result = false;
- }
- } else {
- result = super.approveRequest(setRequest);
- }
- } else if (request instanceof CreateRelationshipRequest) {
+
+ if (request instanceof CreateRelationshipRequest) {
IElementType type = ((CreateRelationshipRequest) request).getElementType();
if (type != null && ElementTypeUtils.isTypeCompatible(type, ElementTypeRegistry.getInstance().getType(IUMLRTElementTypes.RT_CONNECTOR_ID))) {
result = checkSourceAndTarget(((CreateRelationshipRequest) request));
@@ -131,6 +112,10 @@ public class RTPortEditHelperAdvice extends AbstractEditHelperAdvice {
@Override
protected ICommand getBeforeConfigureCommand(ConfigureRequest request) {
final Port port = (Port) request.getElementToConfigure();
+
+ // This port is new if it is being configured
+ NewElementUtil.elementCreated(port);
+
CompositeCommand compositeCommand = new CompositeCommand("Before Configure RTPort");
// If the newly create Port has no multiplicity set it to the default Value
@@ -234,19 +219,7 @@ public class RTPortEditHelperAdvice extends AbstractEditHelperAdvice {
Port portToEdit = (Port) request.getElementToEdit();
RTPort rtPortToEdit = UMLUtil.getStereotypeApplication(portToEdit, RTPort.class);
- if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(feature)) {
- // if element is unnamed, set a name according to the new Type name
- Object newValue = request.getValue();
- EObject elementToEdit = request.getElementToEdit();
- if (newValue instanceof Type && elementToEdit instanceof Port && ((Port) elementToEdit).getName() == null) {
- String name = ((Type) newValue).getName();
- if (name != null && !name.isEmpty()) {
- String newName = Character.toLowerCase(name.charAt(0)) + name.substring(1);
- compositeCommand.add(new SetValueCommand(new SetRequest(request.getElementToEdit(), UMLPackage.eINSTANCE.getNamedElement_Name(), newName)));
- }
- }
- } else if (UMLPackage.eINSTANCE.getPort_IsService().equals(feature)) {
-
+ if (UMLPackage.eINSTANCE.getPort_IsService().equals(feature)) {
ICommand visibilityCommand = getVisibilityCommand(request, portToEdit);
if (null != visibilityCommand && visibilityCommand.canExecute()) {
diff --git a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortSetTypeAdvice.java b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortSetTypeAdvice.java
new file mode 100644
index 000000000..118910e88
--- /dev/null
+++ b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/types/advice/RTPortSetTypeAdvice.java
@@ -0,0 +1,99 @@
+/*****************************************************************************
+ * 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 474481
+ *****************************************************************************/
+package org.eclipse.papyrusrt.umlrt.core.types.advice;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.type.core.commands.SetValueCommand;
+import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
+import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrusrt.umlrt.core.utils.NewElementUtil;
+import org.eclipse.papyrusrt.umlrt.core.utils.ProtocolUtils;
+import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort;
+import org.eclipse.uml2.uml.Port;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLPackage;
+
+import com.google.common.base.Strings;
+
+/**
+ * Advice for {@link RTPort} on the setting of its
+ * {@link UMLPackage.Literals#TYPED_ELEMENT__TYPE type}.
+ */
+public class RTPortSetTypeAdvice extends AbstractEditHelperAdvice {
+
+ @Override
+ public boolean approveRequest(IEditCommandRequest request) {
+ boolean result = false;
+ // check that the type of the RTPort is a protocol, and nothing else
+ if (request instanceof SetRequest) {
+ SetRequest setRequest = (SetRequest) request;
+ EStructuralFeature feature = setRequest.getFeature();
+ if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(feature)) {
+ // new value should be a protocol or null
+ Object newValue = ((SetRequest) request).getValue();
+ if (newValue instanceof EObject) {
+ if (ProtocolUtils.isProtocol((EObject) newValue)) {
+ result = true;
+ } else {
+ result = false;
+ }
+ } else {
+ result = false;
+ }
+ } else {
+ result = super.approveRequest(setRequest);
+ }
+ } else {
+ result = super.approveRequest(request);
+ }
+
+ return result;
+ }
+
+ /**
+ * React to the setting of the initial type of an unnamed port by initializing
+ * its name.
+ */
+ @Override
+ protected ICommand getAfterSetCommand(SetRequest request) {
+ ICommand result = null;
+
+ EStructuralFeature feature = request.getFeature();
+
+ if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(feature)) {
+ // if element is unnamed or is itself a new element, set a name
+ // according to the new Type name
+ Object newValue = request.getValue();
+ EObject elementToEdit = request.getElementToEdit();
+ if ((newValue instanceof Type)
+ && (elementToEdit instanceof Port)
+ && (Strings.isNullOrEmpty(((Port) elementToEdit).getName())
+ || NewElementUtil.isCreatedElement(elementToEdit))) {
+
+ Port port = (Port) elementToEdit;
+ String name = ((Type) newValue).getName();
+ if (!Strings.isNullOrEmpty(name)) {
+ String newName = NewElementUtil.getUniqueName(port, (Type) newValue);
+
+ result = new SetValueCommand(new SetRequest(request.getElementToEdit(), UMLPackage.eINSTANCE.getNamedElement_Name(), newName));
+ }
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/utils/NewElementUtil.java b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/utils/NewElementUtil.java
new file mode 100644
index 000000000..4476820b7
--- /dev/null
+++ b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/utils/NewElementUtil.java
@@ -0,0 +1,139 @@
+/*****************************************************************************
+ * 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.papyrusrt.umlrt.core.utils;
+
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Type;
+
+import com.google.common.base.Strings;
+
+/**
+ * Static utilities for working with newly created elements.
+ */
+public class NewElementUtil {
+
+ /**
+ * Marks the given {@code object} as having been created during the process
+ * of the current transaction.
+ *
+ * @param object
+ * a newly created element
+ *
+ * @see #isCreatedElement(EObject)
+ */
+ public static void elementCreated(EObject object) {
+ // Don't repeat
+ if (!isCreatedElement(object)) {
+ object.eAdapters().add(new NewElementAdapter());
+ }
+ }
+
+ /**
+ * Queries whether the specified {@code object} was created during the current
+ * transaction.
+ *
+ * @param object
+ * an object
+ *
+ * @return whether it was recorded earlier in the current transaction as having
+ * been created
+ *
+ * @see #elementCreated(EObject)
+ */
+ public static boolean isCreatedElement(EObject object) {
+ return EcoreUtil.getExistingAdapter(object, NewElementAdapter.class) != null;
+ }
+
+ /**
+ * Obtains an unique name for a new {@code property} of a given {@code type} that
+ * is the initial-lower-case name of the {@code type} suffixed as necessary to
+ * distinguish it from other properties of the same context class.
+ *
+ * @param property
+ * a new property in some class
+ * @param type
+ * the type of the new property
+ *
+ * @return a default unique name for the property, with a numeric distinguishing
+ * suffix if necessary, or {@code null} if the {@code type} has no name
+ */
+ public static String getUniqueName(Property property, Type type) {
+ String result = null;
+
+ String typeName = type.getName();
+ if (!Strings.isNullOrEmpty(typeName)) {
+ result = Character.toLowerCase(typeName.charAt(0)) + typeName.substring(1);
+
+ if (property.getClass_() != null) {
+ // Ensure uniqueness
+ String nameBase = result;
+ boolean done = false;
+ for (int suffix = 2; !done; suffix++) {
+ done = true; // Be optimistic
+ for (Property next : property.getClass_().getAttributes()) {
+ if (next != property) {
+ if (result.equals(next.getName())) {
+ result = nameBase + suffix;
+ done = false; // Repeat
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ //
+ // Nested types
+ //
+
+ private static final class NewElementAdapter extends AdapterImpl {
+
+ /**
+ * Initializes me.
+ */
+ NewElementAdapter() {
+ super();
+ }
+
+ /**
+ * @see org.eclipse.emf.common.notify.impl.AdapterImpl#setTarget(org.eclipse.emf.common.notify.Notifier)
+ *
+ * @param newTarget
+ */
+ @Override
+ public void setTarget(Notifier newTarget) {
+ super.setTarget(newTarget);
+
+ if (newTarget instanceof EObject) {
+ // Schedule clean-up at the end of the transaction
+ EObject element = (EObject) newTarget;
+ PostTransactionExecutor.getInstance(element).execute(
+ () -> element.eAdapters().remove(this));
+ }
+ }
+
+ @Override
+ public boolean isAdapterForType(Object type) {
+ return type == NewElementAdapter.class;
+ }
+ }
+}
diff --git a/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/utils/PostTransactionExecutor.java b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/utils/PostTransactionExecutor.java
new file mode 100644
index 000000000..90df6670a
--- /dev/null
+++ b/plugins/umlrt/core/org.eclipse.papyrusrt.umlrt.core/src/org/eclipse/papyrusrt/umlrt/core/utils/PostTransactionExecutor.java
@@ -0,0 +1,130 @@
+/*****************************************************************************
+ * 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.papyrusrt.umlrt.core.utils;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.Transaction;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.TransactionalEditingDomainEvent;
+import org.eclipse.emf.transaction.TransactionalEditingDomainListenerImpl;
+import org.eclipse.emf.transaction.impl.InternalTransaction;
+import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.papyrus.infra.core.utils.TransactionHelper;
+import org.eclipse.papyrus.infra.tools.util.CoreExecutors;
+import org.eclipse.papyrusrt.umlrt.core.Activator;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+/**
+ * Executor utility that runs tasks after the completion or failure of the current
+ * top-level transaction, regardless. This is different from executors obtained
+ * via the {@link TransactionHelper#createTransactionExecutor(TransactionalEditingDomain, Executor)}
+ * and related APIs, which execute before commit or not at all if the transaction rolls
+ * back.
+ */
+public class PostTransactionExecutor implements Executor {
+ private static final LoadingCache<TransactionalEditingDomain, Executor> executors = CacheBuilder
+ .newBuilder().weakKeys().weakValues().build(CacheLoader.from(
+ domain -> new PostTransactionExecutor(domain, CoreExecutors.getUIExecutorService())));
+
+ private final ConcurrentLinkedQueue<Runnable> pendingTasks = new ConcurrentLinkedQueue<>();
+ private final Executor fallback;
+ private final AtomicReference<Transaction> activeTransaction;
+
+ private PostTransactionExecutor(TransactionalEditingDomain domain, Executor fallback) {
+ super();
+
+ this.fallback = fallback;
+
+ InternalTransaction active = ((InternalTransactionalEditingDomain) domain).getActiveTransaction();
+ this.activeTransaction = new AtomicReference<>((active == null) ? null : active.getRoot());
+
+ TransactionalEditingDomain.Lifecycle lifecycle = TransactionUtil.getAdapter(domain, TransactionalEditingDomain.Lifecycle.class);
+ lifecycle.addTransactionalEditingDomainListener(new TransactionalEditingDomainListenerImpl() {
+
+ @Override
+ public void transactionStarted(TransactionalEditingDomainEvent event) {
+ activeTransaction.compareAndSet(null, event.getTransaction());
+ }
+
+ @Override
+ public void transactionClosed(TransactionalEditingDomainEvent event) {
+ if (activeTransaction.compareAndSet(event.getTransaction(), null)) {
+ executePending();
+ }
+ }
+
+ @Override
+ public void editingDomainDisposing(TransactionalEditingDomainEvent event) {
+ lifecycle.removeTransactionalEditingDomainListener(this);
+
+ // In case there were any
+ executePending();
+ }
+ });
+ }
+
+ /**
+ * Obtains the post-transaction executor for the given {@code domain}.
+ *
+ * @param domain
+ * an editing domain
+ * @return its post-transaction executor
+ */
+ public static Executor getInstance(TransactionalEditingDomain domain) {
+ // Initialization of an executor cannot fail under this configuration
+ return executors.getUnchecked(domain);
+ }
+
+ /**
+ * Obtains the best available post-transaction executor for the given {@code object}.
+ *
+ * @param object
+ * an object
+ * @return its domain's executor if the {@code object} is in an editing domain,
+ * otherwise a UI-thread asynchronous executor as a fallback
+ */
+ public static Executor getInstance(EObject object) {
+ TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(object);
+ return (domain == null) ? CoreExecutors.getUIExecutorService() : getInstance(domain);
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ Transaction active = activeTransaction.get();
+ if (active == null) {
+ // There will be no completion of the transaction, so "fall back"
+ fallback.execute(command);
+ } else {
+ pendingTasks.add(command);
+ }
+ }
+
+ private void executePending() {
+ for (Runnable task = pendingTasks.poll(); task != null; task = pendingTasks.poll()) {
+ try {
+ task.run();
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in post-commit runnable", e); //$NON-NLS-1$
+ }
+ }
+ }
+}
diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CapsuleToCapsulePartDropStrategy.java b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CapsuleToCapsulePartDropStrategy.java
index 13bc254ab..34993f13b 100644
--- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CapsuleToCapsulePartDropStrategy.java
+++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CapsuleToCapsulePartDropStrategy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014 CEA LIST.
+ * 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
@@ -8,6 +8,7 @@
*
* Contributors:
* CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 474481
*****************************************************************************/
package org.eclipse.papyrusrt.umlrt.tooling.diagram.common.drop;
@@ -28,7 +29,6 @@ import org.eclipse.papyrusrt.umlrt.core.utils.CapsuleUtils;
import org.eclipse.papyrusrt.umlrt.tooling.diagram.common.Activator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.uml2.uml.Classifier;
-import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.UMLPackage;
/**
@@ -109,25 +109,12 @@ public class CapsuleToCapsulePartDropStrategy extends TransactionalDropStrategy
// 3. add it to the targetClassifier as a Property
// 4. create the view
CreateCapsulePartAndDisplayCommand command = new CreateCapsulePartAndDisplayCommand(targetClassifier, IUMLRTElementTypes.CAPSULE_PART_ID, UMLPackage.eINSTANCE.getNamespace_OwnedMember(), droppedObject, location, targetEditPart);
- command.setCapsulePartName(getName(droppedObject));
return new ICommandProxy(command);
}
-
- protected String getName(EObject droppedObject) {
- if (droppedObject instanceof NamedElement) {
- String name = ((NamedElement) droppedObject).getName();
- if (name.length() > 0) {
- return Character.toLowerCase(name.charAt(0)) + name.substring(1);
- }
- }
- return "";
-
- }
-
protected List<Classifier> getDroppedCapsules(Request req) {
List<EObject> droppedObjects = getSourceEObjects(req);
- List<Classifier> result = new ArrayList<Classifier>();
+ List<Classifier> result = new ArrayList<>();
if (droppedObjects != null) {
for (EObject droppedObject : droppedObjects) {
if (droppedObject instanceof Classifier) {
diff --git a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CreateCapsulePartAndDisplayCommand.java b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CreateCapsulePartAndDisplayCommand.java
index 9be409c79..f2c6c0015 100644
--- a/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CreateCapsulePartAndDisplayCommand.java
+++ b/plugins/umlrt/tooling/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/src/org/eclipse/papyrusrt/umlrt/tooling/diagram/common/drop/CreateCapsulePartAndDisplayCommand.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014 CEA LIST.
+ * 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
@@ -8,6 +8,7 @@
*
* Contributors:
* CEA LIST - Initial API and implementation
+ * Christian W. Damus - bug 474481
*****************************************************************************/
package org.eclipse.papyrusrt.umlrt.tooling.diagram.common.drop;
@@ -53,7 +54,6 @@ public class CreateCapsulePartAndDisplayCommand extends AbstractCommand {
protected EObject droppedObject;
protected Point location;
protected EditPart targetEditPart;
- private String name;
public CreateCapsulePartAndDisplayCommand(Classifier targetClassifier, String capsulePartId, EReference classifier_Feature, EObject droppedObject, Point location, EditPart targetEditPart) {
super("");
@@ -84,27 +84,10 @@ public class CreateCapsulePartAndDisplayCommand extends AbstractCommand {
}
Property capsulePart = createCapsulePart(editingDomain);
setCapsuleAsType(editingDomain, capsulePart, droppedObject);
- setCapsulePartName(editingDomain, capsulePart, name);
dropCapsulePart(capsulePart);
return CommandResult.newOKCommandResult(capsulePart);
}
- protected void setCapsulePartName(TransactionalEditingDomain editingDomain, Property capsulePart, String name2) {
- SetRequest setRequest = new SetRequest(editingDomain, capsulePart, UMLPackage.eINSTANCE.getNamedElement_Name(), name);
- IElementEditService provider = ElementEditServiceUtils.getCommandProvider(ElementTypeRegistry.getInstance().getType(IUMLRTElementTypes.CAPSULE_PART_ID));
- if (provider != null) {
- ICommand setCommand = provider.getEditCommand(setRequest);
-
- if (setCommand != null && setCommand.canExecute()) {
- try {
- setCommand.execute(new NullProgressMonitor(), null);
- } catch (ExecutionException e) {
- Activator.log.error(e);
- }
- }
- }
- }
-
protected void setCapsuleAsType(TransactionalEditingDomain editingDomain, Property capsulePart, EObject type) {
SetRequest setRequest = new SetRequest(editingDomain, capsulePart, UMLPackage.eINSTANCE.getTypedElement_Type(), type);
@@ -198,8 +181,4 @@ public class CreateCapsulePartAndDisplayCommand extends AbstractCommand {
return null;
}
- public void setCapsulePartName(String name) {
- this.name = name;
- }
-
}
diff --git a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.classpath b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.classpath
index 098194ca4..eca7bdba8 100644
--- a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.classpath
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.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/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.settings/org.eclipse.jdt.core.prefs b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.settings/org.eclipse.jdt.core.prefs
index 28f0d0f67..9b6d675fd 100644
--- a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/.settings/org.eclipse.jdt.core.prefs
@@ -1,15 +1,15 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
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/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/META-INF/MANIFEST.MF b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/META-INF/MANIFEST.MF
index 8a23b9ade..d175088ff 100644
--- a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/META-INF/MANIFEST.MF
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/META-INF/MANIFEST.MF
@@ -51,11 +51,12 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.papyrus.infra.core.sashwindows.di;bundle-version="1.2.0",
org.eclipse.papyrusrt.umlrt.core.cpp;bundle-version="0.7.2",
org.eclipse.papyrusrt.junit;bundle-version="0.7.2"
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.papyrusrt.umlrt.core.tests,
org.eclipse.papyrusrt.umlrt.core.tests.creation,
org.eclipse.papyrusrt.umlrt.core.tests.defaultlanguage,
org.eclipse.papyrusrt.umlrt.core.tests.deletion,
org.eclipse.papyrusrt.umlrt.core.tests.edition,
+ org.eclipse.papyrusrt.umlrt.core.tests.types.advice,
org.eclipse.papyrusrt.umlrt.core.tests.utils
diff --git a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.di b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.di
new file mode 100644
index 000000000..bf9abab34
--- /dev/null
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"/>
diff --git a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.notation b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.notation
new file mode 100644
index 000000000..0c68b678d
--- /dev/null
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.notation
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:configuration="http://www.eclipse.org/papyrus/infra/viewpoints/configuration" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/viewpoints/policy/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <notation:Diagram xmi:id="_o0AJIBIIEeaM3pwxY5WOXQ" type="CompositeStructure" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_o0B-UBIIEeaM3pwxY5WOXQ" type="Class_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_o0ClYBIIEeaM3pwxY5WOXQ" type="Class_NameLabel"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_o0ClYRIIEeaM3pwxY5WOXQ" type="Class_FloatingNameLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_o0ClYhIIEeaM3pwxY5WOXQ" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_o0ClYxIIEeaM3pwxY5WOXQ" type="Class_StructureCompartment">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_o0ClZBIIEeaM3pwxY5WOXQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_o0ClZRIIEeaM3pwxY5WOXQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="party.uml#_ox9hwBIIEeaM3pwxY5WOXQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_o0B-URIIEeaM3pwxY5WOXQ" x="40" y="40" width="500" height="250"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_o0AJIRIIEeaM3pwxY5WOXQ" name="diagram_compatibility_version" stringValue="1.2.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_o0AJIhIIEeaM3pwxY5WOXQ"/>
+ <styles xmi:type="style:PapyrusViewStyle" xmi:id="_o0AJIxIIEeaM3pwxY5WOXQ">
+ <owner xmi:type="uml:Class" href="party.uml#_ox9hwBIIEeaM3pwxY5WOXQ"/>
+ <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/>
+ </styles>
+ <element xmi:type="uml:Class" href="party.uml#_ox9hwBIIEeaM3pwxY5WOXQ"/>
+ </notation:Diagram>
+ <notation:Diagram xmi:id="_qSti0BIIEeaM3pwxY5WOXQ" type="CompositeStructure" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_qSti1BIIEeaM3pwxY5WOXQ" type="Class_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_qSuJ4BIIEeaM3pwxY5WOXQ" type="Class_NameLabel"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_qSuJ4RIIEeaM3pwxY5WOXQ" type="Class_FloatingNameLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_qSuJ4hIIEeaM3pwxY5WOXQ" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_qSuJ4xIIEeaM3pwxY5WOXQ" type="Class_StructureCompartment">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_qSuJ5BIIEeaM3pwxY5WOXQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_qSuJ5RIIEeaM3pwxY5WOXQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="party.uml#_qSp4cBIIEeaM3pwxY5WOXQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_qSti1RIIEeaM3pwxY5WOXQ" x="40" y="40" width="500" height="250"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_qSti0RIIEeaM3pwxY5WOXQ" name="diagram_compatibility_version" stringValue="1.2.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_qSti0hIIEeaM3pwxY5WOXQ"/>
+ <styles xmi:type="style:PapyrusViewStyle" xmi:id="_qSti0xIIEeaM3pwxY5WOXQ">
+ <owner xmi:type="uml:Class" href="party.uml#_qSp4cBIIEeaM3pwxY5WOXQ"/>
+ <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/>
+ </styles>
+ <element xmi:type="uml:Class" href="party.uml#_qSp4cBIIEeaM3pwxY5WOXQ"/>
+ </notation:Diagram>
+ <notation:Diagram xmi:id="_ZBaA0BINEeaM3pwxY5WOXQ" type="CompositeStructure" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_ZBan4BINEeaM3pwxY5WOXQ" type="Class_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_ZBan4hINEeaM3pwxY5WOXQ" type="Class_NameLabel"/>
+ <children xmi:type="notation:DecorationNode" xmi:id="_ZBan4xINEeaM3pwxY5WOXQ" type="Class_FloatingNameLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_ZBan5BINEeaM3pwxY5WOXQ" y="5"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_ZBan5RINEeaM3pwxY5WOXQ" type="Class_StructureCompartment">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_ZBan5hINEeaM3pwxY5WOXQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ZBan5xINEeaM3pwxY5WOXQ"/>
+ </children>
+ <element xmi:type="uml:Class" href="party.uml#_Y_YAgBINEeaM3pwxY5WOXQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ZBan4RINEeaM3pwxY5WOXQ" x="40" y="40" width="500" height="250"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_ZBaA0RINEeaM3pwxY5WOXQ" name="diagram_compatibility_version" stringValue="1.2.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_ZBaA0hINEeaM3pwxY5WOXQ"/>
+ <styles xmi:type="style:PapyrusViewStyle" xmi:id="_ZBaA0xINEeaM3pwxY5WOXQ">
+ <owner xmi:type="uml:Class" href="party.uml#_Y_YAgBINEeaM3pwxY5WOXQ"/>
+ <configuration xmi:type="configuration:PapyrusDiagram" href="platform:/plugin/org.eclipse.papyrusrt.umlrt.tooling.diagram.common/configuration/UMLRT.configuration#_Z79eQHcZEeSnWeKqQOfW2A"/>
+ </styles>
+ <element xmi:type="uml:Class" href="party.uml#_Y_YAgBINEeaM3pwxY5WOXQ"/>
+ </notation:Diagram>
+</xmi:XMI>
diff --git a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.uml b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.uml
new file mode 100644
index 000000000..6a9b67c00
--- /dev/null
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/resource/party.uml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:UMLRealTime="http://www.eclipse.org/papyrus/umlrt" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML">
+ <uml:Model xmi:id="_mncK8BIIEeaM3pwxY5WOXQ" name="model">
+ <packagedElement xmi:type="uml:Class" xmi:id="_ox9hwBIIEeaM3pwxY5WOXQ" name="Party" isActive="true"/>
+ <packagedElement xmi:type="uml:Class" xmi:id="_qSp4cBIIEeaM3pwxY5WOXQ" name="Guest" isActive="true"/>
+ <packagedElement xmi:type="uml:Package" xmi:id="_r44PYBIIEeaM3pwxY5WOXQ" name="Greeter">
+ <packagedElement xmi:type="uml:Collaboration" xmi:id="_r4yv0BIIEeaM3pwxY5WOXQ" name="Greeter">
+ <interfaceRealization xmi:type="uml:InterfaceRealization" xmi:id="_r49u8BIIEeaM3pwxY5WOXQ" client="_r4yv0BIIEeaM3pwxY5WOXQ" supplier="_r47SsBIIEeaM3pwxY5WOXQ" contract="_r47SsBIIEeaM3pwxY5WOXQ"/>
+ <interfaceRealization xmi:type="uml:InterfaceRealization" xmi:id="_r5EcoBIIEeaM3pwxY5WOXQ" client="_r4yv0BIIEeaM3pwxY5WOXQ" supplier="_r5CncBIIEeaM3pwxY5WOXQ" contract="_r5CncBIIEeaM3pwxY5WOXQ"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Interface" xmi:id="_r47SsBIIEeaM3pwxY5WOXQ" name="Greeter"/>
+ <packagedElement xmi:type="uml:Interface" xmi:id="_r4_kIBIIEeaM3pwxY5WOXQ" name="Greeter~"/>
+ <packagedElement xmi:type="uml:Usage" xmi:id="_r5BZUBIIEeaM3pwxY5WOXQ" client="_r4yv0BIIEeaM3pwxY5WOXQ" supplier="_r4_kIBIIEeaM3pwxY5WOXQ"/>
+ <packagedElement xmi:type="uml:AnyReceiveEvent" xmi:id="_r5CAYBIIEeaM3pwxY5WOXQ" name="*"/>
+ <packagedElement xmi:type="uml:Interface" xmi:id="_r5CncBIIEeaM3pwxY5WOXQ" name="GreeterIO"/>
+ <packagedElement xmi:type="uml:Usage" xmi:id="_r5FDsBIIEeaM3pwxY5WOXQ" client="_r4yv0BIIEeaM3pwxY5WOXQ" supplier="_r5CncBIIEeaM3pwxY5WOXQ"/>
+ </packagedElement>
+ <packagedElement xmi:type="uml:Class" xmi:id="_Y_YAgBINEeaM3pwxY5WOXQ" name="Meeting" isActive="true"/>
+ <profileApplication xmi:type="uml:ProfileApplication" xmi:id="_mqrFIBIIEeaM3pwxY5WOXQ">
+ <eAnnotations xmi:type="ecore:EAnnotation" xmi:id="_mqrsMBIIEeaM3pwxY5WOXQ" source="http://www.eclipse.org/uml2/2.0.0/UML">
+ <references xmi:type="ecore:EPackage" href="http://www.eclipse.org/papyrus/umlrt#/"/>
+ </eAnnotations>
+ <appliedProfile xmi:type="uml:Profile" href="pathmap://UML_RT_PROFILE/uml-rt.profile.uml#_1h74oEeVEeO0lv5O1DTHOQ"/>
+ </profileApplication>
+ </uml:Model>
+ <UMLRealTime:Capsule xmi:id="_o0DMcBIIEeaM3pwxY5WOXQ" base_Class="_ox9hwBIIEeaM3pwxY5WOXQ"/>
+ <UMLRealTime:Capsule xmi:id="_qSuw8BIIEeaM3pwxY5WOXQ" base_Class="_qSp4cBIIEeaM3pwxY5WOXQ"/>
+ <UMLRealTime:ProtocolContainer xmi:id="_r45dgBIIEeaM3pwxY5WOXQ" base_Package="_r44PYBIIEeaM3pwxY5WOXQ"/>
+ <UMLRealTime:RTMessageSet xmi:id="_r48g0BIIEeaM3pwxY5WOXQ" base_Interface="_r47SsBIIEeaM3pwxY5WOXQ"/>
+ <UMLRealTime:RTMessageSet xmi:id="_r5AyQBIIEeaM3pwxY5WOXQ" base_Interface="_r4_kIBIIEeaM3pwxY5WOXQ" rtMsgKind="out"/>
+ <UMLRealTime:RTMessageSet xmi:id="_r5DOgBIIEeaM3pwxY5WOXQ" base_Interface="_r5CncBIIEeaM3pwxY5WOXQ" rtMsgKind="inOut"/>
+ <UMLRealTime:Protocol xmi:id="_r5FqwBIIEeaM3pwxY5WOXQ" base_Collaboration="_r4yv0BIIEeaM3pwxY5WOXQ"/>
+ <UMLRealTime:Capsule xmi:id="_ZBbO8BINEeaM3pwxY5WOXQ" base_Class="_Y_YAgBINEeaM3pwxY5WOXQ"/>
+</xmi:XMI>
diff --git a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/types/advice/CapsulePartDefaultNameTest.java b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/types/advice/CapsulePartDefaultNameTest.java
new file mode 100644
index 000000000..723fbc5ce
--- /dev/null
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/types/advice/CapsulePartDefaultNameTest.java
@@ -0,0 +1,136 @@
+/*****************************************************************************
+ * 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.papyrusrt.umlrt.core.tests.types.advice;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import javax.inject.Named;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
+import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
+import org.eclipse.papyrus.junit.utils.rules.HouseKeeper;
+import org.eclipse.papyrus.junit.utils.rules.ModelSetFixture;
+import org.eclipse.papyrus.junit.utils.rules.PluginResource;
+import org.eclipse.papyrus.junit.utils.rules.ServiceRegistryModelSetFixture;
+import org.eclipse.papyrusrt.junit.rules.FixtureElementRule;
+import org.eclipse.papyrusrt.umlrt.core.types.UMLRTElementTypesEnumerator;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test suite for default naming of capsule-parts in capsules.
+ */
+@PluginResource("resource/party.di")
+public class CapsulePartDefaultNameTest {
+ @Rule
+ public HouseKeeper houseKeeper = new HouseKeeper();
+
+ @Rule
+ public ModelSetFixture modelSet = new ServiceRegistryModelSetFixture();
+
+ @Rule
+ public FixtureElementRule fixtureRule = new FixtureElementRule();
+
+ @Named("model::Party")
+ private Class partyCapsule;
+
+ @Named("model::Guest")
+ private Class guestCapsule;
+
+ @Named("model::Meeting")
+ private Class meetingCapsule;
+
+ /**
+ * Initializes me.
+ */
+ public CapsulePartDefaultNameTest() {
+ super();
+ }
+
+ /**
+ * Verify the default name of the only capsule-part of its type.
+ */
+ @Test
+ public void singleCapsulePart() throws Exception {
+ Property part = createCapsulePart(partyCapsule, guestCapsule);
+ assertThat(part.getName(), is("guest"));
+
+ // In a different capsule
+ part = createCapsulePart(meetingCapsule, guestCapsule);
+ assertThat(part.getName(), is("guest"));
+ }
+
+ /**
+ * Verify the default names of multiple capsule-parts of the same type.
+ */
+ @Test
+ public void multipleCapsuleParts() throws Exception {
+ Property part = createCapsulePart(partyCapsule, guestCapsule);
+ assertThat(part.getName(), is("guest"));
+
+ // In the same capsule
+ part = createCapsulePart(partyCapsule, guestCapsule);
+ assertThat(part.getName(), is("guest2"));
+
+ // Again
+ part = createCapsulePart(partyCapsule, guestCapsule);
+ assertThat(part.getName(), is("guest3"));
+ }
+
+ //
+ // Test framework
+ //
+
+ Property createCapsulePart(Class capsule, Class partType) {
+ IElementType typeToCreate = UMLRTElementTypesEnumerator.CAPSULE_PART;
+
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(modelSet.getEditingDomain(), "Create Capsule Part");
+ command.add(ElementEditServiceUtils.getCreateChildCommandWithContext(capsule, (IHintedType) typeToCreate));
+
+ ICommand setType = new AbstractTransactionalCommand(modelSet.getEditingDomain(), "Set Type", null) {
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // The new part is the last one added
+ Property newPart = capsule.getOwnedAttributes().get(capsule.getOwnedAttributes().size() - 1);
+
+ SetRequest request = new SetRequest(getEditingDomain(), newPart, UMLPackage.Literals.TYPED_ELEMENT__TYPE, partType);
+ ICommand delegate = ElementEditServiceUtils.getCommandProvider(newPart).getEditCommand(request);
+ delegate.execute(monitor, info);
+
+ return CommandResult.newOKCommandResult(newPart);
+ }
+ };
+ command.add(setType);
+ modelSet.execute(command);
+
+ Property result = (Property) setType.getCommandResult().getReturnValue();
+ assertThat("Capsule Part creation failed", result, notNullValue());
+ return result;
+ }
+}
diff --git a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/types/advice/PortDefaultNameTest.java b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/types/advice/PortDefaultNameTest.java
new file mode 100644
index 000000000..756484ae7
--- /dev/null
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/types/advice/PortDefaultNameTest.java
@@ -0,0 +1,158 @@
+/*****************************************************************************
+ * 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.papyrusrt.umlrt.core.tests.types.advice;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import javax.inject.Named;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
+import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
+import org.eclipse.papyrus.junit.utils.rules.HouseKeeper;
+import org.eclipse.papyrus.junit.utils.rules.ModelSetFixture;
+import org.eclipse.papyrus.junit.utils.rules.PluginResource;
+import org.eclipse.papyrus.junit.utils.rules.ServiceRegistryModelSetFixture;
+import org.eclipse.papyrusrt.junit.rules.FixtureElementRule;
+import org.eclipse.papyrusrt.umlrt.core.types.IUMLRTElementTypes;
+import org.eclipse.papyrusrt.umlrt.core.utils.RTPortKindEnum;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Collaboration;
+import org.eclipse.uml2.uml.Port;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test suite default naming of ports on capsules.
+ */
+@PluginResource("resource/party.di")
+public class PortDefaultNameTest {
+ @Rule
+ public HouseKeeper houseKeeper = new HouseKeeper();
+
+ @Rule
+ public ModelSetFixture modelSet = new ServiceRegistryModelSetFixture();
+
+ @Rule
+ public FixtureElementRule fixtureRule = new FixtureElementRule();
+
+ @Named("model::Party")
+ private Class partyCapsule;
+
+ @Named("model::Guest")
+ private Class guestCapsule;
+
+ @Named("model::Greeter::Greeter")
+ private Collaboration greeterProtocol;
+
+ /**
+ * Initializes me.
+ */
+ public PortDefaultNameTest() {
+ super();
+ }
+
+ /**
+ * Verify the default name of the only port of its type.
+ */
+ @Test
+ public void singlePort() throws Exception {
+ Port port = createPort(partyCapsule, greeterProtocol, RTPortKindEnum.EXTERNAL);
+ assertThat(port.getName(), is("greeter"));
+
+ // In a different capsule
+ port = createPort(guestCapsule, greeterProtocol, RTPortKindEnum.EXTERNAL);
+ assertThat(port.getName(), is("greeter"));
+ }
+
+ /**
+ * Verify the default names of multiple ports of the same type.
+ */
+ @Test
+ public void multiplePorts() throws Exception {
+ Port port = createPort(partyCapsule, greeterProtocol, RTPortKindEnum.EXTERNAL);
+ assertThat(port.getName(), is("greeter"));
+
+ // In the same capsule (doesn't matter the port kind)
+ port = createPort(partyCapsule, greeterProtocol, RTPortKindEnum.INTERNAL);
+ assertThat(port.getName(), is("greeter2"));
+
+ // Again
+ port = createPort(partyCapsule, greeterProtocol, RTPortKindEnum.RELAY);
+ assertThat(port.getName(), is("greeter3"));
+ }
+
+ //
+ // Test framework
+ //
+
+ Port createPort(Class capsule, Collaboration protocol, RTPortKindEnum kind) {
+ IElementType typeToCreate;
+ switch (kind) {
+ case EXTERNAL:
+ typeToCreate = ElementTypeRegistry.getInstance().getType(IUMLRTElementTypes.EXTERNAL_BEHAVIOR_PORT_ID);
+ break;
+ case INTERNAL:
+ typeToCreate = ElementTypeRegistry.getInstance().getType(IUMLRTElementTypes.INTERNAL_BEHAVIOR_PORT_ID);
+ break;
+ case RELAY:
+ typeToCreate = ElementTypeRegistry.getInstance().getType(IUMLRTElementTypes.RELAY_PORT_ID);
+ break;
+ case SAP:
+ typeToCreate = ElementTypeRegistry.getInstance().getType(IUMLRTElementTypes.SERVICE_ACCESS_POINT_ID);
+ break;
+ case SPP:
+ typeToCreate = ElementTypeRegistry.getInstance().getType(IUMLRTElementTypes.SERVICE_PROVISION_POINT_ID);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid port kind: " + kind);
+ }
+
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(modelSet.getEditingDomain(), "Create Port");
+ command.add(ElementEditServiceUtils.getCreateChildCommandWithContext(capsule, (IHintedType) typeToCreate));
+
+ ICommand setType = new AbstractTransactionalCommand(modelSet.getEditingDomain(), "Set Type", null) {
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // The new port is the last one added
+ Port newPort = capsule.getOwnedPorts().get(capsule.getOwnedPorts().size() - 1);
+
+ SetRequest request = new SetRequest(getEditingDomain(), newPort, UMLPackage.Literals.TYPED_ELEMENT__TYPE, protocol);
+ ICommand delegate = ElementEditServiceUtils.getCommandProvider(newPort).getEditCommand(request);
+ delegate.execute(monitor, info);
+
+ return CommandResult.newOKCommandResult(newPort);
+ }
+ };
+ command.add(setType);
+ modelSet.execute(command);
+
+ Port result = (Port) setType.getCommandResult().getReturnValue();
+ assertThat("Port creation failed", result, notNullValue());
+ return result;
+ }
+}
diff --git a/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/utils/PostTransactionExecutorTest.java b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/utils/PostTransactionExecutorTest.java
new file mode 100644
index 000000000..9d2451b1f
--- /dev/null
+++ b/tests/junit/umlrt/core/org.eclipse.papyrusrt.umlrt.core.tests/src/org/eclipse/papyrusrt/umlrt/core/tests/utils/PostTransactionExecutorTest.java
@@ -0,0 +1,353 @@
+/*****************************************************************************
+ * 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.papyrusrt.umlrt.core.tests.utils;
+
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.emf.transaction.ResourceSetListenerImpl;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.TransactionalEditingDomainEvent;
+import org.eclipse.emf.transaction.TransactionalEditingDomainListener;
+import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.papyrus.junit.utils.rules.AbstractHouseKeeperRule.CleanUp;
+import org.eclipse.papyrus.junit.utils.rules.HouseKeeper;
+import org.eclipse.papyrus.junit.utils.rules.ModelSetFixture;
+import org.eclipse.papyrus.junit.utils.rules.PluginResource;
+import org.eclipse.papyrusrt.umlrt.core.utils.PostTransactionExecutor;
+import org.eclipse.swt.widgets.Display;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+/**
+ * Test suite for the {@link PostTransactionExecutor} API.
+ */
+@PluginResource("resource/TestModel.di")
+public class PostTransactionExecutorTest {
+ @ClassRule
+ public static HouseKeeper.Static houseKeeper = new HouseKeeper.Static();
+
+ @ClassRule
+ public static ModelSetFixture modelSet = new ModelSetFixture();
+
+ @CleanUp
+ private static Executor fixture;
+
+ /**
+ * Initializes me.
+ */
+ public PostTransactionExecutorTest() {
+ super();
+ }
+
+ /**
+ * Verify the execution of runnables after the close of a read-only transaction.
+ */
+ @Test
+ public void postReadTransaction() throws Exception {
+ // We expect read notification(s) to be followed by the post-commit execution
+ Canary canary = new Canary();
+ canary.expectModelNotifications();
+ canary.expectExecution();
+ canary.close();
+
+ // Do something in a read-only transaction
+ modelSet.getEditingDomain().runExclusive(() -> {
+ fixture.execute(canary);
+
+ // This generates read-compatible notifications for a post-commit listener
+ modelSet.getResourceSet().createResource(URI.createURI("http://localhost/bogus.xmi"));
+ });
+
+ canary.assertTimeline();
+ }
+
+ /**
+ * Verify the execution of runnables after the close of a read/write transaction.
+ */
+ @Test
+ public void postWriteTransaction() throws Exception {
+ // We expect write notification(s) to be followed by the post-commit execution
+ Canary canary = new Canary();
+ canary.expectModelNotifications();
+ canary.expectExecution();
+ canary.close();
+
+ // Do something in a read/write transaction
+ modelSet.execute(new RecordingCommand(modelSet.getEditingDomain(), "Do It") {
+
+ @Override
+ protected void doExecute() {
+ fixture.execute(canary);
+
+ // This generates read-compatible notifications for a post-commit listener
+ modelSet.getModel().setName("Foo");
+ }
+ });
+
+ canary.assertTimeline();
+ }
+
+ /**
+ * Verify the execution of runnables after the failure of a read/write transaction.
+ */
+ @Test
+ public void postTransactionRollback() throws Exception {
+ // We expect rollback to be followed by the post-rollback execution
+ Canary canary = new Canary();
+ canary.expectRollback();
+ canary.expectExecution();
+ canary.close();
+
+ // Do something in a read/write transaction
+ modelSet.execute(new RecordingCommand(modelSet.getEditingDomain(), "Do It") {
+
+ @Override
+ protected void doExecute() {
+ fixture.execute(canary);
+
+ ((InternalTransactionalEditingDomain) modelSet.getEditingDomain())
+ .getActiveTransaction().abort(
+ new Status(IStatus.ERROR,
+ "org.eclipse.papyrusrt.umlrt.core.test",
+ "Trigger roll-back"));
+ }
+ });
+
+ canary.assertTimeline();
+ }
+
+ /**
+ * Verify the execution of runnables not in the context of a transaction.
+ */
+ @Test
+ public void noTransaction() throws Exception {
+ // We expect rollback to be followed by the post-rollback execution
+ Canary canary = new Canary();
+ canary.expectUIThread();
+ canary.expectExecution();
+ canary.close();
+
+ // Do something not in a transaction
+ fixture.execute(canary);
+
+ canary.assertTimeline();
+ }
+
+ //
+ // Test framework
+ //
+
+ @BeforeClass
+ public static void createFixture() {
+ fixture = PostTransactionExecutor.getInstance(modelSet.getEditingDomain());
+ }
+
+ /**
+ * A test fixture that observes and asserts a specific timeline sequence of events.
+ */
+ static class Canary extends ResourceSetListenerImpl implements Runnable, TransactionalEditingDomainListener {
+ private final Queue<TimelineEventKind> expectedTimeline = new LinkedList<>();
+ private final List<String> timelineErrors = new ArrayList<>(2);
+
+ private final TransactionalEditingDomain domain;
+ private final TransactionalEditingDomain.Lifecycle domainLifecycle;
+
+ private final Lock lock = new ReentrantLock();
+ private final Condition executedCond = lock.newCondition();
+ private volatile boolean executed;
+
+ Canary() {
+ super();
+
+ domain = modelSet.getEditingDomain();
+ domain.addResourceSetListener(this);
+
+ domainLifecycle = TransactionUtil.getAdapter(domain, TransactionalEditingDomain.Lifecycle.class);
+ domainLifecycle.addTransactionalEditingDomainListener(this);
+ }
+
+ //
+ // Canary protocol
+ //
+
+ void expectModelNotifications() {
+ expectedTimeline.add(TimelineEventKind.MODEL_NOTIFICATIONS);
+ }
+
+ void expectRollback() {
+ expectedTimeline.add(TimelineEventKind.ROLLBACK);
+ }
+
+ void expectUIThread() {
+ expectedTimeline.add(TimelineEventKind.UI_THREAD);
+ }
+
+ void expectExecution() {
+ expectedTimeline.add(TimelineEventKind.EXECUTION);
+ }
+
+ void close() {
+ expectedTimeline.add(TimelineEventKind.DONE);
+ }
+
+ void assertTimeline() {
+ // First, disconnect me
+ domainLifecycle.removeTransactionalEditingDomainListener(this);
+ domain.removeResourceSetListener(this);
+
+ // Wait for execution on another thread, if appropriate
+ try {
+ awaitExecuted();
+ } catch (InterruptedException e) {
+ fail("Test interrupted waiting for canary execution");
+ }
+
+ if (!timelineErrors.isEmpty()) {
+ fail("Timeline out of sequence:\n "
+ + timelineErrors.stream().collect(Collectors.joining("\n ")));
+ }
+
+ if (expectedTimeline.peek() != TimelineEventKind.DONE) {
+ fail("Test timeline not finished");
+ }
+ }
+
+ private void encounter(TimelineEventKind timelineEvent) {
+ timelineEvent.dequeue(expectedTimeline, timelineErrors);
+ }
+
+ private void awaitExecuted() throws InterruptedException {
+ // Be generous in case of high build server load
+ Date deadline = new Date(System.currentTimeMillis() + 5000L);
+
+ lock.lock();
+
+ try {
+ while (!executed) {
+ executedCond.awaitUntil(deadline);
+
+ if (deadline.before(new Date(System.currentTimeMillis()))) {
+ // Ran out of time. The test will fail
+ break;
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ //
+ // Event protocols
+ //
+
+ @Override
+ public boolean isPostcommitOnly() {
+ return true;
+ }
+
+ @Override
+ public void resourceSetChanged(ResourceSetChangeEvent event) {
+ encounter(TimelineEventKind.MODEL_NOTIFICATIONS);
+ }
+
+ @Override
+ public void transactionClosing(TransactionalEditingDomainEvent event) {
+ if (event.getTransaction().getStatus().getSeverity() >= IStatus.ERROR) {
+ // Rolling back
+ encounter(TimelineEventKind.ROLLBACK);
+ }
+ }
+
+ @Override
+ public void run() {
+ if (Display.getCurrent() != null) {
+ encounter(TimelineEventKind.UI_THREAD);
+ }
+
+ encounter(TimelineEventKind.EXECUTION);
+
+ lock.lock();
+
+ try {
+ executed = true;
+ executedCond.signalAll();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ @Override
+ public void transactionStarting(TransactionalEditingDomainEvent event) {
+ // Pass
+ }
+
+ @Override
+ public void transactionInterrupted(TransactionalEditingDomainEvent event) {
+ // Pass
+ }
+
+ @Override
+ public void transactionStarted(TransactionalEditingDomainEvent event) {
+ // Pass
+ }
+
+ @Override
+ public void transactionClosed(TransactionalEditingDomainEvent event) {
+ // pass
+ }
+
+ @Override
+ public void editingDomainDisposing(TransactionalEditingDomainEvent event) {
+ // Pass
+ }
+
+ //
+ // Nested types
+ //
+
+ private static enum TimelineEventKind {
+ MODEL_NOTIFICATIONS, ROLLBACK, UI_THREAD, EXECUTION, DONE;
+
+ void dequeue(Queue<? extends TimelineEventKind> expectedTimeline, List<? super String> errors) {
+ TimelineEventKind expected = expectedTimeline.peek();
+ if (expected == this) {
+ // Dequeue it
+ expectedTimeline.remove();
+ } else {
+ // Event out of sequence
+ errors.add(String.format("Got %s; expected %s", this, expected));
+ }
+ }
+ }
+
+ }
+}

Back to the top