Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: for the plan.

Jump to: navigation, search


< Papyrus-RT‎ | Developer‎ | Design
Revision as of 09:37, 3 April 2017 by Unnamed Poltroon (Talk) (Add demonstration of inheritance of the behaviour state machine of a capsule)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

UML-RT Semantics in Eclipse UML

This document describes the implementation of UML-RT semantics in Papyrus as a customization of the Eclipse UML2 implementation of UML.

Most of the APIs and other code described herein are implemented in a new bundle org.eclipse.papyrusrt.umlrt.uml. Critically, this bundle is designed (and required) to operate in a "pure Java" context, that is, without the Eclipse or any OSGi run-time running. Changes in other bundles are required to integrate these into Papyrus-RT; those will be called out in the text below.

Development of this feature is tracked in bug 467545, with attendant git branches, Gerrit patches, and blocking/related bugs. Builds of the feature branch are produced here. Use caution when trying these builds! Do not use them on models that you care about without adequate backup. There are bugs, particularly in undo/redo, which usually is intended to provide a safeguard.

Demonstrative videos are posted from time to time on YouTube:

Demo videos
The following videos demonstrate work in progress and may not represent the current capabilities or features of a Papyrus-RT release.

Incremental Redefinition

The key concept in UML-RT that distinguishes it, besides the profile, from UML is the notion of incremental redefinition. This recognizes that a redefining element can leave some of its attributes unset so that they shall be interpreted as being inherited from the redefined element. This is accomplished by means of subclasses of the UML2 implementation classes for the various redefinable elements. These implement an internal interface InternalUMLRTElement that defines various operations for inheriting values of unset features from the redefined element, setting the redefined element, and more. The custom implementation classes use these common internal APIs to override the basic UML features inherited from Eclipse UML2.

UML-RT Implementation Classes

These custom implementation classes also override the methods implementing standard UML well-formedness constraints to account for UML-RT requirements, especially for type compatibility in protocols, connector ends, etc.

Stand-alone Configuration

For configuration of a ResourceSet to work with UML-RT models, a static utility class UMLRTResourcesUtil is provided as an analogue to UMLResourcesUtil from the UML2 API (the former actually uses the latter for core UML set-up). The init(ResourceSet) API performs all of the registrations required to install the UML-RT support described in this document in a resource set.

UML Extensions

When a generalization relationship is established between capsules or protocols, or a redefinition relationship between state machines, then inheritance of elements is activated that is managed in part by extensions to the UML metamodel. These essentially are structural features of model elements that are stored in separate companion objects (extensions) made accessible through the elements, themselves. So, in a sense they are like features that may be added to metaclasses by package merge, only there is no actual merge; but in practice they are much more like stereotypes, except that they are more deeply integrated into the elements by way of the custom implementation classes.

The extensions are modelled as a metamodel umlext with metaclasses that mirror the extended metaclasses in name and generalization relationships. One important use case for the extensions is to store implicit redefinitions of inherited elements for the cases where they are neither excluded nor configured differently in any attribute as compared to the inherited element. These implicit redefinitions are stored in extension attributes as depicted in the diagram below. The implementation classes, for example ClassRTImpl, are instrumented to forward access to these features via Ecore reflection to the extension object. This makes it possible, for example, to extend the ownedMember superset in the ClassRTImpl to include the implicitAttribute and implicitConnector properties. This ripples to other derived unions such as ownedElement and feature.

UML Extensions

The extension elements are stored in a special resource maintained in the resource set, called the extension extent. This resource, therefore, indirectly contains any "virtual elements" that are these implicit members or other model content. It also maintains an adapter on every element contained within it that, when some concrete change is made to it (thus effecting an incremental redefinition of some inherited element), reifies the object by moving it and any stereotype applications it may have into the user model (in the appropriate containment reference, of course).

Extensions thus far are used only to define containment references for the distinct "shadow" elements representing the local view of an element inherited by some namespace. These typically are named implicitXyz (e.g., implicitPort) and are added to the Namespace::ownedMember superset as a non-standard subset, for access via the Eclipse UML2 UML API. They are in addition to queries such as Namespace::inheritedMember() and further supersets such as Namespace::member which account for inheritance by presenting the same definitions of elements in the supertype.

Extensions are not used for inheritable containment references such as MultiplicityElement::lowerValue and Connector::end. These are handled by customized setting/list implementations (InheritableSetting and InheritableEList, respectively) that take care of presenting "shadows" of inherited elements in the unset state and automatically reifying the contained elements when they are modified to effect redefinition. By implementing this inheritance in the unset state, the serialization of a model is assured never to contain an element in such a reference unless it is a redefinition. And, as these are not typically RedefinableElements according to the UML metamodel, their traceability to the elements that they redefine is implied by the reference in which they are contained (e.g., lower or upper value of a multiplicity element) and position (in case of a reference collection). Furthermore, in the case of an inheritable reference collection such as Connector::end or Operation::ownedParameter, if any element is redefined and thus requires it to be persisted (making the containment reference "set" as compared to "unset"), then all elements in the collection are persisted and are, effectively, redefinitions of the inherited elements. This is unavoidable owing to the significance of ordering in these collections.

For containment references such as StructuredClassifier::ownedAttribute or Region::subvertex that have corresponding extensions, their usual accessor methods in the Java API (e.g., StructuredClassifier.getOwnedAttributes() or Region.getSubvertices() method) will not include in their result lists any of the virtual redefinitions contained in the extensions. Nor, for consistency and safety in the EMF run-time, does the Ecore reflective access to these references. For access to the virtual redefinitions in a generic fashion, clients may use some variant of the UMLRTExtensionUtil.getUMLRTContents(...) API, which automatically includes extension references corresponding to the references requested by the caller. So, it is safe to use in all cases, with any EReference feature, whether it is extended or not.

Deviations from UML

Clearly, none of these extension and inheritance semantics can be implemented without significant deviations from the standard structure of the UML metamodel, especially as is encoded in its Ecore representation for the benefit of the EMF Run-time and applications such as EMF Compare that, to a large extent, are generic and driven by the Ecore metadata.

Although the customized UML implementation classes for UML-RT can change the outward behaviour of the API, they cannot (reasonably) change the Ecore metadata describing that API to EMF-based applications. The two most obvious deviations of the API's behaviour from what applications would expect according to the Ecore metadata are of two kinds:

  • features presenting "unsettable" semantics that in the Ecore are declared as not unsettable. This somewhat confusing nomenclature in Ecore just indicates whether a feature has a discrete "unset" state in addition to its value
  • references, especially containments, appearing to have EObject values even in the unset state (default values for EReferences are not supported by EMF)

Both of these semantic deviations are in support of inheritance: properties of an element that can be inherited from the element that it redefines (according to UML-RT incremental inheritance) must behave as though unsettable, so that the unset state can inherit the value and the set state can override it. And containment references such as MultiplicityElement::lowerValue and Connector::end must be able to present the inherited values in their unset state.

The EMF Run-time is generally well-behaved in the face of these deviations, including the ChangeRecorder that is used for automatic undo/redo of model edits. It is not concerned about receiving UNSET notifications or notifications with isSetChange from features that are not declared as unsettable; it just faithfully records set-state changes and performs eUnset() as appropriate on apply. Likewise for notifications received from extension features: they are handled correctly despite not actually being features of the notifier's EClass.

In general, applications that process notifications should behave as expected if they do not make any assumptions about the kinds of notifications that they will received based on the Ecore metadata. Applications that are primarily driven by the Ecore metadata (for more than just reacting to notifications) may have to make adjustments to account for UML-RT models if they do not just treat all features as though they were unsettable (which, in fact, is generally advisable as it does not lead to contradictions or erroneous behaviour in most cases anyways).

Relation to the UML-RT Profile

These extensions are modelled to capture primarily the implicit redefinitions of inherited elements that provide distinct objects in the model for "purely inherited" elements. This allows, for example, the Papyrus-RT editor UI to present objects with distinct identities in the Model Explorer and the diagrams to represent the same element inherited by multiple different namespaces. By actually having distinct objects, any change to one of them made by the UI or some third-party plug-in automatically converts that "virtual element" in the extension domain to a "real element" in the UML model, that redefines the inherited element in the normal UML fashion.

This is the only purpose for which it is anticipated that the extensions capability will be employed. The primary model extension mechanism in UML is the profile, in the case of Papyrus-RT the UML-RT Profile. What this custom extension capability provides is a kind of extension that profiles cannot model: expansion of property supersets to include additional properties not defined by the UML metamodel. A stereotype may define properties of various kinds, but it cannot define a composite property of any UML metaclass type (UML elements must only be owned by other UML elements), and it most certainly cannot add such a property to a derived union of other superset of the UML metaclass that it extends.

The expansion of supersets, primarily Namespace::ownedMember, to include properties defined in the extension metamodel affords some convenient properties if done carefully. A particularly good example is in the well-formedness constraints for the Connector metaclass. A connector must only connect roles of the Class that owns it. In Papyrus-RT, an inherited connector, implemented as a "virtual element" in the extension of the class, automatically resolves inherited references to connected roles and parts-with-port to the redefinitions of those roles and parts-with-port in the context of the class that owns it. Those roles and parts-with-port may, themselves, be virtual elements that shadow elements inherited from an ancestor class. Because the class's ownedMember superset is expanded to include the <implicitAttribute> property of its extension, these virtual elements are included in the member superset and its derived subset feature and that subset's further derived subset role. The connector constraint is defined in terms of this role property of its owning class, so the constraint is satisfied without any need to override its specification.

UML Extension Example

The image above illustrates the inheritance of a connector by the Capsule2 class: the virtual connector element is contained in its implicitConnector collection and it owns virtual ends that inherit the roles and parts-with-port from the Capsule1 connector in the model (the dotted arrows indicate implied redefinitions; UML connector ends are not redefinable elements). So, these ends inherit references to the port and part in the UML model, but resolve them at run-time to the virtual port and part in the extension. Thus, all roles connected by the virtual connector are properly roles of the Capsule2 that owns it (by extension).

As the UML-RT profile evolves, the kinds of changes that may have to be made in the extension metamodel to accommodate it are generally in the addition of these implicitXyz properties in the extension metaclasses, as follows. Given a property (usually a composite aggregation) in the UML metamodel that can contain redefinitions of inherited elements, a corresponding extension property for implicit redefinitions should:

  • be modelled in a metaclass corresponding to the extended UML metaclass. These are given the same name as the UML metaclass in the uml-ext.uml model because the EMF generator model prepends an Ext prefix to the generated Java API names to distinguish them. If the appropriate metaclass is not already defined in the uml-ext then it must be added. And then, where appropriate, generalizations between these metaclasses mirroring the UML structure. So, for example, the extension metamodel has ClassEncapsulatedClassifierStructuredClassifier as in UML to define the implicitOperation, implicitPort, and implicit{Attribute,Connector} properties with implicitPort being a derived subset of implicitAttribute as in UML. So, the extension object of an UML element is always an instance of the correspondingly named extension metaclass for the UML metaclass, even if it wouldn't otherwise define any extension features.
  • added to the most appropriate superset of the UML metaclass, usually Namespace::ownedMember if applicable. If there is no suitable superset, then it may not be feasible to add the extension, but there should usually at least be Element::ownedElement as an option. This requires overriding the superset property's accessor in the XyzRTImpl Java class to create aDerivedUnionEObjectEListExt that properly accounts for extension properties as subsets

Façade API

The org.eclipse.papyrusrt.umlrt.uml package contains a suite of classes that provide a façade API exposing the UML-RT model structure in a friendly way, primarily targeted to extenders but also used by the Papyrus-RT UI, especially the Properties View. The façade is a UML2-generated metamodel that supports many of the services of the EMF run-time and, therefore, various other EMF-based technologies and integrations. Instances of the façade classes correspond one-to-one with the core element of the UML representation of each UML-RT concept; this association is maintained by means of an EMF Adapter attached to the UML element.

This adapter provides the necessary coördination of the façade structure with the UML model as the latter changes with the user's edits and also maintains the UML extensions of model elements, including virtual redefinitions where necessary, amongst potentially other content.

The initial prototype of the façade API consists of these classes:

  • UMLRTModel — corresponds to a Resource in the editor's ModelSet
  • UMLRTPackage — corresponds to a Package, including the root Model, that is not a «protocolContainer» package
  • UMLRTCapsule — corresponds to a Class stereotyped as «capsule»
  • UMLRTPort — corresponds to a Port stereotyped as «rtPort»
  • UMLRTCapsulePart — properties of a capsule stereotyped as «capsulePart»
  • UMLRTConnector — a Connector in a capsule that is stereotyped as «rtConnector»
  • UMLRTProtocol — a Collaboration stereotyped as «protocol». For each protocol façade there is a corresponding conjugate that follows the naming convention and presents its messages as being of the conjugate direction kind. The conjugate protocol façade is the type of a conjugate port façade
  • UMLRTProtocolMessage — an Operation of in/out/inout direction as determined by the «rtMessageSet» Interface that defines it. The parameters of a message are exposed as the UML API because a façade would provide no significant value

The façades provide direct access to and modification of the most important properties of their UML-RT concepts. For example, names of elements, types of ports (as UMLRTProtocols), etc. The UMLRTCapsule maintains a single list of UMLRTPorts that synthesizes regular owned ports, redefining ports, virtual redefining ports (from the UML extension), and excluded ports. Other details can be obtained from the corresponding UML model element, which each façade object provides via a toUML() operation. Notification of changes is not supported; this must be done at the UML level.

The UMLRT prefix is applied to these façade class names to distinguish them clearly from the similarly named Java interfaces in the UML-RT Profile, e.g. Capsule, Protocol, CapsulePart, RTPort. Although it is not strictly necessary (the names are distinguished by their package namespace, anyways), it is convenient for readability of code to see at a glance that it is working in UML-RT terms, not UML terms, especially in sophisticated Papyrus-RT plug-ins and derived DSMLs that mix both APIs together.

Façade Metamodel

Although the façade is a complete and self-consistent EMF-based metamodel, there are still limitations as compared to, for example, the UML metamodel, including:

  • all features of the façade metaclasses are derived, being computed on demand from the underlying UML model; the façade objects are wrappers for the UML
  • as such, there is no support for serialization (persistence) of façade instances. They are persisted as a UML model only
  • however, many of these derived features in the façade do notify, which makes them suitable for triggering updates in the UI and such, but not for undo/redo, because all edits are actually performed on the UML model anyways and the façade is not maintained in any resource (and so not in the resource set and the editing domain that controls it). The features that support notification are the ones that seem most like the “structural” properties that one would edit and present in the UI. See below for a complete list
  • direct creation of the façade objects via the static generated EFactory is not supported. In fact, there is experimental support for caching of façade instances by soft reference, to let the garbage collector purge them under memory pressure. This is not enabled by default, but the JUnit launch configurations enable it for testing until we see how it shakes out in practice. To enable it in your own run-time workbench launch configurations, add the following to the VM arguments:

Relation to the UML-RT Profile

Most of the façade elements encapsulate a UML element and its canonical UML-RT stereotype application together, for example, a Class and its Capsule application, although some UML-RT concepts do not have these stereotypes, for example protocol messages or even packages as containers of capsules or protocols. Moreover, some UML elements that are important to the UML-RT structure are not surfaced in the façade API as distinct elements, such as message-set interfaces. The UMLRTProtocolMessage façade object infers its direction kind from the message set that contains it in the UML model.

As the UML-RT profile grows (including, of course, the separate state machines and interactions profiles) the façade API may need changes from time to time to track this evolution. Most commonly the problem is to add a new façade type, which involves:

  • creating a new UMLRTXyz class for the concept, usually extending some existing façade class (UMLRTNamedElement if none more specific)
  • defining its TYPE as a static FacadeType object (analogous to Ecore EClass)
  • defining static FacadeReferences for references to other façade objects (analogous to Ecore EReference)
  • exposing properties either directly from or computed from properties of the underlying UML element, with mutation API as appropriate
  • if necessary, customizing the BasicFacadeAdapter to update façade objects as changes occur in the UML model. This is the adapter that provides the one-to-one-and-onto correspondence between façade objects and the UML elements that they wrap
  • implementing any required resolution of inherited references to redefining elements in the contextual namespace, such as the UMLRTConnector does in its port and part-with-port references. Although, this may be (should be) redundant with the inheritance semantics implemented in the UML-RT metamodel, itself


A partial list of features in the UML-RT façade metamodel that support notification, as of 30 January 2017:

  • Package
    • name
    • nested packages
    • capsules
    • protocols
  • Capsule
    • name
    • superclass
    • ports
    • capsule-parts
    • connectors
  • Port
    • name
    • type and isConjugated
    • replication factor
    • port kind
    • isService, isBehavior, isWired, isPublish
    • isNotification, registration, registrationOverride
  • Capsule Part
    • name
    • type
    • isOptional
    • capsule-part kind
    • replication factor
  • Connector
    • name
    • source and target ports
    • source and target parts-with-port
    • source and target replication factors
  • Protocol
    • name
    • super-type protocol
    • in, out, an in-out messages
  • Protocol Message
    • name
    • parameters

Integration in Papyrus-RT

The UMLRTLanguage class in the org.eclipse.papyrusrt.umlrt.core bundle that plugs into the ILanguageService uses the UMLRTResourcesUtil to install the UML-RT implementation of the UML metamodel in place of the Eclipse UML2 UML implementation in the ModelSet-local package registry. It also bootstraps the UML-RT façade API on the model with its listeners that react to structural changes to keep the UML-RT semantics up-to-date and hooks into the TransactionalEditingDomain to ensure that undo/redo transactions do not interfere with the reification of virtual redefinition elements.

The org.eclipse.papyrusrt.umlrt.tooling.modelexplorer bundle adds a new EMF Facet customization model, Structure.custom, that enhances the Model Explorer presentation to show virtual redefinitions in the UML extension features of their namespaces. This is done by means of a generic GetExtensionFeatureQuery facet-query that takes an extension feature (an EStructuralFeature from the UML Extension metamodel) and retrieves its value from the context object, if that object is one from the UML-RT implementation that supports extension.

Capsule Structure Diagram Inheritance

For the visualization of inherited features in the Capsule Structure Diagrams, I have decided not to use the synchronization framework (org.eclipse.papyrus.infra.sync) introduced in the Papyrus Mars release. Prototyping work with this framework showed that it is simply too unwieldy, prone to failure of undo/redo, and that it is in large part obviated by work done in bug 467545 on an implementation of UML-RT semantics in the UML metamodel. So, inheritance in the diagrams is implemented by means of a coördination of GEF edit policies:

  • Canonical Edit Policy: the Papyrus-RT semantic and visual children strategies use the UML-RT façade API to find and return inherited elements
  • Inheritance Edit Policy: (NEW) manages optional tracking of the visuals of the inherited elements from the capsule structure diagram in which they are defined
  • Applied Stereotype Comment Edit Policy: specialized in Papyrus-RT to omit the comment view for inherited elements

In the Capsule Structure Diagram, all views of inherited elements reference the root definition as the semantic element, regardless of whether it is an inherited element (which is not attached to the model resource and so would break the serialization) or even a redefinition (which is a real, distinct element in the UML model). The edit-parts override the IGraphicalEditPart::resolveSemanticElement() and IAdaptable::getAdapter() APIs to resolve their notation view's reference to the appropriate redefinition or virtual "shadow" element in the local namespace for inherited elements. This ensures that UI components such as the Properties View that correctly use these APIs to get the semantic element (not simply assuming that it is the notation view's element reference) will get the correct EObject to present, so that any edits made on it will automatically trigger redefinition. However, there are many Papyrus edit-policies and other classes that do not resolve the semantic element correctly via the edit-part, which have to be overridden in Papyrus-RT to do so.

Properties View

The Papyrus-RT contributions to the Properties View are to a large extent built on the façade API, via JFace Data Bindings observable properties tailored to the façades. The org.eclipse.papyrusrt.umlrt.tooling.ui.databinding.facade has a suite of factory classes providing IFacadeProperty instances that are specialized implementations of observable data-binding properties for the façades:

  • CapsuleProperties: observable list properties for ports, capsule-parts, and connectors
  • ProtocolProperties: observable list properties for each direction-kind of protocol messages
  • NamedElementProperties: observable value property for the name

The observable lists for containment references provided by these properties support the usual Papyrus UML observable list behaviours, with an extra for inherited elements:

  • addition of new elements
  • destruction of removed elements, if exclusion does not apply
  • attempts to remove inherited or redefining elements are re-directed to exclusion, which preserves the element in the list but as an excluded element

These observables are used by a new FacadeModelElement in the properties view context to provide appropriate UI bindings for a customized multiple reference editor, the InheritableMultipleReferenceEditor. This adds buttons to the list controls for re-inheriting excluded or redefined elements and for filtering the presentation of excluded elements (by default, they are not shown). The FacadeModelElement provides full support for protocol properties via the façade API, obviating the need for the delegation pattern of observables and other details to model-elements for the message-set interfaces in the UMLRTExtModelElement. This latter class is now simplified by the removal of capsule and protocol concerns.

The properties view context/XWT contributions for capsules and protocols are updated to use the FacadeModelElement for their names, ports/parts (of capsules), and protocol messages. Likewise the creation dialog XWT descriptions for capsules and protocols that request only the name in certain UI workflows.

Model Explorer

Inherited elements in capsule (ports, parts, connectors) and protocols (messages) are presented via EMF Facets with reference queries implemented on the Façade API. By default, purely inherited elements are not shown (they are shown in the Properties View), but they can be enabled by an additional facet override in the customization dialog (the UML-RT Structure Inheritance customization). Excluded elements and redefinitions are always shown, with appropriate decorations.

The children of different dispositions are shown in a definite order:

  • Capsule
    • inherited RT ports — if shown, per above, either by redefinition/exclusion or customization to include inherited elements
    • inherited capsule-parts
    • inherited RT connectors
    • locally-defined RT ports — root definitions initially defined by the capsule
    • locally-defined capsule-parts
    • locally-defined RT connectors
    • other ports (non-RT, if applicable)
    • other attributes (that are not capsule-parts)
    • other connectors (non-RT, if applicable)
  • Protocol
    • inherited outgoing messages — if shown, per above, either by redefinition/exclusion or customization to include inherited elements. This ordering matches what was presented in the Properties View since the 0.7.x releases
    • inherited incoming messages
    • inherited in/out messages
    • locally-defined outgoing messages — root definitions initially defined by the protocol
    • locally-defined incoming messages
    • locally-defined in/out messages
    • (there is no provision in UML-RT for operations that are not protocol messages)

Back to the top