Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EMF DiffMerge/Co-Evolution/Programmatic Usage"

(Step 5: Test it)
(Step 3: Define a transformation)
 
(One intermediate revision by the same user not shown)
Line 27: Line 27:
 
A model transformation must be defined that takes as input a source data set and an empty trace and produces a corresponding target data set while filling the trace. It should be a simple one-shot (non-incremental) transformation so there is no need to worry about the update mechanism at this stage.
 
A model transformation must be defined that takes as input a source data set and an empty trace and produces a corresponding target data set while filling the trace. It should be a simple one-shot (non-incremental) transformation so there is no need to worry about the update mechanism at this stage.
  
It can be implemented with any (Java-based) technology as long as the technology conforms to, or adapts to, the Co-Evolution APIs (see org.eclipse.emf.diffmerge.bridge.api.IBridge). By default, Co-Evolution includes a '''Mapping''' module that allows implementing transformations as sets of queries and rules without bothering about filling the trace (see org.eclipse.emf.diffmerge.bridge.mapping.impl.MappingBridge). Co-Evolution also integrates the Transposer transformation framework from [https://polarsys.org/kitalpha/ Polarsys Kitalpha]. Other transformation technologies have been experimented with such as [https://www.eclipse.org/xtend/ Xtend].
+
It can be implemented with any (Java-based) technology as long as the technology conforms to, or adapts to, the Co-Evolution APIs (see org.eclipse.emf.diffmerge.bridge.api.IBridge). By default, Co-Evolution includes a [https://wiki.eclipse.org/EMF_DiffMerge/Co-Evolution/Programmatic_Usage/Mapping Mapping] module that allows implementing transformations as sets of queries and rules without bothering about filling the trace (see org.eclipse.emf.diffmerge.bridge.mapping.impl.MappingBridge). Co-Evolution also integrates the Transposer transformation framework from [https://polarsys.org/kitalpha/ Polarsys Kitalpha]. Other transformation technologies have been experimented with such as [https://www.eclipse.org/xtend/ Xtend].
  
 
== Step 4: Make it incremental  ==
 
== Step 4: Make it incremental  ==
Line 50: Line 50:
  
 
For simple usage scenarios based on model files, a subclass of org.eclipse.emf.diffmerge.bridge.interactive.BridgeJob<SourceObjectType> may be defined with the code above in method getBridge(). Then the job can be instantiated with the desired file URIs and finally job.schedule();.
 
For simple usage scenarios based on model files, a subclass of org.eclipse.emf.diffmerge.bridge.interactive.BridgeJob<SourceObjectType> may be defined with the code above in method getBridge(). Then the job can be instantiated with the desired file URIs and finally job.schedule();.
 +
 
Otherwise:
 
Otherwise:
 
<pre>
 
<pre>

Latest revision as of 12:43, 16 November 2017

Principles

Co-Evolution supports implementing 'bridges', i.e., incremental model/data transformations of arbitrary complexity. Its primary goal is to enable engineers of different disciplines, working on the same system in a Model-Based Systems Engineering approach, to discuss and synchronize their (heterogeneous) models during co-engineering sessions within iterative processes.

Step 1: Define what must be synchronized

Co-Evolution classically assumes the existence of two data sets that need to be synchronized. These are arbitrary sets of data elements, for example: an EMF model, a model in some other arbitrary but known format, a subset of a model, or a subset of the union of models. One data set is given the role of source and the other one the role of target. Deviations or inconsistencies between them are expressed as differences on the target side between: a) the target data set as it is now, and b) the target data set as it should be according to the source.

The data sets must comply to the following assumptions.

  • Their data elements can be identified uniquely and consistently through their life cycle. In other words, if an element is identified as E within a data set then there is no ambiguity as to which element of the data set is E. And even though the data set evolves, the identification of the element as E remains.
  • They can be read in Java, and for the target side written in Java, from the same Java Virtual Machine.
  • They are disjoint: no data element belongs to both data sets.

In the case where a data set is only made of EMF model elements, it naturally maps to an EMF Diff/Merge model scope. This is only important for the target side, though: for the source side, any Java Object that allows retrieving the data elements will do, as long as the assumptions above hold.

So in the case of a bridge to an EMF model, what we have in the end is of type:

IBridge<SourceObjectType, IEditableModelScope>

Step 2: Define how elements are traced

The synchronization mechanism requires a persistent trace that relies on the identification mechanism mentioned above. Any implementation that conforms to the expected API can be used (see org.eclipse.emf.diffmerge.bridge.api.IBridgeTrace). However, a default one is provided which supports arbitrarily complex mappings of EMF model elements that have identifiers (ID attributes or XML/XMI IDs assigned via EMF Resource-based persistence).

The most reliable way to ensure traceability of EMF model elements is to use meta-models that define ID attributes (see org.eclipse.emf.ecore.EAttribute#isID()) and org.eclipse.emf.ecore.util.EcoreUtil#generateUUID()). In this situation, the default behavior is probably appropriate so nothing more needs to be done.

Step 3: Define a transformation

A model transformation must be defined that takes as input a source data set and an empty trace and produces a corresponding target data set while filling the trace. It should be a simple one-shot (non-incremental) transformation so there is no need to worry about the update mechanism at this stage.

It can be implemented with any (Java-based) technology as long as the technology conforms to, or adapts to, the Co-Evolution APIs (see org.eclipse.emf.diffmerge.bridge.api.IBridge). By default, Co-Evolution includes a Mapping module that allows implementing transformations as sets of queries and rules without bothering about filling the trace (see org.eclipse.emf.diffmerge.bridge.mapping.impl.MappingBridge). Co-Evolution also integrates the Transposer transformation framework from Polarsys Kitalpha. Other transformation technologies have been experimented with such as Xtend.

Step 4: Make it incremental

Put the one-shot model transformation into a predefined incremental wrapper bridge that makes it incremental (see org.eclipse.emf.diffmerge.bridge.api.incremental.IIncrementalBridge.Wrapping). Configure the wrapper to:

  • Use the desired trace implementation (nothing to be done in the default case).
  • Use the desired update behavior via:
    • A diff policy: what differences are relevant?
    • A merge policy: how to consistently merge the differences?
    • A merge selector: what differences must be automatically handled and how?

In most cases, it is easier to use the default update behavior at first, then refine it by providing explicit policies if needed.

In the case where we want an interactive bridge to an EMF model with an update GUI and the default update behavior (all differences covered, default merge policy preserving meta-model conformance, no automatic handling of differences), the code looks as follows:

IBridge<SourceObjectType, IEditableModelScope> transformation = ...;
EMFInteractiveBridge<SourceObjectType, IEditableModelScope> incrementalBridge = 
    new EMFInteractiveBridge<SourceObjectType, IEditableModelScope>(transformation, null, null, null);

Step 5: Test it

For simple usage scenarios based on model files, a subclass of org.eclipse.emf.diffmerge.bridge.interactive.BridgeJob<SourceObjectType> may be defined with the code above in method getBridge(). Then the job can be instantiated with the desired file URIs and finally job.schedule();.

Otherwise:

SourceObjectType mySourceObject = ...;
IEditableModelScope myTargetScope = ...; // For example: new FragmentedModelScope(myEMFResource, false)
IProgressMonitor myProgressMonitor = ...; // Can be null
IBridgeTrace myPreviousTrace = ...; // Null for first, non-incremental execution; otherwise must be the getTrace()
                                    // of the IBridgeExecution returned by the previous execution
incrementalBridge.executeOn(
    mySourceObject, myTargetScope, null, myPreviousTrace, false, myProgressMonitor);

Back to the top