The platform text framework defines a document model for text and provides a viewer that displays text using this model. We will start by looking at the Java editor example and how it uses this model. We will not focus on the basic mechanics of registering an editor extension, since we've already seen this in the section discussing org.eclipse.ui.editors. Instead, we'll look at the specifics of how the editor class is implemented in the example.
In the workbench, an editor is typically opened when the user selects a domain element (such as a file or an element stored inside an archive file) and opens it. When the editor is created, it is associated with an editor input (IEditorInput), which describes the object being edited.
The Java editor example opens when the user opens a file with the "*.jav" extension. In this case, the input to the editor is an IFileEditorInput. The platform text framework assumes little about the editor input itself. It works with a presentation model, called an IDocument, for the input, so that it can effectively display and manipulate text.
This means that there must be a way to map from an expected domain model (the editor input) to the presentation model. This mapping is defined in an IDocumentProvider. Given an editor input, the document provider returns an appropriate IDocument.
The Java editor example defines a JavaDocumentProvider which returns the appropriate document. How is the relationship between the appropriate document provider and the "*.jav" extension established? It's done in the org.eclipse.ui.documentProviders extension. This extension is used to define mappings between file types and document providers. The example defines its document provider as follows:
<extension point="org.eclipse.ui.documentProviders"> <provider extensions="jav" class="org.eclipse.ui.examples.javaeditor.JavaDocumentProvider" id="org.eclipse.ui.examples.javaeditor.JavaDocumentProvider"> </provider> </extension>
When the user opens a file with the specified extension, the workbench manages the details of creating the document provider instance. The workbench creates a document provider instance only once and shares this instance among different editors.
It is not required that your plug-in use this extension point to register its document provider. Another way to associate a document provider with an editor is to let your plug-in itself manage the document provider. This is usually done in your plug-in class. When an input element is set into your editor, the editor asks its plug-in class for the appropriate document provider. The plug-in can manage the creation and the references to the document provider. This technique may be preferable when there is special initialization or other processing involved with the document provider. See ClassFileEditor in the JDT tooling for an example.
Once the proper document provider is associated with an editor, its main task is to create a document from the editor input and configure an appropriate object for dividing the document up into partitions.
Let's look at documents and partitions in the JavaDocumentProvider. When a document is created, an IDocumentPartitioner is created and set into the document.
protected IDocument createDocument(Object element) throws CoreException { IDocument document= super.createDocument(element); if (document != null) { IDocumentPartitioner partitioner= createJavaPartitioner(); document.setDocumentPartitioner(partitioner); partitioner.connect(document); } return document; }
The partitioner is responsible for dividing the document into non-overlapping regions called partitions. Partitions (represented at ITypedRegion) are useful for treating different sections of the document differently with respect to features like syntax highlighting or formatting.
In the case of the Java editor example, the document is divided into partitions that represent the javadoc comments, multi line comments, and everything else. Each region is assigned a content type and its position in the document. Positions are updated as the user edits text.
It is up to each editor to determine the appropriate implementation for a document partitioner. Support is provided in org.eclipse.jface.text.rules for rule-based document scanning. Using a rule-based scanner allows an editor to use the DefaultPartitioner provided by the framework.
private IDocumentPartitioner createJavaPartitioner() { return new DefaultPartitioner(getJavaPartitionScanner(), TYPES); }
RuleBasedPartitionScanner is the superclass for rule based scanners. Subclasses are responsible for enumerating and implementing the rules that should be used to distinguish tokens such as line delimiters, white space, and generic patterns when scanning a document. The example's JavaPartitionScanner defines rules for distinguishing single line comments, character constants, javadoc, multi line comments, and words. This is done in the scanner's constructor:
public JavaPartitionScanner() { super(); IToken javaDoc= new Token(JAVA_DOC); IToken comment= new Token(JAVA_MULTILINE_COMMENT); List rules= new ArrayList(); // Add rule for single line comments. rules.add(new EndOfLineRule("//", Token.UNDEFINED)); // Add rule for strings and character constants. rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); // Add special case word rule. rules.add(new WordPredicateRule(comment)); // Add rules for multi-line comments and javadoc. rules.add(new MultiLineRule("/**", "*/", javaDoc, (char) 0, true)); rules.add(new MultiLineRule("/*", "*/", comment, (char) 0, true)); IPredicateRule[] result= new IPredicateRule[rules.size()]; rules.toArray(result); setPredicateRules(result); }
See the classes in org.eclipse.jface.text.rules for more details about defining rules and the types of rules availables. We'll look at the scanners again when we look at syntax coloring.
Besides providing an appropriate document for an editor input, another important task of a document provider is to supply an appropriate IAnnotationModel to use with an editor input. This model is used to manage annotations attached to documents. By letting the document provider supply the model, your editor can use a model appropriate for the type of content. We'll look at annotations and how they are presented more closely in the next section.