Implementing a content viewer
The compare plug-in allows you to supply specialized viewers for viewing and
merging content differences between unstructured elements.
Simple content viewers
A content viewer is used in places where only a single input is available and therefore
no compare is necessary. A typical example for this is the "Restore from Local
History" function. The
org.eclipse.compare.contentViewers
extension point allows you to define a specialized content viewer that does not
compare its inputs.
<extension
point="org.eclipse.compare.contentViewers">
<viewer
extensions="java,java2"
class="org.eclipse.jdt.internal.ui.compare.JavaTextViewerCreator"
id="org.eclipse.jdt.internal.ui.compare.JavaTextViewerCreator">
</viewer>
<contentTypeBinding
contentTypeId="org.eclipse.jdt.core.javaSource"
contentViewerId="org.eclipse.jdt.internal.ui.compare.JavaTextViewerCreator">
</contentTypeBinding>
</extension>
Specialized viewers contributed by your plug-in are designated in the
viewer element. You must specify the id of the viewer and the class that
creates it. You may also specify any file extensions for which the content viewer should be used.
You may also use the contentTypeBinding element to associate a
content type
with a content viewer.
Content merge viewers
A content merge viewer performs a two-way or three-way compare of its inputs
and presents the result side-by-side or in any other suitable way. The viewer lets the user
merge between the inputs. Content merge viewers are common for text or images.
If the standard merge viewers are not appropriate for your plug-in's
function, you may choose to implement your own content merge viewer. Your
content merge viewer should be registered with the platform using the
org.eclipse.compare.contentMergeViewers
extension point. The following markup shows
the definition of specialized content merge viewers for viewing Java files and
properties files in the Java IDE:
<extension
point="org.eclipse.compare.contentMergeViewers">
<viewer
extensions="java,java2"
class="org.eclipse.jdt.internal.ui.compare.JavaContentViewerCreator"
id="org.eclipse.jdt.internal.ui.compare.JavaContentViewerCreator">
</viewer>
<contentTypeBinding
contentTypeId="org.eclipse.jdt.core.javaSource"
contentMergeViewerId="org.eclipse.jdt.internal.ui.compare.JavaContentViewerCreator">
</contentTypeBinding>
</extension>
<extension
point="org.eclipse.compare.contentMergeViewers">
<viewer
extensions="properties,properties2"
class="org.eclipse.jdt.internal.ui.compare.PropertiesFileMergeViewerCreator"
id="org.eclipse.jdt.internal.ui.compare.PropertiesFileMergeViewerCreator">
</viewer>
<contentTypeBinding
contentTypeId="org.eclipse.jdt.core.javaProperties"
contentMergeViewerId="org.eclipse.jdt.internal.ui.compare.PropertiesFileMergeViewerCreator">
</contentTypeBinding>
</extension>
Similar to content viewers, specialized merge viewers contributed by your plug-in are designated in the
viewer element. You must specify the id of the viewer and the class that
creates it. You may also specify any file extensions for which the content merge viewer should be used.
Also similar to content viewers, you can use contentTypeBinding to associate a
content type
with a merge viewer. The JDT plug-in binds content merge viewers to two different content types: Java source and Java properties files.
ContentMergeViewer
is an abstract compare and merge viewer
with two side-by-side content areas and an optional content area for a
common ancestor (for three-way compare). Because the implementation makes
no assumptions about the content type, the subclass is responsible for dealing
with the specific content type.
ImageMergeViewer in org.eclipse.compare.internal shows how to
implement a simple merge viewer for images using a
ContentMergeViewer.
A
ContentMergeViewer
accesses its model by means of a content
provider which must implement the
IMergeViewerContentProvider interface.
If your viewer uses text, additional classes that compare
and merge text content can be used.
TextMergeViewer
is the concrete subclass of
ContentMergeViewer
used for comparing and merging text content. A text merge viewer uses the
RangeDifferencer
to perform a textual, line-by-line comparison of two (or three) input documents.
For text lines that differ, the
TextMergeViewer
uses an
ITokenComparator
to find the longest sequences of matching and non-matching tokens.
The
TextMergeViewer's
default token compare works on characters separated by white space. If a
different strategy is needed (for example, Java tokens in a Java-aware
merge viewer), clients can create their own token comparators by implementing
the
ITokenComparator
interface.
TextMergeViewer
works on whole documents and on sub ranges of documents. For partial documents,
the viewer's input must adapt to an
IDocumentRange
instead of an
IDocument.
The
TextMergeViewer also
supports the use of a shared document (i.e. document's that are shared by multiple open editors) when the input adapts to an
ISharedDocumentAdapter. Subclasses of
TextMergeViewer that provide syntax highlighting must implement both the getDocumentPartitioner()
and
getDocumentPartitioning()
methods to support shared documents.
Range differencing
RangeDifferencer
finds the longest sequences of matching and
non-matching comparable entities in text content. Its implementation is based on
an objectified version of the algorithm by Eugene W. Myers found
here.
Clients must supply
an input to the differencer that implements the
IRangeComparator
interface.
IRangeComparator
breaks the input data into a sequence
of entities and provides a method for comparing
one entity with the entity in another
IRangeComparator.
For example, to compare two text documents and find the longest common
sequences of matching and non-matching lines,
the implementation of
IRangeComparator
must break the document into lines and provide a method for testing
whether two lines are considered equal.
See org.eclipse.compare.internal.DocLineComparator for an example of how this can be done.
The differencer returns the differences among these sequences as an
array of
RangeDifference
objects.
Every single
RangeDifference
describes the kind of difference
(no change, change, addition, deletion) and the corresponding ranges
of the underlying comparable entities in the two or three inputs.