Jump to: navigation, search

EMF Compare/New and Noteworthy/2.1.0

EMF Compare 2.0 was a full overhaul of the design, architecture and code of the project. EMF Compare 2.1 comes to fill the functionality gap between 1.3 and 2.0, especially regarding content matching and graphical comparisons.

Content Matching

EMF Compare 2.0 only supported models that presented IDs of some sort : XMI ID, functional ID... 2.1 re-introduces support for other models through a content matching strategy.

By default, EMF Compare will try and match objects through their ID, delegating to the content matcher if none can be found. This can be altered to avoid using identifiers entirely when needed.

Graphical comparison

EMF Compare 1.3 provided basic support for GMF diagram comparisons and difference visualization. This basic implementation was dropped altogether in the 2.0 release as the architecture overhaul made it obsolete.

2.1 re-introduces the graphical comparison with a much more complete support on all aspects : comparison, visualization, merging... Here are a few key points of these enhancements :

Uses the same formalism as the semantic comparison
color, interest areas and place-holders, highlighting on selection.
  • Add node in local:
AddClassA.PNG
  • Delete node in remote:
DeleteFeature2.PNG
  • Conflict example:
Conflict.PNG
Displays one difference at a time (on double-click) but with its context
  • Cascading additions:
ContextNodes.PNG
  • Addition of edges on nodes subject to differences:
ContextEdges.PNG

Conflict detection

The conflict detection has been largely revamped in order to properly detect complex conflicts and pseudo conflicts (identical changes on both sides of the comparison are conflicting, but can be auto-merged... and as such are detected as "pseudo" conflicts). This also allows for much better results with extensions such as the UML or GMF specific supports.

Enhanced UI

The comparison UI has been enhanced to provide a much more precise and intelligible information. Among these improvements, the most notable are :

a number of grouping options
This feature allows you to group differences together in the structural view according to a set predicate. By default, EMF Compare provides three distinct grouping strategies :
EMF Compare Groups Choice.png
  • Default : Do not try and group differences together, display them as they were detected.
EMF Compare Groups Default.png
  • By Kind : Group differences according to their kind (additions, deletions, moves, changes).
EMF Compare Groups Kind.png
  • By Side : Group differences according to their side: left or right and a special group regrouping differences in conflicts with other differences together.
EMF Compare Groups Side.png
a comprehensive set of filters
This feature allows you to filter differences out of the structural view according to a set predicate. By default, EMF Compare provides five distinct filters :
EMF Compare Filters Choice.png
  • Pseudo conflicts differences: Filter out all pseudo conflicts differences(only in 3-way comparison). Enabled by default.
  • Identical elements : Filter out all identical elements (elements with no differences). Enabled by default.
  • Empty Resource Mappings : Filter out all resource mappings with no differences from the view. Enabled by default.
  • Cascading differences : Filter out all differences that are contained under differences (except when in conflict). Enabled by default.
more complete contextual information around the differences
All differences of containment references are now displayed within the same TreeViewer.
Ecore tree compare.png
Uml tree compare.png
background comparisons
All comparisons launched from the UI are now executed as background operations. This will avoid the usual "frozen" Eclipse for long-running comparisons.
Direct edit
Textual differences can now be directly edited in the comparison editor for users that would rather use a mix of the left and right values instead of taking one or the other.

Customizable UI

One of the main limitations of the 1.* stream was its "locked" UI. EMF Compare 2.1 introduces a lot of customization options for the visualization of the differences and model elements.

  • Users can introduce new filters through the org.eclipse.emf.compare.rcp.ui.filters extension point. Filters can be contributed to either hide or show differences given a predicate.
  • New grouping options can be contributed through the org.eclipse.emf.compare.rcp.ui.groups extension point. The groups can be used to group differences together in the "structure" (top half) panel of the comparison UI.
  • Label providers can be contributed to override or extend the behavior of the default EMF label providers through the org.eclipse.emf.compare.rcp.ui.accessorFactory extension point. This can be used to change the way elements are displayed in the compare UI, both in the structure (top half) or content (bottom half) panels of the comparison UI.

Minimized Scope

EMF Compare 2.0 introduced the mandatory architecture and API for the project to handle large input models... Yet only provided a default scope which loaded everything in memory and compared the input models as a whole. 2.1 builds upon these APIs to introduce a scoping mechanism capable of treating model fragments as first-class citizens, minimizing the input logical model to the bare minimal while never loading the whole model in-memory unless all of its fragments have changed.

For example, assuming that we need to compare the three following models :

Origin
EMFC Logic origin.png
Left Right
EMFC Logic left.png
EMFC Logic right.png

Each of the three sides is an EMF model composed of 7 fragments. Origin is the common ancestor of left and right. The blue-colored fragments are those that actually present differences (so D and G have been modified in the "left" copy while only B has been modified in the "right" copy).

In order to compare these three models together, we would normally need to load all 21 fragments in memory. However, with the help of the synchronization model we can narrow it down to the modified fragments only. What we'll really load, then, are the following fragments for each three sides :

EMFC Logic loaded fragments.png

In other words, we are actually only loading 9 fragments out of the initial 21. This amounts to 58% less memory usage if we consider all fragments to be of equal "weight". And this is only for small models; the ratio of saved memory really going up for extremely large models. Of course, all of these objects that we are not loading in memory are all objects that we no longer need to compare, bringing an incredible performance boost along with the memory gain.

API

A number of new APIs have been opened in order to facilitate the programmatic use of EMF Compare and consumption of its output comparison model.

Pretty Printer

The comparison model contains a lot of information, which might be hard to consume or read. 2.1 introduces APIs that will provide more user-friendly descriptions for both differences and matched elements.

For example, here are the results for a given difference :

System.out.println(diff);
ReferenceChangeSpec{reference=EClass.eSuperTypes, value=EClass@3190dc79 TitledItem, parentMatch=MatchSpec{left=EClass@72b398da Book, right=EClass@675926d1 Book, origin=EClass@28d4ff95 Book, #differences=3, #submatches=5}, match of value=MatchSpec{left=<null>, right=EClass@3190dc79 TitledItem, origin=<null>, #differences=1, #submatches=1}, kind=ADD, source=RIGHT, state=UNRESOLVED}
EMFComparePrettyPrinter.printDifference(diff, System.out)
value TitledItem has been remotely added to reference eSuperTypes of object Book

Comparison Configuration

Most aspects of the comparison process can be customized before launching the comparison itself. All customizations can be made in a similar way through the EMFCompare class, they will be described in depth on the Developper guide.

For example, replacing the Match engine would be done through

IMatchEngine customMatchEngine = new MyMatchEngine(...);
EMFCompare.builder().setMatchEngine(customMatchEngine).build().compare(scope);

Or replacing the Diff engine could be done with

IDiffEngine customDiffEngine = new MyDiffEngine(...);
EMFCompare.builder().setDiffEngine(customDiffEngine).build().compare(scope);

Separation of the RCP, IDE and core concepts

EMF Compare 2.1 further enhances the separation of concerns that 2.0 introduced so that the core of the comparison process is all located in a single, fully standalone plugin that does not depend on Eclipse in the least.

Furthermore, all code that does not depend on the IDE has been extracted in "rcp" namespaces, both RCP and RCP UI are in this case, separated themselves in their own isolated plugins.

Mergers extensibility

The mergers have been greatly enhanced since the 1.* stream of EMF Compare, though 2.0 did not allow for easy overriding, replacing or inheriting of the default mergers.

EMF Compare 2.1 solves these concerns by introducing a more flexible merging mechanism, supporting any kind of combination of existing/new/overridden mergers along with a "batch" merging mechanism. Clients can refer to IMerger.Registry for more information on extending the default behavior.

Performance Enhancements

EMF Compare 2.1 introduced a minimized scoping mechanism, which will greatly enhance both the memory footprint and comparison time of all comparisons targetting fragmented models.

Furthermore, both aspects (memory footprint and overall time) have been fully profiled and enhanced for large model comparisons, this makes for a noticeable improvement on all comparisons, whether the input models are fragmented or not.