Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2017-01-31 02:03:47 +0000
committerChristian W. Damus2017-01-31 02:03:47 +0000
commitdf8a130a91d28b2db5f0ce676f3afb18f554fe5e (patch)
treeca9fa21a1653ddd8b526552389396b8e92b6c1f8
parentb5b400ba0e697f373f60c51a730c9845efda5f3e (diff)
downloadorg.eclipse.papyrus-rt-committers/cdamus/inheritance.tar.gz
org.eclipse.papyrus-rt-committers/cdamus/inheritance.tar.xz
org.eclipse.papyrus-rt-committers/cdamus/inheritance.zip
Bug 510315: [UML-RT] UML specific implementation for state machinescommitters/cdamus/inheritance
More extensive notification support in the façade metamodel, beyond what is required to support the Capsule and Protocol properties in the property sheet UI. https://bugs.eclipse.org/bugs/show_bug.cgi?id=510315 Change-Id: I366b195f9d7acb86c4c5bc5729a8b412205b7202
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePartKind.java85
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTPortKind.java132
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsuleImpl.java20
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsulePartImpl.java97
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTClassifierImpl.java98
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTConnectorImpl.java172
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTNamedElementImpl.java27
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPackageImpl.java151
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPortImpl.java155
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolImpl.java35
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolMessageImpl.java67
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTReplicatedElementImpl.java201
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/FacadeObjectImpl.java16
-rw-r--r--plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritanceAdapter.java40
-rw-r--r--tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsuleFacadeNotificationTest.java113
-rw-r--r--tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsulePartNotificationTest.java197
-rw-r--r--tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ConnectorNotificationTest.java169
-rw-r--r--tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PackageFacadeNotificationTest.java94
-rw-r--r--tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PortFacadeNotificationTest.java297
-rw-r--r--tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolFacadeNotificationTest.java93
-rw-r--r--tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolMessageFacadeNotificationTest.java94
-rw-r--r--tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/ModelFixture.java81
22 files changed, 2380 insertions, 54 deletions
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePartKind.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePartKind.java
index 4d0ed4f38..1b09ad98c 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePartKind.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTCapsulePartKind.java
@@ -17,6 +17,8 @@ import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.uml2.uml.AggregationKind;
+import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
/**
* <!-- begin-user-doc -->
@@ -316,6 +318,89 @@ public enum UMLRTCapsulePartKind implements Enumerator {
}
/**
+ * Computes the kind that is like me but for capsule-parts of the given {@code required} kind.
+ *
+ * @param required
+ * the requireness kind from which to derive a new capsule-part kind
+ * @return the new capsule-part kind, which may be {@link #NULL} if this value of {@code required}
+ * does not make sense with the other attributes that I imply
+ */
+ public UMLRTCapsulePartKind setRequired(boolean required) {
+ if (required == isRequired()) {
+ return this;
+ } else {
+ switch (this) {
+ case OPTIONAL:
+ return FIXED;
+ case FIXED:
+ return OPTIONAL;
+ case PLUG_IN:
+ // We don't consider aggregation if the multiplicity is required
+ return FIXED;
+ default:
+ return NULL;
+ }
+ }
+ }
+
+ /**
+ * Computes the kind that is like me but for capsule-parts of the given {@code composite} kind.
+ *
+ * @param composite
+ * the compositeness kind from which to derive a new capsule-part kind
+ * @return the new capsule-part kind, which may be {@link #NULL} if this value of {@code composite}
+ * does not make sense with the other attributes that I imply
+ */
+ public UMLRTCapsulePartKind setComposite(boolean composite) {
+ if (composite == isComposite()) {
+ return this;
+ } else {
+ switch (this) {
+ case OPTIONAL:
+ return PLUG_IN;
+ case PLUG_IN:
+ return OPTIONAL;
+ default:
+ return NULL;
+ }
+ }
+ }
+
+ /**
+ * Computes the kind of a capsule-part by its attributes.
+ *
+ * @param lowerBound
+ * the capsule-part's lower bound
+ * @param upperBound
+ * the capsule-part's upper bound
+ * @param aggregation
+ * the capsule-part's aggregation
+ *
+ * @return the capsule-part kind, or {@link #NULL} if the specific attributes make no sense together
+ */
+ public static UMLRTCapsulePartKind get(int lowerBound, int upperBound, AggregationKind aggregation) {
+ UMLRTCapsulePartKind result = UMLRTCapsulePartKind.NULL;
+
+ if ((lowerBound > 0) && (upperBound > 0)) {
+ result = FIXED;
+ } else if ((lowerBound == 0) || (upperBound == LiteralUnlimitedNatural.UNLIMITED)) {
+ switch (aggregation) {
+ case COMPOSITE_LITERAL:
+ result = OPTIONAL;
+ break;
+ case SHARED_LITERAL:
+ result = PLUG_IN;
+ break;
+ default:
+ // Pass
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
* Returns the literal value of the enumerator, which is its string representation.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTPortKind.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTPortKind.java
index eb4f6a0b5..eb844c50e 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTPortKind.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/UMLRTPortKind.java
@@ -426,6 +426,138 @@ public enum UMLRTPortKind implements Enumerator {
}
/**
+ * Computes the kind that is like me but for ports of the given {@code service} kind.
+ *
+ * @param service
+ * the service kind from which to derive a new port kind
+ * @return the new port kind, which may be {@link #NULL} if this value of {@code service}
+ * does not make sense with the other attributes that I imply
+ */
+ public UMLRTPortKind setService(boolean service) {
+ if (service == isService()) {
+ return this;
+ } else {
+ switch (this) {
+ case EXTERNAL_BEHAVIOR:
+ return INTERNAL_BEHAVIOR;
+ case INTERNAL_BEHAVIOR:
+ return EXTERNAL_BEHAVIOR;
+ case SPP:
+ return SAP;
+ case SAP:
+ return SPP;
+ default:
+ return NULL;
+ }
+ }
+ }
+
+ /**
+ * Computes the kind that is like me but for ports of the given {@code behavior} kind.
+ *
+ * @param behavior
+ * the behavior kind from which to derive a new port kind
+ * @return the new port kind, which may be {@link #NULL} if this value of {@code behavior}
+ * does not make sense with the other attributes that I imply
+ */
+ public UMLRTPortKind setBehavior(boolean behavior) {
+ if (behavior == isBehavior()) {
+ return this;
+ } else {
+ switch (this) {
+ case EXTERNAL_BEHAVIOR:
+ return RELAY;
+ case RELAY:
+ return EXTERNAL_BEHAVIOR;
+ default:
+ return NULL;
+ }
+ }
+ }
+
+ /**
+ * Computes the kind that is like me but for ports of the given {@code wired} kind.
+ *
+ * @param wired
+ * the wiredness kind from which to derive a new port kind
+ * @return the new port kind, which may be {@link #NULL} if this value of {@code wired}
+ * does not make sense with the other attributes that I imply
+ */
+ public UMLRTPortKind setWired(boolean wired) {
+ if (wired == isWired()) {
+ return this;
+ } else {
+ switch (this) {
+ case EXTERNAL_BEHAVIOR:
+ return SPP;
+ case SPP:
+ return EXTERNAL_BEHAVIOR;
+ case INTERNAL_BEHAVIOR:
+ return SAP;
+ case SAP:
+ return INTERNAL_BEHAVIOR;
+ default:
+ return NULL;
+ }
+ }
+ }
+
+ /**
+ * Computes the kind that is like me but for ports of the given {@code publish} kind.
+ *
+ * @param publish
+ * the publication kind from which to derive a new port kind
+ * @return the new port kind, which may be {@link #NULL} if this value of {@code publish}
+ * does not make sense with the other attributes that I imply
+ */
+ public UMLRTPortKind setPublish(boolean publish) {
+ if (publish == isPublish()) {
+ return this;
+ } else {
+ switch (this) {
+ case SPP:
+ return SAP;
+ case SAP:
+ return SPP;
+ default:
+ return NULL;
+ }
+ }
+ }
+
+ /**
+ * Computes the kind of a port by its attributes.
+ *
+ * @param service
+ * whether the port is a service port
+ * @param behavior
+ * whether the port is a behavior port
+ * @param wired
+ * whether the port is wired
+ * @param publish
+ * whether the port is published
+ *
+ * @return the port kind, or {@link #NULL} if the specific attributes make no sense together
+ */
+ public static UMLRTPortKind get(boolean service, boolean behavior, boolean wired, boolean publish) {
+ UMLRTPortKind result = NULL;
+
+ if (service && wired && behavior && !publish) {
+ result = EXTERNAL_BEHAVIOR;
+ } else if (behavior && publish && !wired) {
+ result = SPP; // isService won't be checked here => Cf. bug 477033
+ } else if (wired && behavior && !service && !publish) {
+ result = INTERNAL_BEHAVIOR;
+ } else if (service && wired && !behavior && !publish) {
+ result = RELAY;
+ } else if (behavior && !wired && !publish) {
+ result = SAP; // isService won't be checked here => Cf. bug 477033
+ }
+
+ return result;
+ }
+
+ /**
* Returns the literal value of the enumerator, which is its string representation.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsuleImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsuleImpl.java
index 9146b1667..aa0a85af4 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsuleImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsuleImpl.java
@@ -20,10 +20,12 @@ import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Capsule;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart;
@@ -107,15 +109,24 @@ public class UMLRTCapsuleImpl extends UMLRTClassifierImpl implements UMLRTCapsul
ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR,
UMLPackage.Literals.CONNECTOR);
- protected static class CapsuleAdapter<F extends UMLRTCapsuleImpl> extends Reactor<F> {
+ protected static class CapsuleAdapter<F extends UMLRTCapsuleImpl> extends ClassifierAdapter<F> {
CapsuleAdapter(F facade) {
super(facade);
}
@Override
+ protected void notifyGeneral(F owner, FacadeObject oldObject, FacadeObject newObject) {
+ // Notify the subset before the superset
+ if (owner.eNotificationRequired()) {
+ owner.eNotify(new ENotificationImpl(owner, Notification.SET, UMLRTUMLRTPackage.Literals.CAPSULE__SUPERCLASS, oldObject, newObject));
+ }
+ super.notifyGeneral(owner, oldObject, newObject);
+ }
+
+ @Override
protected List<? extends FacadeObject> getFacadeList(EObject owner, EReference reference, EObject object) {
- List<? extends FacadeObject> result = null;
+ List<? extends FacadeObject> result;
if ((reference == UMLPackage.Literals.STRUCTURED_CLASSIFIER__OWNED_ATTRIBUTE)
|| (reference == ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_ATTRIBUTE)) {
@@ -129,6 +140,8 @@ public class UMLRTCapsuleImpl extends UMLRTClassifierImpl implements UMLRTCapsul
|| (reference == ExtUMLExtPackage.Literals.ENCAPSULATED_CLASSIFIER__IMPLICIT_PORT)) {
result = get().ports;
+ } else {
+ result = super.getFacadeList(owner, reference, object);
}
return result;
@@ -153,7 +166,10 @@ public class UMLRTCapsuleImpl extends UMLRTClassifierImpl implements UMLRTCapsul
|| (reference == ExtUMLExtPackage.Literals.STRUCTURED_CLASSIFIER__IMPLICIT_CONNECTOR)) {
result = get().connectors;
}
+ } else {
+ result = super.validateObject(owner, reference, object);
}
+
return result;
}
}
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsulePartImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsulePartImpl.java
index 6ea25647f..c4155f994 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsulePartImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTCapsulePartImpl.java
@@ -21,12 +21,15 @@ import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;
+import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage;
+import org.eclipse.papyrusrt.umlrt.uml.FacadeObject;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePartKind;
@@ -100,6 +103,81 @@ public class UMLRTCapsulePartImpl extends UMLRTReplicatedElementImpl implements
*/
protected static final boolean OPTIONAL_EDEFAULT = false;
+ protected static class CapsulePartAdapter<F extends UMLRTCapsulePartImpl> extends ReplicationAdapter<F> {
+ CapsulePartAdapter(F facade) {
+ super(facade);
+ }
+
+ @Override
+ protected void handleObjectReplaced(Notification msg, int position, FacadeObject oldObject, FacadeObject newObject) {
+ if (msg.getFeature() == UMLPackage.Literals.TYPED_ELEMENT__TYPE) {
+ if (get().eNotificationRequired()) {
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.CAPSULE_PART__TYPE, oldObject, newObject));
+ }
+ } else {
+ super.handleObjectReplaced(msg, position, oldObject, newObject);
+ }
+ }
+
+ @Override
+ protected void handleLowerBoundChanged(Object oldValue, Object newValue) {
+ super.handleLowerBoundChanged(oldValue, newValue);
+
+ int oldInt = asIntegerBound(oldValue);
+ int newInt = asIntegerBound(newValue);
+
+ if ((oldInt != newInt) && get().eNotificationRequired()) {
+ UMLRTCapsulePartImpl part = get();
+ Property uml = part.toUML();
+
+ if (uml.getAggregation() == AggregationKind.COMPOSITE_LITERAL) {
+ part.eNotify(new ENotificationImpl(part, Notification.SET, UMLRTUMLRTPackage.Literals.CAPSULE_PART__OPTIONAL,
+ oldInt == 0, newInt == 0));
+ }
+
+ // Infer what the kind previously was
+ UMLRTCapsulePartKind kind = part.getKind();
+ part.eNotify(new ENotificationImpl(part, Notification.SET, UMLRTUMLRTPackage.Literals.CAPSULE_PART__KIND,
+ UMLRTCapsulePartKind.get(oldInt, uml.getUpper(), uml.getAggregation()), kind));
+ }
+ }
+
+ @Override
+ protected void handleUpperBoundChanged(Object oldValue, Object newValue) {
+ super.handleUpperBoundChanged(oldValue, newValue);
+
+ int oldInt = asIntegerBound(oldValue);
+ int newInt = asIntegerBound(newValue);
+
+ if ((oldInt != newInt) && get().eNotificationRequired()) {
+ UMLRTCapsulePartImpl part = get();
+ Property uml = part.toUML();
+
+ // Infer what the kind previously was
+ UMLRTCapsulePartKind kind = part.getKind();
+ part.eNotify(new ENotificationImpl(part, Notification.SET, UMLRTUMLRTPackage.Literals.CAPSULE_PART__KIND,
+ UMLRTCapsulePartKind.get(uml.getLower(), oldInt, uml.getAggregation()), kind));
+ }
+ }
+
+ @Override
+ protected void handleValueReplaced(Notification msg, int position, Object oldValue, Object newValue) {
+ if (msg.getFeature() == UMLPackage.Literals.PROPERTY__AGGREGATION) {
+ if (get().eNotificationRequired()) {
+ UMLRTCapsulePartImpl part = get();
+ Property uml = part.toUML();
+
+ // Infer what the kind previously was
+ UMLRTCapsulePartKind kind = part.getKind();
+ part.eNotify(new ENotificationImpl(part, Notification.SET, UMLRTUMLRTPackage.Literals.CAPSULE_PART__KIND,
+ UMLRTCapsulePartKind.get(uml.getLower(), uml.getUpper(), (AggregationKind) oldValue), kind));
+ }
+ } else {
+ super.handleValueReplaced(msg, position, oldValue, newValue);
+ }
+ }
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -133,6 +211,11 @@ public class UMLRTCapsulePartImpl extends UMLRTReplicatedElementImpl implements
return UMLRTUMLRTPackage.Literals.CAPSULE_PART;
}
+ @Override
+ protected BasicFacadeAdapter<? extends UMLRTCapsulePartImpl> createFacadeAdapter() {
+ return new CapsulePartAdapter<>(this);
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -171,20 +254,8 @@ public class UMLRTCapsulePartImpl extends UMLRTReplicatedElementImpl implements
*/
@Override
public UMLRTCapsulePartKind getKind() {
- UMLRTCapsulePartKind result = UMLRTCapsulePartKind.NULL;
Property uml = toUML();
-
- if ((uml.getLower()) > 0 && (uml.getUpper() > 0)) {
- result = UMLRTCapsulePartKind.FIXED;
- } else if ((uml.getLower() == 0) || (uml.getUpper() == LiteralUnlimitedNatural.UNLIMITED)) {
- if (uml.getAggregation() == AggregationKind.COMPOSITE_LITERAL) {
- result = UMLRTCapsulePartKind.OPTIONAL;
- } else if (uml.getAggregation() == AggregationKind.SHARED_LITERAL) {
- result = UMLRTCapsulePartKind.PLUG_IN;
- }
- }
-
- return result;
+ return UMLRTCapsulePartKind.get(uml.getLower(), uml.getUpper(), uml.getAggregation());
}
/**
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTClassifierImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTClassifierImpl.java
index ee40016fd..48ef65fa4 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTClassifierImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTClassifierImpl.java
@@ -18,11 +18,18 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.BasicEList.UnmodifiableEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.papyrusrt.umlrt.uml.FacadeObject;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTClassifier;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTFactory;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage;
import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
import org.eclipse.uml2.common.util.CacheAdapter;
@@ -30,6 +37,7 @@ import org.eclipse.uml2.common.util.DerivedUnionEObjectEList;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Generalization;
+import org.eclipse.uml2.uml.UMLPackage;
/**
* <!-- begin-user-doc -->
@@ -46,6 +54,91 @@ import org.eclipse.uml2.uml.Generalization;
* @generated
*/
public abstract class UMLRTClassifierImpl extends UMLRTNamedElementImpl implements UMLRTClassifier {
+
+ protected static class ClassifierAdapter<F extends UMLRTClassifierImpl> extends NamedElementAdapter<F> {
+
+ ClassifierAdapter(F facade) {
+ super(facade);
+ }
+
+ @Override
+ public void setTarget(Notifier newTarget) {
+ super.setTarget(newTarget);
+
+ if (newTarget instanceof Classifier) {
+ Classifier classifier = (Classifier) newTarget;
+ List<Generalization> generalizations = classifier.getGeneralizations();
+ if (!generalizations.isEmpty()) {
+ // UML-RT supports single inheritance only
+ addAdapter(generalizations.get(0));
+ }
+ }
+ }
+
+ @Override
+ public void unsetTarget(Notifier oldTarget) {
+ if (oldTarget instanceof Classifier) {
+ Classifier classifier = (Classifier) oldTarget;
+ List<Generalization> generalizations = classifier.getGeneralizations();
+ if (!generalizations.isEmpty()) {
+ generalizations.forEach(this::removeAdapter);
+ }
+ }
+
+ super.unsetTarget(oldTarget);
+ }
+
+ @Override
+ protected void handleObjectAdded(Notification msg, int position, EObject object) {
+ if (msg.getFeature() == UMLPackage.Literals.CLASSIFIER__GENERALIZATION) {
+ if (get().toUML().getGeneralizations().indexOf(object) == 0) {
+ // UML-RT only supports single generalization
+ addAdapter(object);
+ }
+ } else {
+ super.handleObjectAdded(msg, position, object);
+ }
+ }
+
+ @Override
+ protected void handleObjectRemoved(Notification msg, int position, EObject object) {
+ if (msg.getFeature() == UMLPackage.Literals.CLASSIFIER__GENERALIZATION) {
+ removeAdapter(object);
+ } else {
+ super.handleObjectRemoved(msg, position, object);
+ }
+ }
+
+ @Override
+ protected FacadeObject getFacade(EObject umlOwner, EReference umlReference, EObject object) {
+ if (object instanceof Generalization) {
+ Classifier general = ((Generalization) object).getGeneral();
+ return (general == null) ? null : UMLRTFactory.create(general);
+ } else {
+ return super.getFacade(umlOwner, umlReference, object);
+ }
+ }
+
+ @Override
+ protected void handleObjectReplaced(Notification msg, int position, FacadeObject oldObject, FacadeObject newObject) {
+ if (msg.getFeature() == UMLPackage.Literals.CLASSIFIER__GENERALIZATION) {
+ if (position == 0) {
+ notifyGeneral(get(), oldObject, newObject);
+ }
+ } else if (msg.getFeature() == UMLPackage.Literals.GENERALIZATION__GENERAL) {
+ notifyGeneral(get(), oldObject, newObject);
+ } else {
+ super.handleObjectReplaced(msg, position, oldObject, newObject);
+ }
+ }
+
+ protected void notifyGeneral(F owner, FacadeObject oldObject, FacadeObject newObject) {
+ if (owner.eNotificationRequired()) {
+ owner.eNotify(new ENotificationImpl(owner, Notification.SET, UMLRTUMLRTPackage.Literals.CLASSIFIER__GENERAL, oldObject, newObject));
+ }
+ }
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -67,6 +160,11 @@ public abstract class UMLRTClassifierImpl extends UMLRTNamedElementImpl implemen
return UMLRTUMLRTPackage.Literals.CLASSIFIER;
}
+ @Override
+ protected BasicFacadeAdapter<? extends UMLRTClassifierImpl> createFacadeAdapter() {
+ return new ClassifierAdapter<>(this);
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTConnectorImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTConnectorImpl.java
index a532ad897..80634ebb9 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTConnectorImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTConnectorImpl.java
@@ -12,10 +12,19 @@
*/
package org.eclipse.papyrusrt.umlrt.uml.internal.facade.impl;
+import static org.eclipse.papyrusrt.umlrt.uml.internal.facade.impl.UMLRTReplicatedElementImpl.ReplicationAdapter.asIntegerBound;
+import static org.eclipse.papyrusrt.umlrt.uml.internal.facade.impl.UMLRTReplicatedElementImpl.ReplicationAdapter.valueOf;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTConnector;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage;
+import org.eclipse.papyrusrt.umlrt.uml.FacadeObject;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTConnector;
@@ -25,8 +34,11 @@ import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.ConnectorEnd;
+import org.eclipse.uml2.uml.MultiplicityElement;
+import org.eclipse.uml2.uml.OpaqueExpression;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.ValueSpecification;
/**
* <!-- begin-user-doc -->
@@ -80,6 +92,161 @@ public class UMLRTConnectorImpl extends UMLRTNamedElementImpl implements UMLRTCo
connector -> (UMLRTConnectorImpl) connector.getRedefinedConnector(),
UMLRTConnectorImpl::new);
+ protected static class ConnectorAdapter<F extends UMLRTConnectorImpl> extends NamedElementAdapter<F> {
+ ConnectorAdapter(F facade) {
+ super(facade);
+ }
+
+ @Override
+ public void setTarget(Notifier newTarget) {
+ super.setTarget(newTarget);
+
+ if (newTarget instanceof Connector) {
+ ((Connector) newTarget).getEnds().forEach(this::addAdapter);
+ } else if (newTarget instanceof MultiplicityElement) {
+ MultiplicityElement mult = (MultiplicityElement) newTarget;
+ if (mult.getUpperValue() != null) {
+ addAdapter(mult.getUpperValue());
+ }
+ }
+ }
+
+ @Override
+ public void unsetTarget(Notifier oldTarget) {
+ if (oldTarget instanceof Connector) {
+ ((Connector) oldTarget).getEnds().forEach(this::removeAdapter);
+ } else if (oldTarget instanceof MultiplicityElement) {
+ MultiplicityElement mult = (MultiplicityElement) oldTarget;
+ if (mult.getUpperValue() != null) {
+ removeAdapter(mult.getUpperValue());
+ }
+ }
+
+ super.setTarget(oldTarget);
+ }
+
+ @Override
+ protected void handleObjectAdded(Notification msg, int position, EObject object) {
+ if (msg.getFeature() == UMLPackage.Literals.CONNECTOR__END) {
+ addAdapter(object);
+ }
+
+ super.handleObjectAdded(msg, position, object);
+ }
+
+ @Override
+ protected void handleObjectRemoved(Notification msg, int position, EObject object) {
+ super.handleObjectRemoved(msg, position, object);
+
+ if (msg.getFeature() == UMLPackage.Literals.CONNECTOR__END) {
+ removeAdapter(object);
+ }
+ }
+
+ @Override
+ protected void handleObjectReplaced(Notification msg, int position, EObject oldObject, EObject newObject) {
+ if (msg.getFeature() == UMLPackage.Literals.CONNECTOR__END) {
+ removeAdapter(oldObject);
+ addAdapter(newObject);
+ } else if (msg.getFeature() == UMLPackage.Literals.MULTIPLICITY_ELEMENT__UPPER_VALUE) {
+ if (oldObject != null) {
+ removeAdapter(oldObject);
+ }
+ if (newObject != null) {
+ addAdapter(newObject);
+ }
+
+ boolean isSource = msg.getNotifier() == get().umlEnd(0);
+ handleUpperBoundChanged(isSource, asIntegerBound(valueOf((ValueSpecification) oldObject)),
+ asIntegerBound(valueOf((ValueSpecification) newObject)));
+ } else {
+ super.handleObjectReplaced(msg, position, oldObject, newObject);
+ }
+ }
+
+ @Override
+ protected void handleObjectReplaced(Notification msg, int position, FacadeObject oldObject, FacadeObject newObject) {
+ if (msg.getFeature() == UMLPackage.Literals.CONNECTOR_END__ROLE) {
+ if (get().eNotificationRequired()) {
+ boolean isSource = msg.getNotifier() == get().umlEnd(0);
+ EStructuralFeature feature = isSource
+ ? UMLRTUMLRTPackage.Literals.CONNECTOR__SOURCE
+ : UMLRTUMLRTPackage.Literals.CONNECTOR__TARGET;
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), feature, oldObject, newObject));
+ }
+ } else if (msg.getFeature() == UMLPackage.Literals.CONNECTOR_END__PART_WITH_PORT) {
+ if (get().eNotificationRequired()) {
+ boolean isSource = msg.getNotifier() == get().umlEnd(0);
+ EStructuralFeature feature = isSource
+ ? UMLRTUMLRTPackage.Literals.CONNECTOR__SOURCE_PART_WITH_PORT
+ : UMLRTUMLRTPackage.Literals.CONNECTOR__TARGET_PART_WITH_PORT;
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), feature, oldObject, newObject));
+ }
+ } else {
+ super.handleObjectReplaced(msg, position, oldObject, newObject);
+ }
+ }
+
+ @Override
+ protected void handleValueReplaced(Notification msg, int position, Object oldValue, Object newValue) {
+ if ((msg.getFeature() == UMLPackage.Literals.LITERAL_INTEGER__VALUE)
+ || (msg.getFeature() == UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE)
+ || (msg.getFeature() == UMLPackage.Literals.LITERAL_STRING__VALUE)
+ || ((msg.getFeature() == UMLPackage.Literals.OPAQUE_EXPRESSION__BODY)
+ && (position == 0))) {
+
+ ValueSpecification bound = (ValueSpecification) msg.getNotifier();
+ MultiplicityElement mult = (MultiplicityElement) bound.getOwner();
+ boolean isSource = mult == get().umlEnd(0);
+
+ handleUpperBoundChanged(isSource, asIntegerBound(oldValue), asIntegerBound(newValue));
+ } else {
+ super.handleValueReplaced(msg, position, oldValue, newValue);
+ }
+ }
+
+ @Override
+ protected void handleValueAdded(Notification msg, int position, Object value) {
+ if ((msg.getFeature() == UMLPackage.Literals.OPAQUE_EXPRESSION__BODY)
+ && (position == 0)) {
+
+ ValueSpecification bound = (ValueSpecification) msg.getNotifier();
+ MultiplicityElement mult = (MultiplicityElement) bound.getOwner();
+ boolean isSource = mult == get().umlEnd(0);
+
+ handleUpperBoundChanged(isSource, 1, asIntegerBound(value));
+ } else {
+ super.handleValueAdded(msg, position, value);
+ }
+ }
+
+ @Override
+ protected void handleValueRemoved(Notification msg, int position, Object value) {
+ if ((msg.getFeature() == UMLPackage.Literals.OPAQUE_EXPRESSION__BODY)
+ && ((OpaqueExpression) msg.getNotifier()).getBodies().isEmpty()) {
+
+ ValueSpecification bound = (ValueSpecification) msg.getNotifier();
+ MultiplicityElement mult = (MultiplicityElement) bound.getOwner();
+ boolean isSource = mult == get().umlEnd(0);
+
+ handleUpperBoundChanged(isSource, asIntegerBound(value), mult.getUpper());
+ } else {
+ super.handleValueRemoved(msg, position, value);
+ }
+ }
+
+ protected void handleUpperBoundChanged(boolean isSource, int oldValue, int newValue) {
+ if (get().eNotificationRequired()) {
+ EStructuralFeature feature = isSource
+ ? UMLRTUMLRTPackage.Literals.CONNECTOR__SOURCE_REPLICATION_FACTOR
+ : UMLRTUMLRTPackage.Literals.CONNECTOR__TARGET_REPLICATION_FACTOR;
+
+ get().eNotify(new ENotificationImpl(get(), Notification.SET, feature,
+ oldValue, newValue));
+ }
+ }
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -113,6 +280,11 @@ public class UMLRTConnectorImpl extends UMLRTNamedElementImpl implements UMLRTCo
return UMLRTUMLRTPackage.Literals.CONNECTOR;
}
+ @Override
+ protected BasicFacadeAdapter<? extends UMLRTConnectorImpl> createFacadeAdapter() {
+ return new ConnectorAdapter<>(this);
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTNamedElementImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTNamedElementImpl.java
index c74977f6f..9c1caba18 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTNamedElementImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTNamedElementImpl.java
@@ -20,9 +20,11 @@ import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTFactory;
@@ -37,6 +39,7 @@ import org.eclipse.uml2.common.util.DerivedUnionEObjectEList;
import org.eclipse.uml2.common.util.UML2Util;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Namespace;
+import org.eclipse.uml2.uml.UMLPackage;
/**
* <!-- begin-user-doc -->
@@ -151,6 +154,25 @@ public abstract class UMLRTNamedElementImpl extends FacadeObjectImpl implements
*/
protected static final boolean IS_EXCLUDED_EDEFAULT = false;
+
+ protected static class NamedElementAdapter<F extends UMLRTNamedElementImpl> extends Reactor<F> {
+
+ NamedElementAdapter(F facade) {
+ super(facade);
+ }
+
+ @Override
+ protected void handleValueReplaced(Notification msg, int position, Object oldValue, Object newValue) {
+ if (msg.getFeature() == UMLPackage.Literals.NAMED_ELEMENT__NAME) {
+ if (get().eNotificationRequired()) {
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.NAMED_ELEMENT__NAME, oldValue, newValue));
+ }
+ } else {
+ super.handleValueReplaced(msg, position, oldValue, newValue);
+ }
+ }
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -172,6 +194,11 @@ public abstract class UMLRTNamedElementImpl extends FacadeObjectImpl implements
return UMLRTUMLRTPackage.Literals.NAMED_ELEMENT;
}
+ @Override
+ protected BasicFacadeAdapter<? extends UMLRTNamedElementImpl> createFacadeAdapter() {
+ return new NamedElementAdapter<>(this);
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPackageImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPackageImpl.java
index 46c0215af..9ffcc1332 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPackageImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPackageImpl.java
@@ -20,17 +20,25 @@ import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Capsule;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.ProtocolContainer;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage;
+import org.eclipse.papyrusrt.umlrt.uml.FacadeObject;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol;
import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Collaboration;
+import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.UMLPackage;
@@ -79,6 +87,118 @@ public class UMLRTPackageImpl extends UMLRTNamedElementImpl implements UMLRTPack
null,
UMLPackage.Literals.PACKAGE);
+ protected static class PackageAdapter<F extends UMLRTPackageImpl> extends NamedElementAdapter<F> {
+
+ // Cannot attach ourselves to protocol-containers because otherwise they
+ // will be mistaken for our own package façade via getFacadeAdapter(...)
+ private final Nested protocolContainerAdapter = new Nested();
+
+ PackageAdapter(F facade) {
+ super(facade);
+ }
+
+ @Override
+ public void setTarget(Notifier newTarget) {
+ super.setTarget(newTarget);
+
+ if ((newTarget instanceof Package) && !isProtocolContainer((Package) newTarget)) {
+ // Look for protocol-containers
+ ((Package) newTarget).getNestedPackages().stream()
+ .filter(UMLRTPackageImpl::isProtocolContainer)
+ .forEach(protocolContainerAdapter::addAdapter);
+ }
+ }
+
+ @Override
+ public void unsetTarget(Notifier oldTarget) {
+ if (oldTarget instanceof Package) {
+ ((Package) oldTarget).getNestedPackages().forEach(protocolContainerAdapter::removeAdapter);
+ }
+
+ super.unsetTarget(oldTarget);
+ }
+
+ @Override
+ protected List<? extends FacadeObject> getFacadeList(EObject owner, EReference reference, EObject object) {
+ List<? extends FacadeObject> result;
+
+ if (reference == UMLPackage.Literals.PACKAGE__PACKAGED_ELEMENT) {
+ result = (object instanceof Package)
+ ? get().nestedPackages
+ : (object instanceof Class)
+ ? get().capsules
+ : (object instanceof Collaboration)
+ ? get().protocols
+ : null;
+ } else {
+ result = super.getFacadeList(owner, reference, object);
+ }
+
+ return result;
+ }
+
+ @Override
+ protected InternalFacadeEList<? extends FacadeObject> validateObject(EObject owner, EReference reference, FacadeObject object) {
+ InternalFacadeEList<? extends FacadeObject> result = null;
+
+ if (object instanceof UMLRTPackage) {
+ if (reference == UMLPackage.Literals.PACKAGE__PACKAGED_ELEMENT) {
+ result = get().nestedPackages;
+ }
+ } else if (object instanceof UMLRTCapsule) {
+ if (reference == UMLPackage.Literals.PACKAGE__PACKAGED_ELEMENT) {
+ result = get().capsules;
+ }
+ } else if (object instanceof UMLRTProtocol) {
+ if (reference == UMLPackage.Literals.PACKAGE__PACKAGED_ELEMENT) {
+ result = get().protocols;
+ }
+ } else {
+ result = super.validateObject(owner, reference, object);
+ }
+
+ return result;
+ }
+
+ @Override
+ public void tickle(NamedElement element) {
+ if (element instanceof Package) {
+ if (isProtocolContainer((org.eclipse.uml2.uml.Package) element)) {
+ addAdapter(element);
+ }
+ } else {
+ super.tickle(element);
+ }
+ }
+
+ //
+ // Nested types
+ //
+
+ private final class Nested extends AdapterImpl {
+ void addAdapter(Notifier notifier) {
+ EList<Adapter> adapters = notifier.eAdapters();
+ if (!adapters.contains(this)) {
+ adapters.add(this);
+ }
+ }
+
+ void removeAdapter(Notifier notifier) {
+ notifier.eAdapters().remove(this);
+ }
+
+ @Override
+ public void notifyChanged(Notification msg) {
+ // Forward to the real package adapter
+ PackageAdapter.this.notifyChanged(msg);
+ }
+ }
+ }
+
+ InternalFacadeEList<UMLRTPackage> nestedPackages;
+ InternalFacadeEList<UMLRTCapsule> capsules;
+ InternalFacadeEList<UMLRTProtocol> protocols;
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -138,6 +258,11 @@ public class UMLRTPackageImpl extends UMLRTNamedElementImpl implements UMLRTPack
return UMLRTUMLRTPackage.Literals.PACKAGE;
}
+ @Override
+ protected BasicFacadeAdapter<? extends UMLRTPackageImpl> createFacadeAdapter() {
+ return new PackageAdapter<>(this);
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -146,7 +271,10 @@ public class UMLRTPackageImpl extends UMLRTNamedElementImpl implements UMLRTPack
*/
@Override
public List<UMLRTPackage> getNestedPackages() {
- return getFacades(NESTED_PACKAGE_REFERENCE);
+ if (nestedPackages == null) {
+ nestedPackages = (InternalFacadeEList<UMLRTPackage>) getFacades(NESTED_PACKAGE_REFERENCE);
+ }
+ return nestedPackages;
}
/**
@@ -197,7 +325,10 @@ public class UMLRTPackageImpl extends UMLRTNamedElementImpl implements UMLRTPack
*/
@Override
public List<UMLRTCapsule> getCapsules() {
- return getFacades(CAPSULE_REFERENCE);
+ if (capsules == null) {
+ capsules = (InternalFacadeEList<UMLRTCapsule>) getFacades(CAPSULE_REFERENCE);
+ }
+ return capsules;
}
/**
@@ -236,12 +367,16 @@ public class UMLRTPackageImpl extends UMLRTNamedElementImpl implements UMLRTPack
*/
@Override
public List<UMLRTProtocol> getProtocols() {
- return toUML().getNestedPackages().stream()
- .filter(UMLRTPackageImpl::isProtocolContainer)
- .map(UMLRTPackageImpl::getProtocol)
- .map(UMLRTProtocol::getInstance)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
+ if (protocols == null) {
+ List<UMLRTProtocol> protocols_ = toUML().getNestedPackages().stream()
+ .filter(UMLRTPackageImpl::isProtocolContainer)
+ .map(UMLRTPackageImpl::getProtocol)
+ .map(UMLRTProtocol::getInstance)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ protocols = new FacadeObjectEList<>(this, UMLRTProtocol.class, UMLRTUMLRTPackage.PACKAGE__PROTOCOL, protocols_);
+ }
+ return protocols;
}
/**
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPortImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPortImpl.java
index 2ac4a498a..d38bdd7ad 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPortImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTPortImpl.java
@@ -22,12 +22,18 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.PortRegistrationType;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage;
+import org.eclipse.papyrusrt.umlrt.uml.FacadeObject;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTConnector;
@@ -48,6 +54,7 @@ import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.VisibilityKind;
+import org.eclipse.uml2.uml.util.UMLUtil;
/**
* <!-- begin-user-doc -->
@@ -223,6 +230,133 @@ public class UMLRTPortImpl extends UMLRTReplicatedElementImpl implements UMLRTPo
*/
protected static final boolean IS_CONNECTED_OUTSIDE_EDEFAULT = false;
+ protected static class PortAdapter<F extends UMLRTPortImpl> extends ReplicationAdapter<F> {
+ PortAdapter(F facade) {
+ super(facade);
+ }
+
+ @Override
+ public void setTarget(Notifier newTarget) {
+ super.setTarget(newTarget);
+
+ if (newTarget instanceof Port) {
+ RTPort stereotype = UMLUtil.getStereotypeApplication((Port) newTarget, RTPort.class);
+ if (stereotype != null) {
+ addAdapter(stereotype);
+ }
+ }
+ }
+
+ @Override
+ public void unsetTarget(Notifier newTarget) {
+ if (newTarget instanceof Port) {
+ RTPort stereotype = UMLUtil.getStereotypeApplication((Port) newTarget, RTPort.class);
+ if (stereotype != null) {
+ removeAdapter(stereotype);
+ }
+ }
+
+ super.setTarget(newTarget);
+ }
+
+ @Override
+ protected FacadeObject getFacade(EObject owner, EReference reference, EObject object) {
+ FacadeObject result = super.getFacade(owner, reference, object);
+
+ if ((result instanceof UMLRTProtocol) && get().isConjugated()) {
+ result = ((UMLRTProtocol) result).getConjugate();
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void handleObjectReplaced(Notification msg, int position, FacadeObject oldObject, FacadeObject newObject) {
+ if (msg.getFeature() == UMLPackage.Literals.TYPED_ELEMENT__TYPE) {
+ if (get().eNotificationRequired()) {
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__TYPE, oldObject, newObject));
+ }
+ } else {
+ super.handleObjectReplaced(msg, position, oldObject, newObject);
+ }
+ }
+
+ @Override
+ protected void handleValueReplaced(Notification msg, int position, Object oldValue, Object newValue) {
+ if (msg.getFeature() == UMLPackage.Literals.PORT__IS_CONJUGATED) {
+ if (get().eNotificationRequired()) {
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__CONJUGATED, oldValue, newValue));
+ UMLRTProtocol type = get().getType();
+
+ if (type != null) {
+ // It is now the conjugate of what it was
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__TYPE,
+ type.getConjugate(), type));
+ }
+ }
+ } else if (msg.getFeature() == UMLPackage.Literals.PORT__IS_SERVICE) {
+ if (get().eNotificationRequired()) {
+ UMLRTPortImpl port = get();
+ port.eNotify(new ENotificationImpl(port, msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__SERVICE, oldValue, newValue));
+
+ // Infer what the kind previously was
+ UMLRTPortKind kind = port.getKind();
+ port.eNotify(new ENotificationImpl(port, msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__KIND,
+ UMLRTPortKind.get((boolean) oldValue, port.isBehavior(), port.isWired(), port.isPublish()),
+ kind));
+ }
+ } else if (msg.getFeature() == UMLPackage.Literals.PORT__IS_BEHAVIOR) {
+ if (get().eNotificationRequired()) {
+ UMLRTPortImpl port = get();
+ port.eNotify(new ENotificationImpl(port, msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__BEHAVIOR, oldValue, newValue));
+
+ // Infer what the kind previously was
+ UMLRTPortKind kind = port.getKind();
+ port.eNotify(new ENotificationImpl(port, msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__KIND,
+ UMLRTPortKind.get(port.isService(), (boolean) oldValue, port.isWired(), port.isPublish()),
+ kind));
+ }
+ } else if (msg.getFeature() == UMLRealTimePackage.Literals.RT_PORT__IS_WIRED) {
+ if (get().eNotificationRequired()) {
+ UMLRTPortImpl port = get();
+ port.eNotify(new ENotificationImpl(port, msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__WIRED, oldValue, newValue));
+
+ // Infer what the kind previously was
+ UMLRTPortKind kind = port.getKind();
+ port.eNotify(new ENotificationImpl(port, msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__KIND,
+ UMLRTPortKind.get(port.isService(), port.isBehavior(), (boolean) oldValue, port.isPublish()),
+ kind));
+ }
+ } else if (msg.getFeature() == UMLRealTimePackage.Literals.RT_PORT__IS_PUBLISH) {
+ if (get().eNotificationRequired()) {
+ UMLRTPortImpl port = get();
+ port.eNotify(new ENotificationImpl(port, msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__PUBLISH, oldValue, newValue));
+
+ // Infer what the kind previously was
+ UMLRTPortKind kind = port.getKind();
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__KIND,
+ UMLRTPortKind.get(port.isService(), port.isBehavior(), port.isWired(), (boolean) oldValue),
+ kind));
+ }
+ } else if (msg.getFeature() == UMLRealTimePackage.Literals.RT_PORT__IS_NOTIFICATION) {
+ if (get().eNotificationRequired()) {
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__NOTIFICATION, oldValue, newValue));
+ }
+ } else if (msg.getFeature() == UMLRealTimePackage.Literals.RT_PORT__REGISTRATION) {
+ if (get().eNotificationRequired()) {
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__REGISTRATION, oldValue, newValue));
+ }
+ } else if (msg.getFeature() == UMLRealTimePackage.Literals.RT_PORT__REGISTRATION_OVERRIDE) {
+ if (get().eNotificationRequired()) {
+ get().eNotify(new ENotificationImpl(get(), msg.getEventType(), UMLRTUMLRTPackage.Literals.PORT__REGISTRATION_OVERRIDE, oldValue, newValue));
+ }
+ } else {
+ super.handleValueReplaced(msg, position, oldValue, newValue);
+ }
+ }
+
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -256,6 +390,11 @@ public class UMLRTPortImpl extends UMLRTReplicatedElementImpl implements UMLRTPo
return UMLRTUMLRTPackage.Literals.PORT;
}
+ @Override
+ protected BasicFacadeAdapter<? extends UMLRTPortImpl> createFacadeAdapter() {
+ return new PortAdapter<>(this);
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -379,21 +518,7 @@ public class UMLRTPortImpl extends UMLRTReplicatedElementImpl implements UMLRTPo
*/
@Override
public UMLRTPortKind getKind() {
- UMLRTPortKind result = UMLRTPortKind.NULL;
-
- if (isService() && isWired() && isBehavior() && !isPublish()) {
- result = UMLRTPortKind.EXTERNAL_BEHAVIOR;
- } else if (isBehavior() && isPublish() && !isWired()) {
- result = UMLRTPortKind.SPP; // isService won't be checked here => Cf. bug 477033
- } else if (isWired() && isBehavior() && !isService() && !isPublish()) {
- result = UMLRTPortKind.INTERNAL_BEHAVIOR;
- } else if (isService() && isWired() && !isBehavior() && !isPublish()) {
- result = UMLRTPortKind.RELAY;
- } else if (isBehavior() && !isWired() && !isPublish()) {
- result = UMLRTPortKind.SAP;// isService won't be checked here => Cf. bug 477033
- }
-
- return result;
+ return UMLRTPortKind.get(isService(), isBehavior(), isWired(), isPublish());
}
/**
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolImpl.java
index f3c43b920..ac3098941 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolImpl.java
@@ -32,6 +32,7 @@ import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Protocol;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind;
@@ -117,6 +118,7 @@ public class UMLRTProtocolImpl extends UMLRTClassifierImpl implements UMLRTProto
private final Supplier<UMLRTProtocol> conjugate;
static {
+
EnumMap<RTMessageKind, Integer> references = new EnumMap<>(RTMessageKind.class);
references.put(RTMessageKind.IN, UMLRTUMLRTPackage.PROTOCOL__IN_MESSAGE);
references.put(RTMessageKind.IN_OUT, UMLRTUMLRTPackage.PROTOCOL__IN_OUT_MESSAGE);
@@ -134,7 +136,7 @@ public class UMLRTProtocolImpl extends UMLRTClassifierImpl implements UMLRTProto
protocol -> requireMessageSet((Collaboration) protocol, kind))));
}
- protected static class ProtocolAdapter<F extends UMLRTProtocolImpl> extends Reactor<F> {
+ protected static class ProtocolAdapter<F extends UMLRTProtocolImpl> extends ClassifierAdapter<F> {
ProtocolAdapter(F facade) {
super(facade);
@@ -185,14 +187,25 @@ public class UMLRTProtocolImpl extends UMLRTClassifierImpl implements UMLRTProto
if ((result instanceof UMLRTProtocolMessage) && get().isConjugate()) {
result = ((UMLRTProtocolMessage) result).getConjugate();
+ } else if ((result instanceof UMLRTProtocol) && get().isConjugate()) {
+ result = ((UMLRTProtocol) result).getConjugate();
}
return result;
}
@Override
+ protected void notifyGeneral(F owner, FacadeObject oldObject, FacadeObject newObject) {
+ // Notify the subset before the superset
+ if (owner.eNotificationRequired()) {
+ owner.eNotify(new ENotificationImpl(owner, Notification.SET, UMLRTUMLRTPackage.Literals.PROTOCOL__SUPER_PROTOCOL, oldObject, newObject));
+ }
+ super.notifyGeneral(owner, oldObject, newObject);
+ }
+
+ @Override
protected List<? extends FacadeObject> getFacadeList(EObject owner, EReference reference, EObject object) {
- List<? extends FacadeObject> result = null;
+ List<? extends FacadeObject> result;
if ((reference == UMLPackage.Literals.INTERFACE__OWNED_OPERATION)
|| (reference == ExtUMLExtPackage.Literals.INTERFACE__IMPLICIT_OPERATION)) {
@@ -210,8 +223,15 @@ public class UMLRTProtocolImpl extends UMLRTClassifierImpl implements UMLRTProto
case IN_OUT:
result = get().inOutMessages;
break;
+ default:
+ result = null;
+ break;
}
+ } else {
+ result = null;
}
+ } else {
+ result = super.getFacadeList(owner, reference, object);
}
return result;
@@ -229,6 +249,15 @@ public class UMLRTProtocolImpl extends UMLRTClassifierImpl implements UMLRTProto
}
@Override
+ protected void handleObjectAdded(Notification msg, int position, FacadeObject object) {
+ super.handleObjectAdded(msg, position, object);
+
+ if (object instanceof UMLRTProtocolMessageImpl) {
+ ((UMLRTProtocolMessageImpl) object).kindChanged();
+ }
+ }
+
+ @Override
protected void handleObjectRemoved(Notification msg, int position, EObject object) {
if (msg.getFeature() == UMLPackage.Literals.PACKAGE__PACKAGED_ELEMENT) {
if (object instanceof Interface) {
@@ -265,6 +294,8 @@ public class UMLRTProtocolImpl extends UMLRTClassifierImpl implements UMLRTProto
break;
}
}
+ } else {
+ result = super.validateObject(owner, reference, object);
}
return result;
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolMessageImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolMessageImpl.java
index 0051f4e06..4547937f7 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolMessageImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTProtocolMessageImpl.java
@@ -20,8 +20,11 @@ import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationWrapper;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageSet;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTNamedElement;
@@ -32,6 +35,7 @@ import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement;
import org.eclipse.papyrusrt.umlrt.uml.internal.util.CachedReference;
import org.eclipse.uml2.uml.CallEvent;
import org.eclipse.uml2.uml.Collaboration;
+import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
@@ -90,8 +94,40 @@ public class UMLRTProtocolMessageImpl extends UMLRTNamedElementImpl implements U
*/
protected static final boolean IS_CONJUGATE_EDEFAULT = false;
+ protected static class MessageAdapter<F extends UMLRTProtocolMessageImpl> extends NamedElementAdapter<F> {
+ MessageAdapter(F facade) {
+ super(facade);
+ }
+
+ @Override
+ protected void handleReference(Notification msg) {
+ if (msg.getFeature() == UMLPackage.Literals.BEHAVIORAL_FEATURE__OWNED_PARAMETER) {
+ if (get().eNotificationRequired()) {
+ UMLRTProtocolMessageImpl message = get();
+
+ // We don't have façades for parameters
+ message.eNotify(new NotificationWrapper(msg) {
+ @Override
+ public Object getNotifier() {
+ return message;
+ }
+
+ @Override
+ public Object getFeature() {
+ return UMLRTUMLRTPackage.Literals.PROTOCOL_MESSAGE__PARAMETER;
+ }
+
+ });
+ }
+ } else {
+ super.handleReference(msg);
+ }
+ }
+ }
+
private final boolean isConjugate;
private final Supplier<UMLRTProtocolMessage> conjugate;
+ private RTMessageKind kind;
/**
* <!-- begin-user-doc -->
@@ -114,6 +150,16 @@ public class UMLRTProtocolMessageImpl extends UMLRTNamedElementImpl implements U
init(base.toUML(), base.toRT());
}
+ @Override
+ <F extends FacadeObjectImpl> F init(Element element, EObject stereotype) {
+ F result = super.init(element, stereotype);
+
+ // Initialize my kind
+ getKind();
+
+ return result;
+ }
+
/**
* Obtains the protocol message façade for the message represented by the given
* UML operation.
@@ -157,6 +203,11 @@ public class UMLRTProtocolMessageImpl extends UMLRTNamedElementImpl implements U
return UMLRTUMLRTPackage.Literals.PROTOCOL_MESSAGE;
}
+ @Override
+ protected BasicFacadeAdapter<? extends UMLRTProtocolMessageImpl> createFacadeAdapter() {
+ return new MessageAdapter<>(this);
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -195,7 +246,21 @@ public class UMLRTProtocolMessageImpl extends UMLRTNamedElementImpl implements U
*/
@Override
public RTMessageKind getKind() {
- return forConjugation(getMessageSet().map(RTMessageSet::getRtMsgKind).orElse(null));
+ if (kind == null) {
+ kind = forConjugation(getMessageSet().map(RTMessageSet::getRtMsgKind).orElse(null));
+ }
+
+ return kind;
+ }
+
+ void kindChanged() {
+ RTMessageKind oldKind = kind;
+ kind = null;
+ RTMessageKind newKind = getKind();
+
+ if ((oldKind != newKind) && eNotificationRequired()) {
+ eNotify(new ENotificationImpl(this, Notification.SET, UMLRTUMLRTPackage.Literals.PROTOCOL_MESSAGE__KIND, oldKind, newKind));
+ }
}
Optional<RTMessageSet> getMessageSet() {
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTReplicatedElementImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTReplicatedElementImpl.java
index d571717af..3044719e7 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTReplicatedElementImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src-facade/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/UMLRTReplicatedElementImpl.java
@@ -14,18 +14,24 @@ package org.eclipse.papyrusrt.umlrt.uml.internal.facade.impl;
import java.util.Objects;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTReplicatedElement;
import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
import org.eclipse.uml2.uml.LiteralInteger;
+import org.eclipse.uml2.uml.LiteralString;
import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
import org.eclipse.uml2.uml.MultiplicityElement;
import org.eclipse.uml2.uml.OpaqueExpression;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.ValueSpecification;
+import org.eclipse.uml2.uml.util.UMLSwitch;
/**
* <!-- begin-user-doc -->
@@ -74,6 +80,196 @@ public abstract class UMLRTReplicatedElementImpl extends UMLRTNamedElementImpl i
*/
protected static final boolean SYMBOLIC_REPLICATION_FACTOR_EDEFAULT = false;
+ protected static class ReplicationAdapter<F extends UMLRTReplicatedElementImpl> extends NamedElementAdapter<F> {
+ ReplicationAdapter(F facade) {
+ super(facade);
+ }
+
+ @Override
+ public void setTarget(Notifier newTarget) {
+ super.setTarget(newTarget);
+
+ if (newTarget instanceof MultiplicityElement) {
+ MultiplicityElement mult = (MultiplicityElement) newTarget;
+ if (mult.getLowerValue() != null) {
+ addAdapter(mult.getLowerValue());
+ }
+ if (mult.getUpperValue() != null) {
+ addAdapter(mult.getUpperValue());
+ }
+ }
+ }
+
+ @Override
+ public void unsetTarget(Notifier oldTarget) {
+ if (oldTarget instanceof MultiplicityElement) {
+ MultiplicityElement mult = (MultiplicityElement) oldTarget;
+ if (mult.getLowerValue() != null) {
+ removeAdapter(mult.getLowerValue());
+ }
+ if (mult.getUpperValue() != null) {
+ removeAdapter(mult.getUpperValue());
+ }
+ }
+
+ super.setTarget(oldTarget);
+ }
+
+ @Override
+ protected void handleObjectReplaced(Notification msg, int position, EObject oldObject, EObject newObject) {
+ if (msg.getFeature() == UMLPackage.Literals.MULTIPLICITY_ELEMENT__LOWER_VALUE) {
+ if (oldObject != null) {
+ removeAdapter(oldObject);
+ }
+ if (newObject != null) {
+ addAdapter(newObject);
+ }
+ handleLowerBoundChanged(valueOf((ValueSpecification) oldObject), valueOf((ValueSpecification) newObject));
+ } else if (msg.getFeature() == UMLPackage.Literals.MULTIPLICITY_ELEMENT__UPPER_VALUE) {
+ if (oldObject != null) {
+ removeAdapter(oldObject);
+ }
+ if (newObject != null) {
+ addAdapter(newObject);
+ }
+ handleUpperBoundChanged(valueOf((ValueSpecification) oldObject), valueOf((ValueSpecification) newObject));
+ } else {
+ super.handleObjectReplaced(msg, position, oldObject, newObject);
+ }
+ }
+
+ protected static Object valueOf(ValueSpecification valueSpecification) {
+ return (valueSpecification == null)
+ ? 1 // The default derivation of the bound when there is no value specified
+ : new UMLSwitch<Object>() {
+ @Override
+ public Object caseLiteralInteger(LiteralInteger object) {
+ return object.getValue();
+ }
+
+ @Override
+ public Object caseLiteralUnlimitedNatural(LiteralUnlimitedNatural object) {
+ return object.getValue();
+ }
+
+ @Override
+ public Object caseLiteralString(LiteralString object) {
+ return object.getValue();
+ }
+
+ @Override
+ public Object caseOpaqueExpression(OpaqueExpression object) {
+ return object.getBodies().isEmpty() ? null : object.getBodies().get(0);
+ }
+
+ @Override
+ public Object caseValueSpecification(ValueSpecification object) {
+ return object.stringValue();
+ }
+ }.doSwitch(valueSpecification);
+ }
+
+ protected static int asIntegerBound(Object bound) {
+ int result = 1;
+
+ if (bound instanceof Integer) {
+ result = (Integer) bound;
+ } else if (bound instanceof String) {
+ try {
+ result = Integer.parseInt((String) bound);
+ } catch (Exception e) {
+ // Pass
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ protected void handleValueReplaced(Notification msg, int position, Object oldValue, Object newValue) {
+ if ((msg.getFeature() == UMLPackage.Literals.LITERAL_INTEGER__VALUE)
+ || (msg.getFeature() == UMLPackage.Literals.LITERAL_UNLIMITED_NATURAL__VALUE)
+ || (msg.getFeature() == UMLPackage.Literals.LITERAL_STRING__VALUE)
+ || ((msg.getFeature() == UMLPackage.Literals.OPAQUE_EXPRESSION__BODY)
+ && (position == 0))) {
+
+ MultiplicityElement mult = get().toUML();
+ ValueSpecification bound = (ValueSpecification) msg.getNotifier();
+
+ if (bound == mult.getLowerValue()) {
+ handleLowerBoundChanged(oldValue, newValue);
+ } else {
+ handleUpperBoundChanged(oldValue, newValue);
+ }
+ } else {
+ super.handleValueReplaced(msg, position, oldValue, newValue);
+ }
+ }
+
+ @Override
+ protected void handleValueAdded(Notification msg, int position, Object value) {
+ if ((msg.getFeature() == UMLPackage.Literals.OPAQUE_EXPRESSION__BODY)
+ && (position == 0)) {
+
+ MultiplicityElement mult = get().toUML();
+ ValueSpecification bound = (ValueSpecification) msg.getNotifier();
+
+ if (bound == mult.getLowerValue()) {
+ handleLowerBoundChanged(null, value);
+ } else {
+ handleUpperBoundChanged(null, value);
+ }
+ } else {
+ super.handleValueAdded(msg, position, value);
+ }
+ }
+
+ @Override
+ protected void handleValueRemoved(Notification msg, int position, Object value) {
+ if ((msg.getFeature() == UMLPackage.Literals.OPAQUE_EXPRESSION__BODY)
+ && ((OpaqueExpression) msg.getNotifier()).getBodies().isEmpty()) {
+
+ MultiplicityElement mult = get().toUML();
+ ValueSpecification bound = (ValueSpecification) msg.getNotifier();
+
+ if (bound == mult.getLowerValue()) {
+ handleLowerBoundChanged(value, null);
+ } else {
+ handleUpperBoundChanged(value, null);
+ }
+ } else {
+ super.handleValueRemoved(msg, position, value);
+ }
+ }
+
+ protected void handleLowerBoundChanged(Object oldValue, Object newValue) {
+ // We don't do lower bounds at this level of abstraction
+ }
+
+ protected void handleUpperBoundChanged(Object oldValue, Object newValue) {
+ if (get().eNotificationRequired()) {
+ if (newValue instanceof Integer) {
+ Integer oldInt = (oldValue instanceof Integer) ? (Integer) oldValue : 1;
+ get().eNotify(new ENotificationImpl(get(), Notification.SET,
+ UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR,
+ oldInt, newValue));
+
+ String oldString = (oldValue instanceof String) ? (String) oldValue : oldInt.toString();
+ get().eNotify(new ENotificationImpl(get(), Notification.SET,
+ UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING,
+ oldString, String.valueOf(newValue)));
+ } else {
+ // Not numeric. Go for the strings. But not "null"
+ String oldString = (oldValue == null) ? null : oldValue.toString();
+ String newString = (newValue == null) ? null : newValue.toString();
+ get().eNotify(new ENotificationImpl(get(), Notification.SET,
+ UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING,
+ oldString, newString));
+ }
+ }
+ }
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
@@ -95,6 +291,11 @@ public abstract class UMLRTReplicatedElementImpl extends UMLRTNamedElementImpl i
return UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT;
}
+ @Override
+ protected BasicFacadeAdapter<? extends UMLRTReplicatedElementImpl> createFacadeAdapter() {
+ return new ReplicationAdapter<>(this);
+ }
+
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/FacadeObjectImpl.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/FacadeObjectImpl.java
index c3c9179ef..190d0df5e 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/FacadeObjectImpl.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/facade/impl/FacadeObjectImpl.java
@@ -57,7 +57,7 @@ public abstract class FacadeObjectImpl extends MinimalEObjectImpl.Container impl
try {
referenceKind = ReferenceKind.valueOf(config);
if (referenceKind != FACADE_REFERENCE_KIND_DEFAULT) {
- UMLRTUMLPlugin.INSTANCE.log(String.format("Using %s reference for facade.", referenceKind));
+ UMLRTUMLPlugin.INSTANCE.log(String.format("Using %s references for facade.", referenceKind));
}
} catch (Exception e) {
UMLRTUMLPlugin.INSTANCE.log("Unrecognized value of papyrusrt.facadeReferenceKind system property: " + config);
@@ -209,7 +209,7 @@ public abstract class FacadeObjectImpl extends MinimalEObjectImpl.Container impl
removeAdapter(getTarget());
}
- return facade.get();
+ return result;
}
@Override
@@ -345,13 +345,13 @@ public abstract class FacadeObjectImpl extends MinimalEObjectImpl.Container impl
}
protected FacadeObject getFacade(Notification msg, EObject object) {
- return getFacade((EObject) msg.getNotifier(), (EReference) msg.getFeature(), object);
+ return (object == null) ? null : getFacade((EObject) msg.getNotifier(), (EReference) msg.getFeature(), object);
}
protected FacadeObject getFacade(EObject umlOwner, EReference umlReference, EObject object) {
- FacadeObject result = UMLRTFactory.create(object);
+ FacadeObject result = (object == null) ? null : UMLRTFactory.create(object);
- if ((result == null) && (object.eResource() == null)) {
+ if ((result == null) && (object != null) && (object.eResource() == null)) {
// If the object was destroyed, it may have lost its adapter,
// so we need to scan
List<? extends FacadeObject> search = getFacadeList(umlOwner, umlReference, object);
@@ -389,7 +389,11 @@ public abstract class FacadeObjectImpl extends MinimalEObjectImpl.Container impl
protected void handleObjectReplaced(Notification msg, int position, EObject oldObject, EObject newObject) {
FacadeObject oldFacade = getFacade(msg, oldObject);
FacadeObject newFacade = getFacade(msg, newObject);
- if ((oldFacade != null) && (newFacade != null)) {
+
+ if (((oldFacade != null) || (oldObject == null))
+ && ((newFacade != null) || (newObject == null))) {
+ // Be careful to to misinterpret the case where there was an old/new
+ // object that does not correspond to a façade object
handleObjectReplaced(msg, position, oldFacade, newFacade);
} else {
handleObjectRemoved(msg, position, oldObject);
diff --git a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritanceAdapter.java b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritanceAdapter.java
index 18cd9e07d..f16869440 100644
--- a/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritanceAdapter.java
+++ b/plugins/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml/src/org/eclipse/papyrusrt/umlrt/uml/internal/util/InheritanceAdapter.java
@@ -40,6 +40,7 @@ import org.eclipse.emf.ecore.util.Switch;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Capsule;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.CapsulePart;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.Protocol;
+import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.ProtocolContainer;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTConnector;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageSet;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort;
@@ -66,6 +67,7 @@ import org.eclipse.papyrusrt.umlrt.uml.internal.umlext.util.ExtensionResource;
import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTExtensionUtil;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Collaboration;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Generalization;
@@ -900,9 +902,16 @@ public abstract class InheritanceAdapter extends AdapterImpl {
switch (stereotypeApplication.eClass().getClassifierID()) {
case UMLRealTimePackage.CAPSULE: {
Capsule capsule = (Capsule) stereotypeApplication;
- if (capsule.getBase_Class() != null) {
+ Class base = capsule.getBase_Class();
+ if (base != null) {
// Initialize it
- getClassifierAdapter().adapt(capsule.getBase_Class());
+ getClassifierAdapter().adapt(base);
+
+ // Kick the package façade, if any
+ org.eclipse.uml2.uml.Package package_ = base.getNearestPackage();
+ if (package_ != null) {
+ FacadeAdapter.getInstance(package_).ifPresent(a -> a.tickle(base));
+ }
}
break;
}
@@ -947,9 +956,19 @@ public abstract class InheritanceAdapter extends AdapterImpl {
}
case UMLRealTimePackage.PROTOCOL: {
Protocol protocol = (Protocol) stereotypeApplication;
- if (protocol.getBase_Collaboration() != null) {
+ Collaboration base = protocol.getBase_Collaboration();
+ if (base != null) {
// Initialize it
- getClassifierAdapter().adapt(protocol.getBase_Collaboration());
+ getClassifierAdapter().adapt(base);
+
+ // Kick the package façade, if any
+ org.eclipse.uml2.uml.Package package_ = base.getNearestPackage();
+ if (package_ != null) {
+ package_ = package_.getNestingPackage();
+ if (package_ != null) {
+ FacadeAdapter.getInstance(package_).ifPresent(a -> a.tickle(base));
+ }
+ }
}
break;
}
@@ -961,7 +980,18 @@ public abstract class InheritanceAdapter extends AdapterImpl {
}
break;
}
- // TODO etc.
+ case UMLRealTimePackage.PROTOCOL_CONTAINER: {
+ ProtocolContainer protocolContainer = (ProtocolContainer) stereotypeApplication;
+ org.eclipse.uml2.uml.Package base = protocolContainer.getBase_Package();
+ if (base != null) {
+ // Kick the containing package façade, if any
+ org.eclipse.uml2.uml.Package package_ = base.getNestingPackage();
+ if (package_ != null) {
+ FacadeAdapter.getInstance(package_).ifPresent(a -> a.tickle(base));
+ }
+ }
+ break;
+ }
}
}
diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsuleFacadeNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsuleFacadeNotificationTest.java
new file mode 100644
index 000000000..b1cb247ed
--- /dev/null
+++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsuleFacadeNotificationTest.java
@@ -0,0 +1,113 @@
+/*****************************************************************************
+ * Copyright (c) 2017 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.uml.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTConnector;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort;
+import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.CapsuleTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.FacadeTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test cases for notifications in the capsule façade class {@link UMLRTCapsule}.
+ */
+@TestModel("inheritance/ports.uml")
+@Category({ CapsuleTests.class, FacadeTests.class })
+public class CapsuleFacadeNotificationTest {
+
+ @Rule
+ public final ModelFixture fixture = new ModelFixture();
+
+ public CapsuleFacadeNotificationTest() {
+ super();
+ }
+
+ @Test
+ public void nameNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+
+ fixture.expectNotification(capsule, UMLRTUMLRTPackage.Literals.NAMED_ELEMENT__NAME, Notification.SET,
+ is("RootCapsule"), is("NewName"), () -> capsule.toUML().setName("NewName"));
+ }
+
+ @Test
+ public void portNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+
+ UMLRTPort[] newPort = { null };
+ capsule.getPorts(); // Make sure the list exists to notify
+
+ fixture.expectNotification(capsule, UMLRTUMLRTPackage.Literals.CAPSULE__PORT, Notification.ADD,
+ null, fixture.defer(() -> is(newPort[0])), () -> newPort[0] = capsule.createPort(capsule.getPackage().getProtocol("Protocol1")));
+
+ fixture.expectNotification(capsule, UMLRTUMLRTPackage.Literals.CAPSULE__PORT, Notification.REMOVE,
+ is(newPort[0]), null, newPort[0]::destroy);
+ }
+
+ @Test
+ @TestModel("inheritance/parts.uml")
+ public void capsulePartNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+
+ UMLRTCapsulePart[] newPart = { null };
+ capsule.getCapsuleParts(); // Make sure the list exists to notify
+
+ fixture.expectNotification(capsule, UMLRTUMLRTPackage.Literals.CAPSULE__CAPSULE_PART, Notification.ADD,
+ null, fixture.defer(() -> is(newPart[0])), () -> newPart[0] = capsule.createCapsulePart(capsule.getPackage().getCapsule("Capsule2")));
+
+ fixture.expectNotification(capsule, UMLRTUMLRTPackage.Literals.CAPSULE__CAPSULE_PART, Notification.REMOVE,
+ is(newPart[0]), null, newPart[0]::destroy);
+ }
+
+ @Test
+ @TestModel("inheritance/connectors.uml")
+ public void connectorNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPorts().get(0);
+ UMLRTCapsulePart part = capsule.getCapsuleParts().get(0);
+ UMLRTCapsule nested = part.getType();
+
+ UMLRTConnector[] newConnector = { null };
+ capsule.getConnectors(); // Make sure the list exists to notify
+
+ fixture.expectNotification(capsule, UMLRTUMLRTPackage.Literals.CAPSULE__CONNECTOR, Notification.ADD,
+ null, fixture.defer(() -> is(newConnector[0])),
+ () -> newConnector[0] = capsule.createConnector("NewConnector", port, null, nested.getPorts().get(0), part));
+
+ fixture.expectNotification(capsule, UMLRTUMLRTPackage.Literals.CAPSULE__CONNECTOR, Notification.REMOVE,
+ is(newConnector[0]), null, newConnector[0]::destroy);
+ }
+
+ @Test
+ public void setSuperCapsule() {
+ UMLRTPackage model = UMLRTPackage.getInstance(fixture.getModel());
+ UMLRTCapsule capsule = model.getCapsule("RootCapsule");
+ UMLRTCapsule subcapsule = model.getCapsule("Subcapsule");
+ UMLRTCapsule subsubcapsule = model.getCapsule("Subsubcapsule");
+
+ fixture.expectNotification(subsubcapsule, UMLRTUMLRTPackage.Literals.CAPSULE__SUPERCLASS, Notification.SET,
+ is(subcapsule), is(capsule), () -> subsubcapsule.toUML().getGeneralizations().get(0).setGeneral(capsule.toUML()));
+ }
+}
diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsulePartNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsulePartNotificationTest.java
new file mode 100644
index 000000000..377571700
--- /dev/null
+++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/CapsulePartNotificationTest.java
@@ -0,0 +1,197 @@
+/*****************************************************************************
+ * Copyright (c) 2017 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.uml.tests;
+
+import static org.hamcrest.CoreMatchers.anything;
+import static org.hamcrest.CoreMatchers.is;
+
+import java.util.List;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePartKind;
+import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.CapsuleTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.FacadeTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel;
+import org.eclipse.uml2.uml.AggregationKind;
+import org.eclipse.uml2.uml.MultiplicityElement;
+import org.eclipse.uml2.uml.OpaqueExpression;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test cases for notifications in the capsule façade class {@link UMLRTCapsulePart}.
+ */
+@TestModel("inheritance/parts.uml")
+@Category({ CapsuleTests.class, FacadeTests.class })
+public class CapsulePartNotificationTest {
+
+ @Rule
+ public final ModelFixture fixture = new ModelFixture();
+
+ public CapsulePartNotificationTest() {
+ super();
+ }
+
+ @Test
+ public void nameNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTCapsulePart part = capsule.getCapsulePart("capsule2");
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.NAMED_ELEMENT__NAME, Notification.SET,
+ is("capsule2"), is("newName"), () -> part.toUML().setName("newName"));
+ }
+
+ @Test
+ public void typeNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTCapsule capsule4 = UMLRTCapsule.getInstance(fixture.getElement("Capsule4"));
+ UMLRTCapsulePart part = capsule.getCapsulePart("capsule2");
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.CAPSULE_PART__TYPE, Notification.SET,
+ is(part.getType()), is(capsule4), () -> part.toUML().setType(capsule4.toUML()));
+ }
+
+ @Test
+ public void optionalNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTCapsulePart part = capsule.getCapsulePart("capsule2");
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.CAPSULE_PART__OPTIONAL, Notification.SET,
+ is(false), is(true), () -> part.toUML().setLower(0));
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.CAPSULE_PART__OPTIONAL, Notification.SET,
+ is(true), is(false), () -> part.toUML().setLower(1));
+
+ fixture.expectNoNotification(part, UMLRTUMLRTPackage.Literals.CAPSULE_PART__OPTIONAL, Notification.SET,
+ anything(), anything(), () -> destroyReplication(part.toUML()));
+ }
+
+ @Test
+ public void replicationNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTCapsulePart part = capsule.getCapsulePart("capsule2");
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR, Notification.SET,
+ anything(), is(3), () -> setReplication(part.toUML(), 3));
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR, Notification.SET,
+ is(3), is(1), () -> setReplication(part.toUML(), 1));
+
+ fixture.expectNoNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR, Notification.SET,
+ anything(), anything(), () -> destroyReplication(part.toUML()));
+ }
+
+ @Test
+ public void replicationAsStringNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTCapsulePart part = capsule.getCapsulePart("capsule2");
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ anything(), is("3"), () -> setReplication(part.toUML(), 3));
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ is("3"), is("1"), () -> setReplication(part.toUML(), 1));
+
+ fixture.expectNoNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ anything(), anything(), () -> destroyReplication(part.toUML()));
+ }
+
+ @Test
+ public void symbolicReplicationNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTCapsulePart part = capsule.getCapsulePart("capsule2");
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ anything(), is("MAX_PARTS"), () -> setReplication(part.toUML(), "MAX_PARTS"));
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ is("MAX_PARTS"), is("NUM_PARTS"), () -> setReplication(part.toUML(), "NUM_PARTS"));
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ is("NUM_PARTS"), is("1"), () -> destroyReplication(part.toUML()));
+ }
+
+ @Test
+ public void kindNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTCapsulePart part = capsule.getCapsulePart("capsule2");
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.CAPSULE_PART__KIND, Notification.SET,
+ is(UMLRTCapsulePartKind.FIXED), is(UMLRTCapsulePartKind.OPTIONAL),
+ () -> part.toUML().setLower(0));
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.CAPSULE_PART__KIND, Notification.SET,
+ is(UMLRTCapsulePartKind.OPTIONAL), is(UMLRTCapsulePartKind.PLUG_IN),
+ () -> part.toUML().setAggregation(AggregationKind.SHARED_LITERAL));
+
+ fixture.expectNotification(part, UMLRTUMLRTPackage.Literals.CAPSULE_PART__KIND, Notification.SET,
+ is(UMLRTCapsulePartKind.PLUG_IN), is(UMLRTCapsulePartKind.FIXED),
+ () -> destroyReplication(part.toUML()));
+
+ // Fixed doesn't care about aggregation
+ fixture.expectNoNotification(part, UMLRTUMLRTPackage.Literals.CAPSULE_PART__KIND, Notification.SET,
+ anything(), anything(),
+ () -> part.toUML().setAggregation(AggregationKind.COMPOSITE_LITERAL));
+ }
+
+ //
+ // Test framework
+ //
+
+ void setReplication(MultiplicityElement mult, int replication) {
+ mult.setLower(replication);
+ mult.setUpper(replication);
+ }
+
+ void setReplication(MultiplicityElement mult, String replication) {
+ if (mult.getLowerValue() instanceof OpaqueExpression) {
+ List<String> body = ((OpaqueExpression) mult.getLowerValue()).getBodies();
+ if (body.isEmpty()) {
+ body.add(replication);
+ } else {
+ body.set(0, replication);
+ }
+ } else {
+ ((OpaqueExpression) mult.createLowerValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION))
+ .getBodies().add(replication);
+ }
+
+ if (mult.getUpperValue() instanceof OpaqueExpression) {
+ List<String> body = ((OpaqueExpression) mult.getUpperValue()).getBodies();
+ if (body.isEmpty()) {
+ body.add(replication);
+ } else {
+ body.set(0, replication);
+ }
+ } else {
+ ((OpaqueExpression) mult.createUpperValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION))
+ .getBodies().add(replication);
+ }
+ }
+
+ void destroyReplication(MultiplicityElement mult) {
+ if (mult.getLowerValue() != null) {
+ mult.getLowerValue().destroy();
+ }
+ if (mult.getUpperValue() != null) {
+ mult.getUpperValue().destroy();
+ }
+ }
+}
diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ConnectorNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ConnectorNotificationTest.java
new file mode 100644
index 000000000..ce580974e
--- /dev/null
+++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ConnectorNotificationTest.java
@@ -0,0 +1,169 @@
+/*****************************************************************************
+ * Copyright (c) 2017 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.uml.tests;
+
+import static org.hamcrest.CoreMatchers.anything;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import java.util.List;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsulePart;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTConnector;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort;
+import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.CapsuleTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.FacadeTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel;
+import org.eclipse.uml2.uml.MultiplicityElement;
+import org.eclipse.uml2.uml.OpaqueExpression;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test cases for notifications in the capsule façade class {@link UMLRTConnector}.
+ */
+@TestModel("inheritance/connectors.uml")
+@Category({ CapsuleTests.class, FacadeTests.class })
+public class ConnectorNotificationTest {
+
+ @Rule
+ public final ModelFixture fixture = new ModelFixture();
+
+ public ConnectorNotificationTest() {
+ super();
+ }
+
+ @Test
+ public void nameNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTConnector connector = capsule.getConnector("connector1");
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.NAMED_ELEMENT__NAME, Notification.SET,
+ is("connector1"), is("newName"), () -> connector.toUML().setName("newName"));
+ }
+
+ @Test
+ public void sourceNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTConnector connector = capsule.getConnector("connector1");
+ UMLRTPort port = capsule.getPort("protocol2");
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.CONNECTOR__SOURCE, Notification.SET,
+ is(connector.getSource()), is(port), () -> connector.toUML().getEnds().get(0).setRole(port.toUML()));
+ }
+
+ @Test
+ public void sourcePartWithPortNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTConnector connector = capsule.getConnector("connector1");
+ UMLRTCapsulePart part = capsule.getCapsulePart("nestedCapsule");
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.CONNECTOR__SOURCE_PART_WITH_PORT, Notification.SET,
+ nullValue(), is(part), () -> connector.toUML().getEnds().get(0).setPartWithPort(part.toUML()));
+ }
+
+ @Test
+ public void targetNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTConnector connector = capsule.getConnector("connector1");
+ UMLRTPort port = capsule.getPort("protocol2");
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.CONNECTOR__TARGET, Notification.SET,
+ is(connector.getTarget()), is(port), () -> connector.toUML().getEnds().get(1).setRole(port.toUML()));
+ }
+
+ @Test
+ public void targetPartWithPortNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTConnector connector = capsule.getConnector("connector1");
+ UMLRTCapsulePart part = capsule.getCapsulePart("nestedCapsule");
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.CONNECTOR__TARGET_PART_WITH_PORT, Notification.SET,
+ is(part), nullValue(), () -> connector.toUML().getEnds().get(1).setPartWithPort(null));
+ }
+
+ @Test
+ public void sourceReplicationNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTConnector connector = capsule.getConnector("connector1");
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.CONNECTOR__SOURCE_REPLICATION_FACTOR, Notification.SET,
+ anything(), is(3), () -> setReplication(connector.toUML().getEnds().get(0), 3));
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.CONNECTOR__SOURCE_REPLICATION_FACTOR, Notification.SET,
+ is(3), is(1), () -> destroyReplication(connector.toUML().getEnds().get(0)));
+ }
+
+ @Test
+ public void targetReplicationNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTConnector connector = capsule.getConnector("connector1");
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.CONNECTOR__TARGET_REPLICATION_FACTOR, Notification.SET,
+ anything(), is(3), () -> setReplication(connector.toUML().getEnds().get(1), 3));
+
+ fixture.expectNotification(connector, UMLRTUMLRTPackage.Literals.CONNECTOR__TARGET_REPLICATION_FACTOR, Notification.SET,
+ is(3), is(1), () -> destroyReplication(connector.toUML().getEnds().get(1)));
+ }
+
+ //
+ // Test framework
+ //
+
+ void setReplication(MultiplicityElement mult, int replication) {
+ mult.setLower(replication);
+ mult.setUpper(replication);
+ }
+
+ void setReplication(MultiplicityElement mult, String replication) {
+ if (mult.getLowerValue() instanceof OpaqueExpression) {
+ List<String> body = ((OpaqueExpression) mult.getLowerValue()).getBodies();
+ if (body.isEmpty()) {
+ body.add(replication);
+ } else {
+ body.set(0, replication);
+ }
+ } else {
+ ((OpaqueExpression) mult.createLowerValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION))
+ .getBodies().add(replication);
+ }
+
+ if (mult.getUpperValue() instanceof OpaqueExpression) {
+ List<String> body = ((OpaqueExpression) mult.getUpperValue()).getBodies();
+ if (body.isEmpty()) {
+ body.add(replication);
+ } else {
+ body.set(0, replication);
+ }
+ } else {
+ ((OpaqueExpression) mult.createUpperValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION))
+ .getBodies().add(replication);
+ }
+ }
+
+ void destroyReplication(MultiplicityElement mult) {
+ if (mult.getLowerValue() != null) {
+ mult.getLowerValue().destroy();
+ }
+ if (mult.getUpperValue() != null) {
+ mult.getUpperValue().destroy();
+ }
+ }
+}
diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PackageFacadeNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PackageFacadeNotificationTest.java
new file mode 100644
index 000000000..543bc024f
--- /dev/null
+++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PackageFacadeNotificationTest.java
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * Copyright (c) 2017 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.uml.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol;
+import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.CapsuleTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.FacadeTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test cases for notifications in the façade class {@link UMLRTPackage}.
+ */
+@TestModel("inheritance/ports.uml")
+@Category({ CapsuleTests.class, FacadeTests.class })
+public class PackageFacadeNotificationTest {
+
+ @Rule
+ public final ModelFixture fixture = new ModelFixture();
+
+ public PackageFacadeNotificationTest() {
+ super();
+ }
+
+ @Test
+ public void nameNotifications() {
+ UMLRTPackage package_ = fixture.getRoot();
+
+ fixture.expectNotification(package_, UMLRTUMLRTPackage.Literals.NAMED_ELEMENT__NAME, Notification.SET,
+ is("ports"), is("NewName"), () -> package_.toUML().setName("NewName"));
+ }
+
+ @Test
+ public void nestedPackageNotifications() {
+ UMLRTPackage package_ = fixture.getRoot();
+
+ UMLRTPackage[] newPackage = { null };
+ package_.getNestedPackages(); // Make sure the list exists to notify
+
+ fixture.expectNotification(package_, UMLRTUMLRTPackage.Literals.PACKAGE__NESTED_PACKAGE, Notification.ADD,
+ null, fixture.defer(() -> is(newPackage[0])), () -> newPackage[0] = package_.createNestedPackage("NewPackage"));
+
+ fixture.expectNotification(package_, UMLRTUMLRTPackage.Literals.PACKAGE__NESTED_PACKAGE, Notification.REMOVE,
+ is(newPackage[0]), null, newPackage[0]::destroy);
+ }
+
+ @Test
+ public void capsuleNotifications() {
+ UMLRTPackage package_ = fixture.getRoot();
+
+ UMLRTCapsule[] newCapsule = { null };
+ package_.getCapsules(); // Make sure the list exists to notify
+
+ fixture.expectNotification(package_, UMLRTUMLRTPackage.Literals.PACKAGE__CAPSULE, Notification.ADD,
+ null, fixture.defer(() -> is(newCapsule[0])), () -> newCapsule[0] = package_.createCapsule("NewCapsule"));
+
+ fixture.expectNotification(package_, UMLRTUMLRTPackage.Literals.PACKAGE__CAPSULE, Notification.REMOVE,
+ is(newCapsule[0]), null, newCapsule[0]::destroy);
+ }
+
+ @Test
+ public void protocolNotifications() {
+ UMLRTPackage package_ = fixture.getRoot();
+
+ UMLRTProtocol[] newProtocol = { null };
+ package_.getProtocols(); // Make sure the list exists to notify
+
+ fixture.expectNotification(package_, UMLRTUMLRTPackage.Literals.PACKAGE__PROTOCOL, Notification.ADD,
+ null, fixture.defer(() -> is(newProtocol[0])), () -> newProtocol[0] = package_.createProtocol("NewProtocol"));
+
+ fixture.expectNotification(package_, UMLRTUMLRTPackage.Literals.PACKAGE__PROTOCOL, Notification.REMOVE,
+ is(newProtocol[0]), null, newProtocol[0]::destroy);
+ }
+}
diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PortFacadeNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PortFacadeNotificationTest.java
new file mode 100644
index 000000000..046e97f1c
--- /dev/null
+++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/PortFacadeNotificationTest.java
@@ -0,0 +1,297 @@
+/*****************************************************************************
+ * Copyright (c) 2017 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.uml.tests;
+
+import static org.hamcrest.CoreMatchers.anything;
+import static org.hamcrest.CoreMatchers.is;
+
+import java.util.List;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.PortRegistrationType;
+import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTPort;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTCapsule;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTPort;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTPortKind;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol;
+import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.CapsuleTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.FacadeTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel;
+import org.eclipse.uml2.uml.MultiplicityElement;
+import org.eclipse.uml2.uml.OpaqueExpression;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.util.UMLUtil;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test cases for notifications in the capsule façade class {@link UMLRTPort}.
+ */
+@TestModel("inheritance/ports.uml")
+@Category({ CapsuleTests.class, FacadeTests.class })
+public class PortFacadeNotificationTest {
+
+ @Rule
+ public final ModelFixture fixture = new ModelFixture();
+
+ public PortFacadeNotificationTest() {
+ super();
+ }
+
+ @Test
+ public void nameNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.NAMED_ELEMENT__NAME, Notification.SET,
+ is("protocol1"), is("newName"), () -> port.toUML().setName("newName"));
+ }
+
+ @Test
+ public void typeNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+ UMLRTProtocol protocol2 = capsule.getPackage().getProtocol("Protocol2");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__TYPE, Notification.SET,
+ is(port.getType()), is(protocol2), () -> port.toUML().setType(protocol2.toUML()));
+ }
+
+ @Test
+ public void replicationNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR, Notification.SET,
+ anything(), is(3), () -> setReplication(port.toUML(), 3));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR, Notification.SET,
+ is(3), is(1), () -> setReplication(port.toUML(), 1));
+
+ fixture.expectNoNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR, Notification.SET,
+ anything(), anything(), () -> destroyReplication(port.toUML()));
+ }
+
+ @Test
+ public void replicationAsStringNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ anything(), is("3"), () -> setReplication(port.toUML(), 3));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ is("3"), is("1"), () -> setReplication(port.toUML(), 1));
+
+ fixture.expectNoNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ anything(), anything(), () -> destroyReplication(port.toUML()));
+ }
+
+ @Test
+ public void symbolicReplicationNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ anything(), is("MAX_PARTS"), () -> setReplication(port.toUML(), "MAX_PARTS"));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ is("MAX_PARTS"), is("NUM_PARTS"), () -> setReplication(port.toUML(), "NUM_PARTS"));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.REPLICATED_ELEMENT__REPLICATION_FACTOR_AS_STRING, Notification.SET,
+ is("NUM_PARTS"), is("1"), () -> destroyReplication(port.toUML()));
+ }
+
+ @Test
+ public void conjugateNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__CONJUGATED, Notification.SET,
+ is(port.isConjugated()), is(!port.isConjugated()),
+ () -> port.toUML().setIsConjugated(!port.toUML().isConjugated()));
+ }
+
+ @Test
+ public void conjugateTypeNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__TYPE, Notification.SET,
+ is(port.getType()), is(port.getType().getConjugate()),
+ () -> port.toUML().setIsConjugated(!port.toUML().isConjugated()));
+ }
+
+ @Test
+ public void behaviorNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__BEHAVIOR, Notification.SET,
+ is(port.isBehavior()), is(!port.isBehavior()),
+ () -> port.toUML().setIsBehavior(!port.toUML().isBehavior()));
+ }
+
+ @Test
+ public void serviceNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__SERVICE, Notification.SET,
+ is(port.isService()), is(!port.isService()),
+ () -> port.toUML().setIsService(!port.toUML().isService()));
+ }
+
+ @Test
+ public void wiredNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+ RTPort stereo = UMLUtil.getStereotypeApplication(port.toUML(), RTPort.class);
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__WIRED, Notification.SET,
+ is(port.isWired()), is(!port.isWired()),
+ () -> stereo.setIsWired(!stereo.isWired()));
+ }
+
+ @Test
+ public void publishNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+ RTPort stereo = UMLUtil.getStereotypeApplication(port.toUML(), RTPort.class);
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__PUBLISH, Notification.SET,
+ is(port.isPublish()), is(!port.isPublish()),
+ () -> stereo.setIsPublish(!stereo.isPublish()));
+ }
+
+ @Test
+ public void notificationNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+ RTPort stereo = UMLUtil.getStereotypeApplication(port.toUML(), RTPort.class);
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__NOTIFICATION, Notification.SET,
+ is(port.isNotification()), is(!port.isNotification()),
+ () -> stereo.setIsNotification(!stereo.isNotification()));
+ }
+
+ @Test
+ public void registrationNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+ RTPort stereo = UMLUtil.getStereotypeApplication(port.toUML(), RTPort.class);
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__REGISTRATION, Notification.SET,
+ is(stereo.getRegistration()), is(PortRegistrationType.AUTOMATIC_LOCKED),
+ () -> stereo.setRegistration(PortRegistrationType.AUTOMATIC_LOCKED));
+ }
+
+ @Test
+ public void registrationOverrideNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+ RTPort stereo = UMLUtil.getStereotypeApplication(port.toUML(), RTPort.class);
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__REGISTRATION_OVERRIDE, Notification.SET,
+ is(""), is("whatever"),
+ () -> stereo.setRegistrationOverride("whatever"));
+ }
+
+ @Test
+ public void kindNotifications() {
+ UMLRTCapsule capsule = UMLRTCapsule.getInstance(fixture.getElement("RootCapsule"));
+ UMLRTPort port = capsule.getPort("protocol1");
+ RTPort stereo = UMLUtil.getStereotypeApplication(port.toUML(), RTPort.class);
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__KIND, Notification.SET,
+ is(UMLRTPortKind.EXTERNAL_BEHAVIOR), is(UMLRTPortKind.RELAY),
+ () -> port.toUML().setIsBehavior(false));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__KIND, Notification.SET,
+ is(UMLRTPortKind.RELAY), is(UMLRTPortKind.EXTERNAL_BEHAVIOR),
+ () -> port.toUML().setIsBehavior(true));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__KIND, Notification.SET,
+ is(UMLRTPortKind.EXTERNAL_BEHAVIOR), is(UMLRTPortKind.INTERNAL_BEHAVIOR),
+ () -> port.toUML().setIsService(false));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__KIND, Notification.SET,
+ is(UMLRTPortKind.INTERNAL_BEHAVIOR), is(UMLRTPortKind.SAP),
+ () -> stereo.setIsWired(false));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__KIND, Notification.SET,
+ is(UMLRTPortKind.SAP), is(UMLRTPortKind.SPP),
+ () -> stereo.setIsPublish(true));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__KIND, Notification.SET,
+ is(UMLRTPortKind.SPP), is(UMLRTPortKind.NULL),
+ () -> stereo.setIsWired(true));
+
+ // The isService is still false!
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__KIND, Notification.SET,
+ is(UMLRTPortKind.NULL), is(UMLRTPortKind.INTERNAL_BEHAVIOR),
+ () -> stereo.setIsPublish(false));
+
+ fixture.expectNotification(port, UMLRTUMLRTPackage.Literals.PORT__KIND, Notification.SET,
+ is(UMLRTPortKind.INTERNAL_BEHAVIOR), is(UMLRTPortKind.EXTERNAL_BEHAVIOR),
+ () -> port.toUML().setIsService(true));
+ }
+
+ //
+ // Test framework
+ //
+
+ void setReplication(MultiplicityElement mult, int replication) {
+ mult.setLower(replication);
+ mult.setUpper(replication);
+ }
+
+ void setReplication(MultiplicityElement mult, String replication) {
+ if (mult.getLowerValue() instanceof OpaqueExpression) {
+ List<String> body = ((OpaqueExpression) mult.getLowerValue()).getBodies();
+ if (body.isEmpty()) {
+ body.add(replication);
+ } else {
+ body.set(0, replication);
+ }
+ } else {
+ ((OpaqueExpression) mult.createLowerValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION))
+ .getBodies().add(replication);
+ }
+
+ if (mult.getUpperValue() instanceof OpaqueExpression) {
+ List<String> body = ((OpaqueExpression) mult.getUpperValue()).getBodies();
+ if (body.isEmpty()) {
+ body.add(replication);
+ } else {
+ body.set(0, replication);
+ }
+ } else {
+ ((OpaqueExpression) mult.createUpperValue(null, null, UMLPackage.Literals.OPAQUE_EXPRESSION))
+ .getBodies().add(replication);
+ }
+ }
+
+ void destroyReplication(MultiplicityElement mult) {
+ if (mult.getLowerValue() != null) {
+ mult.getLowerValue().destroy();
+ }
+ if (mult.getUpperValue() != null) {
+ mult.getUpperValue().destroy();
+ }
+ }
+}
diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolFacadeNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolFacadeNotificationTest.java
new file mode 100644
index 000000000..af2bbfb28
--- /dev/null
+++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolFacadeNotificationTest.java
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (c) 2017 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.uml.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocolMessage;
+import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.FacadeTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.ProtocolTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test cases for notifications in the protocol façade class {@link UMLRTProtocol}.
+ */
+@TestModel("inheritance/ports.uml")
+@Category({ ProtocolTests.class, FacadeTests.class })
+public class ProtocolFacadeNotificationTest {
+
+ @Rule
+ public final ModelFixture fixture = new ModelFixture();
+
+ public ProtocolFacadeNotificationTest() {
+ super();
+ }
+
+ @Test
+ public void nameNotifications() {
+ UMLRTProtocol protocol = fixture.getRoot().getProtocol("Protocol1");
+
+ fixture.expectNotification(protocol, UMLRTUMLRTPackage.Literals.NAMED_ELEMENT__NAME, Notification.SET,
+ is("Protocol1"), is("NewName"), () -> protocol.toUML().setName("NewName"));
+ }
+
+ @Test
+ public void inMessageNotifications() {
+ messageNotifications(RTMessageKind.IN, UMLRTUMLRTPackage.Literals.PROTOCOL__IN_MESSAGE);
+ }
+
+ void messageNotifications(RTMessageKind kind, EReference reference) {
+ UMLRTProtocol protocol = fixture.getRoot().getProtocol("Protocol1");
+
+ UMLRTProtocolMessage[] newMessage = { null };
+ ((EObject) protocol).eGet(reference); // Make sure the list exists to notify
+
+ fixture.expectNotification(protocol, reference, Notification.ADD,
+ null, fixture.defer(() -> is(newMessage[0])),
+ () -> newMessage[0] = protocol.createMessage(kind, "newMsg"));
+
+ fixture.expectNotification(protocol, reference, Notification.REMOVE,
+ is(newMessage[0]), null, newMessage[0]::destroy);
+ }
+
+ @Test
+ public void outMessageNotifications() {
+ messageNotifications(RTMessageKind.OUT, UMLRTUMLRTPackage.Literals.PROTOCOL__OUT_MESSAGE);
+ }
+
+ @Test
+ public void inOutMessageNotifications() {
+ messageNotifications(RTMessageKind.IN_OUT, UMLRTUMLRTPackage.Literals.PROTOCOL__IN_OUT_MESSAGE);
+ }
+
+ @Test
+ public void setSuperProtocol() {
+ UMLRTProtocol protocol1 = fixture.getRoot().getProtocol("Protocol1");
+ UMLRTProtocol protocol2 = fixture.getRoot().getProtocol("Protocol2");
+
+ fixture.expectNotification(protocol2, UMLRTUMLRTPackage.Literals.PROTOCOL__SUPER_PROTOCOL, Notification.SET,
+ nullValue(), is(protocol1), () -> protocol2.toUML().createGeneralization(protocol1.toUML()));
+ }
+}
diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolMessageFacadeNotificationTest.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolMessageFacadeNotificationTest.java
new file mode 100644
index 000000000..9e31ed8ea
--- /dev/null
+++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/ProtocolMessageFacadeNotificationTest.java
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ * Copyright (c) 2017 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.uml.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.RTMessageKind;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocol;
+import org.eclipse.papyrusrt.umlrt.uml.UMLRTProtocolMessage;
+import org.eclipse.papyrusrt.umlrt.uml.internal.facade.UMLRTUMLRTPackage;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.FacadeTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.categories.ProtocolTests;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.ModelFixture;
+import org.eclipse.papyrusrt.umlrt.uml.tests.util.TestModel;
+import org.eclipse.uml2.uml.Interface;
+import org.eclipse.uml2.uml.Parameter;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * Test cases for notifications in the protocol façade class {@link UMLRTProtocolMessage}.
+ */
+@TestModel("inheritance/ports.uml")
+@Category({ ProtocolTests.class, FacadeTests.class })
+public class ProtocolMessageFacadeNotificationTest {
+
+ @Rule
+ public final ModelFixture fixture = new ModelFixture();
+
+ public ProtocolMessageFacadeNotificationTest() {
+ super();
+ }
+
+ @Test
+ public void nameNotifications() {
+ UMLRTProtocol protocol = fixture.getRoot().getProtocol("Protocol1");
+ UMLRTProtocolMessage message = protocol.getInMessage("greet");
+
+ fixture.expectNotification(message, UMLRTUMLRTPackage.Literals.NAMED_ELEMENT__NAME, Notification.SET,
+ is("greet"), is("sayHello"), () -> message.toUML().setName("sayHello"));
+ }
+
+ @Test
+ public void parameterNotifications() {
+ UMLRTProtocol protocol = fixture.getRoot().getProtocol("Protocol1");
+ UMLRTProtocolMessage message = protocol.getInMessage("greet");
+
+ Parameter[] newParam = { null };
+
+ fixture.expectNotification(message, UMLRTUMLRTPackage.Literals.PROTOCOL_MESSAGE__PARAMETER, Notification.ADD,
+ nullValue(), fixture.defer(() -> is(newParam[0])),
+ () -> newParam[0] = message.createParameter("whatToSay", null));
+
+ fixture.expectNotification(message, UMLRTUMLRTPackage.Literals.PROTOCOL_MESSAGE__PARAMETER, Notification.REMOVE,
+ is(newParam[0]), nullValue(),
+ () -> newParam[0].destroy());
+ }
+
+ @Test
+ public void kindNotifications() {
+ UMLRTProtocol protocol = fixture.getRoot().getProtocol("Protocol1");
+ UMLRTProtocolMessage message = protocol.getInMessage("greet");
+
+ Interface messageSetIn = fixture.getElement("Protocol1::Protocol1", Interface.class);
+ Interface messageSetOut = fixture.getElement("Protocol1::Protocol1~", Interface.class);
+ Interface messageSetInOut = fixture.getElement("Protocol1::Protocol1IO", Interface.class);
+
+ fixture.expectNotification(message, UMLRTUMLRTPackage.Literals.PROTOCOL_MESSAGE__KIND, Notification.SET,
+ is(RTMessageKind.IN), is(RTMessageKind.IN_OUT),
+ () -> messageSetInOut.getOwnedOperations().add(message.toUML()));
+
+ fixture.expectNotification(message, UMLRTUMLRTPackage.Literals.PROTOCOL_MESSAGE__KIND, Notification.SET,
+ is(RTMessageKind.IN_OUT), is(RTMessageKind.OUT),
+ () -> messageSetOut.getOwnedOperations().add(message.toUML()));
+
+ fixture.expectNotification(message, UMLRTUMLRTPackage.Literals.PROTOCOL_MESSAGE__KIND, Notification.SET,
+ is(RTMessageKind.OUT), is(RTMessageKind.IN),
+ () -> messageSetIn.getOwnedOperations().add(message.toUML()));
+ }
+}
diff --git a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/ModelFixture.java b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/ModelFixture.java
index 80f8876a1..ccb91e213 100644
--- a/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/ModelFixture.java
+++ b/tests/junit/umlrt/profile/org.eclipse.papyrusrt.umlrt.uml.tests/src/org/eclipse/papyrusrt/umlrt/uml/tests/util/ModelFixture.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.fail;
import java.lang.annotation.Annotation;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -29,6 +30,7 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.Predicate;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -51,6 +53,7 @@ import org.eclipse.emf.edit.provider.IDisposable;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.papyrusrt.umlrt.profile.UMLRealTime.UMLRealTimePackage;
+import org.eclipse.papyrusrt.umlrt.uml.FacadeObject;
import org.eclipse.papyrusrt.umlrt.uml.UMLRTPackage;
import org.eclipse.papyrusrt.umlrt.uml.internal.impl.InternalUMLRTElement;
import org.eclipse.papyrusrt.umlrt.uml.util.UMLRTResourcesUtil;
@@ -60,6 +63,7 @@ import org.eclipse.uml2.uml.Namespace;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.edit.providers.UMLItemProviderAdapterFactory;
+import org.hamcrest.BaseMatcher;
import org.hamcrest.Matcher;
import org.hamcrest.StringDescription;
import org.hamcrest.core.IsAnything;
@@ -74,12 +78,15 @@ import org.junit.runner.Description;
* @see TestModel
*/
public class ModelFixture extends TestWatcher {
+ private static final Object TEST_DEFERRED = new Object();
private String testModelPath;
private ResourceSet resourceSet;
private Package testModel;
private AdapterFactory adapterFactory;
+ private List<Matcher<Object>> deferred;
+
/**
* Initializes me. I will get the test model from an annotation.
*
@@ -240,6 +247,11 @@ public class ModelFixture extends TestWatcher {
protected void finished(Description description) {
if (resourceSet != null) {
try {
+ // Check deferred assertions
+ if (deferred != null) {
+ deferred.forEach(m -> assertThat(TEST_DEFERRED, m));
+ }
+
// Check that nothing accidentally created the wrong kind of model element
assertModelImplementationOverrides();
@@ -365,12 +377,24 @@ public class ModelFixture extends TestWatcher {
expectNotification(notifier, feature, eventType, oldValueMatcher, newValueMatcher, script, true);
}
+ public <T> void expectNotification(FacadeObject notifier, Object feature, int eventType,
+ Matcher<T> oldValueMatcher, Matcher<T> newValueMatcher, Runnable script) {
+
+ expectNotification((EObject) notifier, feature, eventType, oldValueMatcher, newValueMatcher, script);
+ }
+
public <T> void expectNoNotification(Notifier notifier, Object feature, int eventType,
Matcher<T> oldValueMatcher, Matcher<T> newValueMatcher, Runnable script) {
expectNotification(notifier, feature, eventType, oldValueMatcher, newValueMatcher, script, false);
}
+ public <T> void expectNoNotification(FacadeObject notifier, Object feature, int eventType,
+ Matcher<T> oldValueMatcher, Matcher<T> newValueMatcher, Runnable script) {
+
+ expectNoNotification((EObject) notifier, feature, eventType, oldValueMatcher, newValueMatcher, script);
+ }
+
private <T> void expectNotification(Notifier notifier, Object feature, int eventType,
Matcher<T> oldValueMatcher, Matcher<T> newValueMatcher, Runnable script,
boolean expected) {
@@ -407,11 +431,21 @@ public class ModelFixture extends TestWatcher {
}
};
- resourceSet.eAdapters().add(adapter);
+ if (notifier instanceof FacadeObject) {
+ // Façade objects are free-floating, so we can only attach
+ // adapters directly to them
+ notifier.eAdapters().add(adapter);
+ } else {
+ resourceSet.eAdapters().add(adapter);
+ }
try {
script.run();
} finally {
- resourceSet.eAdapters().remove(adapter);
+ if (notifier instanceof FacadeObject) {
+ notifier.eAdapters().remove(adapter);
+ } else {
+ resourceSet.eAdapters().remove(adapter);
+ }
}
if (found.get() != expected) {
@@ -451,4 +485,47 @@ public class ModelFixture extends TestWatcher {
private static boolean isTrivial(Matcher<?> matcher) {
return (matcher == null) || (matcher instanceof IsAnything<?>);
}
+
+ @SuppressWarnings("unchecked")
+ public <T> Matcher<T> defer(Supplier<Matcher<T>> matcherSupplier) {
+ final List<Object> deferred = new ArrayList<>();
+
+ return new BaseMatcher<T>() {
+ {
+ if (ModelFixture.this.deferred == null) {
+ ModelFixture.this.deferred = new ArrayList<>();
+ }
+ ModelFixture.this.deferred.add((Matcher<Object>) this);
+ }
+
+ @Override
+ public void describeMismatch(Object item, org.hamcrest.Description description) {
+ if (deferred.isEmpty()) {
+ description.appendText("Deferred matcher was never asserted: ");
+ describeTo(description);
+ } else {
+ matcherSupplier.get().describeMismatch(deferred.get(0), description);
+ }
+ }
+
+ @Override
+ public void describeTo(org.hamcrest.Description description) {
+ matcherSupplier.get().describeTo(description);
+ }
+
+ @Override
+ public boolean matches(Object item) {
+ if (item == TEST_DEFERRED) {
+ return deferred.stream().anyMatch(matcherSupplier.get()::matches);
+ } else {
+ deferred.add(item);
+ return true;
+ }
+ }
+ };
+ }
+
+ public <T> Matcher<T> defer(Function<T, Matcher<T>> matcher, T expected) {
+ return defer(() -> matcher.apply(expected));
+ }
}

Back to the top