The specification of certain domains, such as UML, describe a graphical notation. When such notation is implemented using GMF, it can be reused to visualize elements of other domains thanks to the DevOps Modeling Platform Metamodel Integration Framework (MMI) infrastructure. This framework allows the visualization of domain elements from a source domain using views from an unrelated domain, called the target domain. The elements of the domain mapped from are called the source elements and the elements of the domain mapped to are called the target elements.
The MMI Framework allows the creation of a mapping between the source domain and target domain, and keep the source and target models synchronized. The source domain can be either EMF or non-EMF based. The target domain must be EMF based.
As an example, the MMI infrastructure is used by IBM Model RealTime to provide the Java Modeling functionality. The source domain is Eclipse's Java Development Tool (JDT), and the target domain is UML2. This functionality allows Java elements in the Package Explorer to be visualized as UML2 elements in diagrams. A Java class is visualized as a UML2 class. The element of the diagram's notation View representing the class shape references the JDT Java class element. When modifying the Java class using JDT's .java file editor and saving, the changes are reflected in the diagram. Conversely, when a semantic change is applied to the UML Class representation of the Java class using the diagram, the change gets reflected automatically within the Java editor. When using MMI, no UML class element ever gets persisted. UML elements are created on-the-fly for the sole purpose of displaying and synchronizing between the source domain and its cross-domain notation counterpart in a diagram.
Mapping elements from a source domain to a target domain is performed using the
ModelMappingService
,
which requires an MMI domain provider to implement the
IModelMappingProvider
interface.
This domain implementation of IModelMappingProvider must map source elements to target elements by creating target elements in a transient EMF Resource which is never serialized.
Other EMF Resources can reference these target
EObjects
in this transient resource, and can serialize and resolve these references transparently.
Serialization of references to these target elements requires MMI domain providers to implement the
IStructuredReferenceProvider
interface.
The domain implementation of IStructuredReferenceProvider must create
StructuredReference
objects for corresponding source elements.
The process of mapping from a domain element to a target domain element is called adapting. The process of mapping from a structured reference to a target element is known as resolving.
Synchronization of target elements with source elements requires associating the target element
with a structured reference for source element and providing an implementation of
ITargetSynchronizer
associating this target synchronizer with the target element.
Synchronization of source elements with target elements requires implementation of ISourceSynchronizationProvider,
which provides a command to change the domain model corresponding to target element changes.
The objects of a target domain must implement
ITarget
.
The DevOps Modeling Platform provides custom implementation of the UML2 domain to be used as the target domain.
The StructuredReference is a way of representing the domain element in terms of its properties. The StructuredReference for a domain element must contain enough properties to uniquely dereference the source element. For example, if a domain object can be uniquely identified using its name then the StructuredReference for such a domain element must have a name property. However, if the name is not enough information to uniquely identify the source element (perhaps it is possible to have multiple source elements with the same name but having other different properties), the structured reference would need more properties to uniquely dereference the domain element.
A structured reference can have underlying structured references. These additional structured references are useful when one structured reference needs to make reference to another structured reference in order to to be uniquely identified. For example, a structured reference representing a source element may have the element's container as a supporting structured reference. This would allow the primary structured reference to be distinguished from a similar structured reference contained in a different container. These underlying structured references are called supporting structured references. Any primary structured reference can be used as a supporting structured reference for another structured reference.
The
StructuredReferenceService
is used to obtain a StructuredReference object from a domain element
or from a structured reference's string representation, and to resolve a structured reference into a
source domain element.
Providers of the StructuredReferenceService, which implement the IStructuredReferenceProvider interface, are responsible for creating the StructuredReference objects requested by the service and for resolving StructuredReference objects into source domain elements.
Structured references are created using modifiers which are assigned to structured reference providers. Each provider is responsible for the StructuredReferences of one or more types of object, but each type of object can be handled by at most one provider.
Domain elements are mapped to target elements which implement the ITarget interface. ITarget provides methods to synchronize the target domain with the source domain, when the structural features of the target element are accessed. It also provides the ability to mark structural features of the target element as affected when the source domain is modified. Only ITarget objects that have been activated using the activate() method can be synchronized.
Synchronization of target elements with source elements requires activating the target element with a StructuredReference for the source element and providing an implementation of ITargetSynchronizer that associates this target synchronizer with the target element. The synchronizer is responsible for synchronizing the features of the target domain. The method that synchronizes the target feature, synchronizeFeature(), is invoked on features that need to be synchronized when the synchronize() method on the ITarget is invoked. Typically, the synchronization will occur when accessing a feature that has never been synchronized or a feature that has been marked dirty using the setDirty() method.
The ModelMappingService is used to map the source elements or structured references to target elements, which we defined earlier as adapting and resolving, respectively. Implementors of IModelMappingProvider provide the implementation of the adapt() and resolve() methods. The MMI framework allows the flexibility of resolving or adapting to a different target model element based on the EClass. The EClass typically indicates the kind of model element that will be created.
As mentioned earlier, each structured reference provider creates structured references for certain types of source elements. In the same way, each model mapping provider is responsible for mapping certain types of source elements and certain types of structured references. The types of source elements each model mapping provider is responsible for adapting are defined by the source elements' Java classes. The kinds of structured references each model mapping provider is responsible for resolving are defined by the ids of the structured reference providers.
Synchronization of source elements with target elements requires implementation of an
ISourceSynchronizationProvider
.
Individual providers are responsible for generating an
ICommand
from a change set known as a delta. The delta contains information from one or more EMF Notification objects. When executed, the command
makes the changes to update the source element to reflect target element changes.
By default, the SourceSynchronizationService
invokes the corresponding provider's emit() method upon validation and when an EMF transaction is
about to be committed. MMI domain providers are also free to invoke the SourceSynchronizationService's emit() method when necessary.
To use a given Ecore model as a target domain, every object of the target domain must implement ITarget in addition to the EMF EObject interface. The DevOps Modeling Platform provides a custom implementation for UML to be used as the target domain.
Throughout this section, we have referred to source and target domains. The "domain" that we are referring
to here must not be confused with the EMF's
EditingDomain
concept. The TransactionalEditingDomain
,
which extends the EMF's EditingDomain, is an EMFT Transaction concept. In the context of MMI, such an EditingDomain is sometimes referred to as a
referenced context.
A thorough discussion of editing domains is outside the scope of this section. An MMI domain provider can create an editing domain through TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(). The default editing domain used by the UMLVisualizerEditor has the id of org.eclipse.gmf.runtime.emf.core.compatibility.MSLEditingDomain. It can be obtained using the following code.
TransactionalEditingDomain.Registry.INSTANCE.getEditingDomain( "org.eclipse.gmf.runtime.emf.core.compatibility.MSLEditingDomain");