Das Textgerüst der Plattform definiert ein Dokumentenmodell für Text und liefert eine Anzeigefunktion, die Text unter Verwendung dieses Modells anzeigt. Zu Beginn wird das Java-Editor-Beispiel betrachtet, sowie die Art, wie es dieses Modell benutzt. Auf die Grundvorgehensweise bei der Registrierung einer Editorerweiterung werden wir nicht eingehen, da dies bereits im Abschnitt über org.eclipse.ui.editors behandelt wurde. Stattdessen wird unter die Lupe genommen, wie die Editorklasse im Beispiel implementiert wird.
In der Workbench wird ein Editor normalerweise dann geöffnet, wenn der Benutzer ein Domänenelement (z. B. eine Datei oder ein Element, das in einer Archivdatei gespeichert ist) auswählt und öffnet. Bei der Erstellung des Editors wird ihm ein Editoreingabeobjekt zugeordnet (IEditorInput), das das bearbeitete Objekt beschreibt.
Das Java-Editor-Beispiel wird geöffnet, wenn der Benutzer eine Datei mit der Erweiterung "*.jav" öffnet. In diesem Fall besteht die Eingabe in den Editor aus einem Objekt IFileEditorInput. Das Textgerüst der Plattform benötigt nur wenige Angaben zur eigentlichen Editoreingabe. Es arbeitet mit einem Darstellungsmodell, dem so genannten IDocument, für die Eingabe, damit Text tatsächlich angezeigt und bearbeitet werden kann.
Dies bedeutet, dass es eine Möglichkeit für die Zuordnung aus einem erwarteten Domänenmodell (der Editoreingabe) zum Darstellungsmodell geben muss. Diese Zuordnung wird in einem Objekt IDocumentProvider definiert. Der Dokumentprovider gibt für eine bestimmte Editoreingabe das passende Objekt IDocument zurück.
Das Java-Editor-Beispiel übernimmt das vom Plug-in org.eclipse.ui.editors definierte Objekt TextFileDocumentProvider. Die Erweiterung org.eclipse.ui.editors.documentProviders wird verwendet, um Zuordnungen zwischen Editor-Eingabetypen (oder Dateierweiterungen) und Dokumentenprovidern zu definieren. Das Plug-in des Editors definiert seinen Dokumentenprovider folgendermaßen:
<extension point="org.eclipse.ui.editors.documentProviders"> <provider class="org.eclipse.ui.editors.text.TextFileDocumentProvider" inputTypes="org.eclipse.ui.IStorageEditorInput" id="org.eclipse.ui.editors.text.StorageDocumentProvider"> </provider> </extension>
Über diesen Erweiterungspunkt können Plug-ins Dokumentenprovider registrieren und sie entweder einer Dateierweiterung oder einer Editor-Eingabeklasse zuordnen. Da das Beispiel des Java-Editors keine eigene Erweiterung für Dokumentenprovider definiert, übernimmt es den generischen Dokumentenprovider, der für alle Eingabetypen der Art IStorageEditorInput angegeben ist. Wenn der Benutzer eine Datei zur Bearbeitung öffnet, verwaltet die Plattform die Details der Erstellung eines korrekten Dokumentenproviderexemplars. Wenn ein bestimmter Dokumentenprovider für die Dateierweiterung registriert ist, so wird dieser verwendet. Wenn es für die Dateierweiterung keinen bestimmten Dokumentenprovider gibt, wird der Editor-Eingabetyp verwendet, um einen geeigneten Provider zu finden.
Durch die Verwendung des generischen Dokumentenproviders der Plattform kann das Java-Editor-Beispiel von allen Vorteilen der Funktionalität des Dokumentenproviders profitieren, wie z.B. Dateipuffer und anderen Optimierungen.
Da der Java-Editor den Textdokumentenprovider der Plattform verwendet, stellt sich die Frage, wie er spezielles Verhalten für die Handhabung von Java-Dateien bereitstellen kann.
Die Erweiterung org.eclipse.core.filebuffers.documentSetup wird verwendet, um Zuordnungen zwischen Dateierweiterungen und einem IDocumentSetupParticipant zu erstellen. Der Konfigurationsteilnehmer definiert das Dokument mit entsprechenden Sondereinrichtungen, nachdem es dem Editor ausgeliefert wurde.
<extension id="ExampleJavaDocumentSetupParticipant" name="%documentSetupParticipantName" point="org.eclipse.core.filebuffers.documentSetup"> <participant extensions="jav" class="org.eclipse.ui.examples.javaeditor.JavaDocumentSetupParticipant"> </participant> </extension>
Diese Erweiterungsdefinition gibt dem Beispiel die Möglichkeit, das Dokument für Java-spezifische Tasks einzurichten. Was macht also JavaDocumentSetupParticipant? Betrachten wir eine vereinfachte Version der Methode setup.
public void setup(IDocument document) { ... IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES); partitioner.connect(document); ... }
Der Konfigurationscode richtet ein Objekt namens partitioner ein.
Die Partitionierungsfunktion (IDocumentPartitioner) ist dafür verantwortlich, das Dokument in überschneidungsfreie Bereiche einzuteilen, die Partitionen genannt werden. Partitionen (dargestellt unterITypedRegion) sind nützlich, wenn unterschiedliche Abschnitte des Dokuments im Hinblick auf Funktionen wie Syntaxhervorhebung oder Formatierung unterschiedlich verarbeitet werden sollen.
Im Beispiel des Java-Editors wird das Dokument in Partitionen unterteilt, die Javadoc-Kommentare, mehrzeilige Kommentare sowie alle übrigen Angaben darstellen. Jedem Bereich ist ein Inhaltstyp und seine Position im Dokument zugeordnet. Positionen werden aktualisiert, wenn der Benutzer den Text bearbeitet.
Jeder Editor muss selbst die geeignete Implementierung für eine Dokumentpartitionierungsfunktion bestimmen. Die Unterstützung für ein regelbasiertes Dokumentscanning wird durch org.eclipse.jface.text.rules bereitgestellt. Mit einer regelbasierten Scannerfunktion kann ein Editor den FastPartitioner verwenden, der durch das Gerüst bereitgestellt wird.
IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);
RuleBasedPartitionScannerist die Superklasse für regelbasierte Scannerfunktionen. Unterklassen sind für die Auflistung und die Implementierung der Regeln zuständig, mit denen Token wie Zeilenbegrenzer, Leerzeichen und generische Muster beim Durchsuchen eines Dokuments voneinander unterschieden werden. Der JavaPartitionScanner des Beispiels definiert Regeln für die Unterscheidung von einzeiligen Kommentaren, Zeichenkonstanten, Javadoc, mehrzeiligen Kommentaren und Wörtern. Dies wird im Konstruktor der Scannerfunktion vorgenommen:
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); }
Weitere Details zum Definieren von Regeln und zu den verfügbaren Regeltypen können Sie in den Klassen inorg.eclipse.jface.text.rules nachlesen. In dem Abschnitt, in dem die syntaxorientierten Textfarben behandelt werden, wird es auch noch einmal um die Scannerfunktionen gehen.