The ElementTypesConfigurations Framework provides model-based facilities to define high-level constructs on top of an EMF metamodels based on the GMF Extensible Type Registry. Indeed, EMF generates CRUD-like facilities to manipulate the underlying data structure of the metamodel. However, this low-level facilities are not always adequate or efficient to handle high-level model editing. The ElementTypesConfigurations Framework is a registry in which you can register new application specific constructs that you’ll be able to request for high level commands like relationship reorienting, complex pattern creation...
For instance, in the context of the UML metamodel, if you have a
UML::Association between two
UML::Class Class1
and Class2
and you want to reorient the
Association from Class2
to another existing
UML::Class Class3
, there are many model modifications to do. The property p2:Class2
must be moved to Class3
(if it is "owned by classifier") and the type of this
UML::Property must be changed to Class3
. In this example, an
ElementTypeConfiguration called "UML::Association" can be defined to always build the complex command containing the upper-mentioned atomic model modifications whenever a reorient request is done.
This framework being based on GMF ElementTypeRegistry, the reader may refer to GMF “Developer's Guide to the Extensible Type Registry” for details about the GMF ElementTypeRegistry.
There are various high-level requests already provided by Papyrus. All of them must implement org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest
and should extend org.eclipse.gmf.runtime.emf.type.core.requests.AbstractEditCommandRequest
.
The following requests are dedicated to EMF-based model editing:
In addition to those, Papyrus proposes requests dedicated to UML:
To define new
ElementTypeConfiguration, a model conforming to the
http://www.eclipse.org/papyrus/infra/elementtypesconfigurations/1.1
metamodel (defined in org.eclipse.papyrus.infra.types
) must be created.
At the root of this model, an
ElementTypeSetConfiguration must be created. The
ElementTypeSetConfiguration must have a unique
identifier and a
name (it is a display name). It must also specify the
NsURI of the metamodel it contributes 'ElementTypeConfiguration'' to.
The
ElementTypesConfigurations can be of two types:
MetamodelTypeConfiguration and
SpecializationTypeConfiguration. In both case, it may have a
hint and a
kind. So far this
kind must be left to its default value (namely org.eclipse.gmf.runtime.emf.type.core.IHintedType
). The
hint (also known as
Semantic Hint) is an optional identifier that may be used by a viewprovider (org.eclipse.gmf.runtime.diagram.core.providers.IViewProvider
). The diagrams implemented in Papyrus are providing views for particular hints so that if you are defining your own ElementTypeConfiguration and want it to be viewable in an existing Papyrus diagram, you must align the value of the hint with the one provided by the target diagram.
The
MetamodelTypeConfigurations can reference an
EClass in the EMF metamodel. The
MetamodelTypeConfigurations defines the base editing command for these elements. The command is implemented by an
EditHelper class that must extend org.eclipse.papyrus.infra.gmfdiag.common.helper.DefaultEditHelper
and should be referenced using the
editHelperClassName attribute.
If multiple MetamodelTypeConfiguration based on the same EClass must provide different base command, multiple ClientContext must be defined. ClientContext are used to group definitions from different ElementTypeSetConfiguration in consistent partition in the registry of ElementTypeConfiguration. There must be maximum one MetamodelTypeConfiguration for a single EClass in a given ClientContext. All model elements of the same EClass and ClientContext have the same MetamodelTypeConfiguration.
SpecializationTypeConfiguration are used to extend the base editing command provided by a
MetamodelTypeConfiguration. A
SpecializationTypeConfiguration must specialize at least one
ElementType. The definition of the specialized
ElementType is done using the
specializedTypes attribute. If multiple
SpecializationTypeConfiguration specialize a
MetamodelTypeConfiguration, they may be distinguished using a
MatcherConfiguration. Note that to create an
ElementTypeConfiguration that has no
EClass (e.g. an
EReference in the metamodel), the org.eclipse.gmf.runtime.emf.type.core.NullElementType
(whose identifier is org.eclipse.gmf.runtime.emf.type.core.null
)
ElementType should be specialized.
SpecializationTypeConfiguration may have an AdviceEditHelper bound to them directly to extend the base editing command with Advice.
Advice are used to define pre and post actions to the base editing command. When an edit is performed on a model element, advices from all of the specializations that match that object is contributed to the command. To force the execution order of the advices bound to an ElementTypeConfiguration, the before and after attributes may be used by an advice to refer to the advices that must be executed before or after this itself.
Using
AdviceBindingConfiguration, additional advices can be defined in an
ElementTypeSetConfiguration' and bound to the ElementTypeConfiguration'' of that
ElementTypeSetConfiguration. If the
target of the
AdviceBindingConfiguration is not defined, the advice will be bound to all
ElementType in the clientcontext.
The advice is implemented by an EditHelperAdvice
class that must extend org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice
and should be referenced using the
editHelperAdviceClassName attribute.
The
inheritance parameter is used to define if the advice applies only to the target
ElementType (
none) or to the target
ElementType and its specializations (
all).
The computation of the command from a request by the
EditHelper is mainly defined in org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelper
. Note that org.eclipse.papyrus.infra.gmfdiag.common.helper.DefaultEditHelper
indirectly extends org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelper
.
InsteadCommand
).
To provide the base edit commands corresponding to the various requests, an
EditHelper class that extends org.eclipse.papyrus.infra.gmfdiag.common.helper.DefaultEditHelper
must override the method corresponding to the type of request to handle. For example, if the domain-specific concept must handle the creation relationship with a custom editing behavior, the corresponding request type is org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest
and therefore the method to override is ICommand getCreateRelationshipCommand(CreateRelationshipRequest req)
.
To disapprove an editing request, boolean approveRequest(IEditCommandRequest request)
method may be overridden.
To configure the request, void configureRequest(IEditCommandRequest request)
method may be overridden.
Papyrus adds high-level requests dedicated to UML. To handle those requests, org.eclipse.papyrus.uml.types.core.edithelper.DefaultUMLEditHelper
should be extended. The methods corresponding to the type of requests to handle can be overridden to provide specific base edit behavior. For instance, to handle the application of a Stereotype, ICommand getApplyStereotypeCommand(ApplyStereotypeRequest req)
must be overridden.
To add pre or post edit commands to the base command for the various requests, an
EditHelperAdvice class that extends org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice
must override the method corresponding to the type of request to handle. For example, if the advice must add a specific editing behavior after the creation relationship, the corresponding request type is org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest
and therefore the method to override is ICommand getAfterCreateRelationshipCommand(CreateRelationshipRequest request)
.
To disapprove an editing request, boolean approveRequest(IEditCommandRequest request)
method may be overridden.
To configure the request, void configureRequest(IEditCommandRequest request)
method may be overridden.
Papyrus adds high-level requests dedicated to UML. To handle those requests, org.eclipse.papyrus.uml.types.core.edithelper.DefaultUMLEditHelperAdvice
should be extended.
Use the org.eclipse.papyrus.infra.types.core.elementTypeSetConfiguration
extensionpoint to register an
ElementTypeSetConfiguration and bind its content to a
ClientContext.
If the definition of the ElementTypeConfiguration, AdviceConfiguration, ContainerConfiguration or MatcherConfiguration starts to be repetitive because, for instance, the same implementation of an IEditHelperAdvice is reused systematically, the ElementTypeConfiguration Framework can be extended to add new predefined ElementTypeConfiguration, AdviceConfiguration, ContainerConfiguration or MatcherConfiguration kinds.
For that, an extension of the
http://www.eclipse.org/papyrus/infra/elementtypesconfigurations/1.1
metamodel can be created and used in combination with the org.eclipse.papyrus.infra.types.core.elementTypeConfigurationKind
, org.eclipse.papyrus.infra.types.core.adviceConfigurationKind
, org.eclipse.papyrus.infra.types.core.containerConfigurationKind
and org.eclipse.papyrus.infra.types.core.matcherConfigurationKind
extensionpoints.
The approach is always the same:
org.eclipse.papyrus.infra.types.ElementTypeConfiguration
, org.eclipse.papyrus.infra.types.AdviceConfiguration
, org.eclipse.papyrus.infra.types.MatcherConfiguration
or org.eclipse.papyrus.infra.types.ContainerConfiguration
metaclass. The metamodel extension must use the EMF "Child Creation Extenders" mechanism to appear in the ElementTypeConfigration model editor. org.eclipse.papyrus.infra.types.core.factories.IElementTypeConfigurationFactory
, org.eclipse.papyrus.infra.types.core.factories.IEditHelperAdviceFactory
, org.eclipse.papyrus.infra.types.core.factories.IContainerFactory
or org.eclipse.papyrus.infra.types.core.factories.IMatcherFactory
) that will predefine the interpretation of this specialization. Developers may have a look at the org.eclipse.papyrus.infra.types.rulebased
or org.eclipse.papyrus.uml.types.core
plugins that use this extension mechanism to predefine
ElementTypesConfiguration or
AdviceConfiguration kinds.
For example, the org.eclipse.papyrus.uml.types.core
plugin introduces the org.eclipse.papyrus.uml.types.core.advices.applystereotype.ApplyStereotypeAdviceConfiguration
metaclass that extends the org.eclipse.papyrus.types.AbstractAdviceBindingConfiguration
metaclass. This specialization adds attributes to define at a model level the stereotypes to apply to the UML element created by the ElementType bound to this new special kind of advice. The org.eclipse.papyrus.uml.types.core.advices.applystereotype.ApplyStereotypeAdviceConfigurationFactory
forces the implementation of the
EditHelperAdvice to be org.eclipse.papyrus.uml.types.core.advices.applystereotype.ApplyStereotypeAdviceEditHelperAdvice
. This later
EditHelperAdvice provides the model interpretation for the ApplyStereotypeAdviceConfiguration
metamodel extension.
To assist the definition and the development of
ElementTypes and
Advice, the ElementTypeConfiguration Framework provides two developer views (available in the org.eclipse.papyrus.dev.types
plugin).
Explore the ElementTypeRegistry using the "Registered ElementTypes View". Use the dropdown menu to select the ClientContext to explore. Select the ElementType to explore in the left hand side tree viewer (the child/parent relationship in this tree illustrates the specialization relationship). On the right hand side, details on the selected ElementType are given. Notably, the Advice that are bound to the selected ElementType are listed and sorted (execution order of advices).
This view works only if the debug option is enabled (-debug
in the program arguments).
This view traces the notifications from the
ElementType and
Advice while editing. It notably helps to trace what request has been sent, what
ElementType and
Advice have been triggered and how those latter replied to the request.