Implementing a structure viewer

A structure merge viewer performs a two-way or three-way compare of its inputs, presents the result in a hierarchical view, and lets the user merge between the inputs.  Structure merge viewers are common for workspace resources or the members of an archive file.

Tree-like structure viewers

Because the implementation of many structure compare viewers is based on a tree, the compare plug-in provides a generic tree-based StructureDiffViewer. Your plug-in is responsible for supplying a structure creator that breaks a single input object into a hierarchical structure. The StructureDiffViewer performs the compare on the resulting structure and displays the result as a tree.

You designate a structure creator for your plug-in using the org.eclipse.compare.structureCreators extension. Much like content viewers, a structure creator can be specified for a set of file extensions, or a contentTypeBinding can be used to associate a content type with a particular structure creator. We won't review the markup here since it's so similar to content viewers. The JDT plug-in defines several contributions for org.eclipse.compare.structureCreators.

Other hierarchical structure viewers

In some cases, the tree-based StructureDiffViewer may not be appropriate for your plug-in.  The org.eclipse.compare.structureMergeViewers extension point allows you to define your own implementation for a structure merge viewer. A structure merge viewer can be specified for file extensions, or a contentTypeBinding can be used to associate a content type with a particular structure merge viewer. See the JDT plug-in for examples of org.eclipse.compare.structureMergeViewers contributions.

Differencer 

Differencer is a differencing engine for hierarchically structured data. It takes two or three inputs and performs a two-way or three-way compare on them.

If the input elements to the differencing engine implement the IStructureComparator interface, the engine recursively applies itself to the children of the input element. Leaf elements must implement the IStreamContentAccessor interface so that the differencer can perform a byte wise comparison on their contents.

There are several good examples of differencers included in the platform implementation:

By default the differencing engine returns the result of the compare operation as a tree of DiffNode objects.  A DiffNode describes the changes among two or three inputs.  The type of result nodes can be changed by overriding a single method of the engine.

Difference Viewers

A tree of DiffNodes can be displayed in a DiffTreeViewer. The DiffTreeViewer requires that inner nodes of the tree implement the IDiffContainer interface and leaves implement the IDiffElement interface.

The typical steps to compare hierarchically structured data and to display the differences are as follows:

  1. Map the input data into a tree of objects implementing both the IStructureComparator and IStreamContentAccessor interfaces
  2. Perform the compare operation by means of the Differencer
  3. Feed the differencing result into the DiffTreeViewer

The StructureDiffViewer is a specialized DiffTreeViewer that automates the three steps from above. It takes a single input object of type ICompareInput from which it retrieves the two or three input elements to compare.  It uses an IStructureCreator to extract a tree containing IStructureComparator and IStreamContentAccessor objects from them.  These trees are then compared with the differencing engine and the result is displayed in the tree viewer.

The ZipFileStructureCreator is an implementation of the IStructureCreator interface and makes the contents of a zip archive available as a hierarchical structure of IStructureComparators which can be easily compared by the differencing engine (Differencer). It is a good example for how to make structured files available to the hierarchical compare functionality of the compare plug-in.

For text based inputs, clients should subclass the StructureCreator class. This will enable the use of a shared document between multiple editors open on the same file. Subclasses of StructureCreator that provide syntax highlighting must implement both the getDocumentPartitioner() and getDocumentPartitioning90 methods to support shared documents.