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:
-
ResourceNode
implements both interfaces
(and more) for platform workspace resources
(
org.eclipse.core.resources.IResource).
-
DocumentRangeNode
is used to compare hierarchical structures
that are superimposed on a document. Nodes and leaves correspond to ranges in a document
(
IDocumentRange).
Typically,
DocumentRangeNodes
are created while parsing a document and they represent
the semantic entities of the document (e.g. a Java class, method or field).
The two subclasses JavaNode (in org.eclipse.jdt.internal.ui.compare)
and PropertyNode (in org.eclipse.jdt.internal.ui.compare) are good examples for this.
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:
-
Map the input data into a tree of objects implementing both the
IStructureComparator
and
IStreamContentAccessor
interfaces
-
Perform the compare operation by means of the
Differencer
-
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.