W środowisku tekstowym platformy jest definiowany model dokumentu dla tekstu, a ponadto jest udostępniana przeglądarka, w której jest wyświetlany tekst przy użyciu tego modelu. Na początek pokazane zostanie, jak przykładowy edytor Java używa tego modelu. Podstawowy mechanizm rejestrowania rozszerzenia edytora nie będzie szczegółowo omawiany, ponieważ informacje o nim zaprezentowane zostały wcześniej, w sekcji dotyczącej punktu rozszerzenia org.eclipse.ui.editors. Zamiast tego pokazane zostanie, jak klasa edytora jest implementowana w tym przykładzie.
W środowisku roboczym edytor jest zwykle otwierany wtedy, gdy użytkownik wybiera element domeny, taki jak plik czy element przechowywany w pliku archiwum, i otwiera go. Dla tworzonego edytora jest tworzone powiązanie z wejściem edytora (interfejsem IEditorInput), które opisuje edytowany obiekt.
Przykładowy edytor Java jest otwierany wtedy, gdy użytkownik otwiera plik z rozszerzeniem "*.jav". W tym przypadku wejściem edytora jest interfejs IFileEditorInput. W środowisku tekstowym platformy nie jest przyjmowanych zbyt wiele założeń dotyczących danych wejściowych edytora. Tekst danych wejściowych jest efektywnie wyświetlany i modyfikowany dzięki współpracy z modelem prezentacji (interfejsem IDocument).
Oznacza to konieczność istnienia sposobu na odwzorowanie oczekiwanego modelu domeny (danych wejściowych edytora) na model prezentacji. Odwzorowanie to jest definiowane przez interfejs IDocumentProvider. Uwzględniając dane wejściowe edytora, dostawca dokumentu zwraca odpowiedni interfejs IDocument.
Przykładowy edytor Java dziedziczy dostawcę TextFileDocumentProvider zdefiniowanego przez moduł dodatkowy org.eclipse.ui.editors. Rozszerzenie org.eclipse.ui.editors.documentProviders służy do definiowania odwzorowania typów danych wejściowych edytora (lub rozszerzeń plików) na dostawców dokumentów. Moduł dodatkowy edytorów definiuje swojego dostawcę dokumentów następująco:
<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>
Ten punkt rozszerzenia umożliwia modułom dodatkowym rejestrowanie dostawców dokumentów i przypisywanie ich do rozszerzeń plików lub do klasy danych wejściowych edytora. Ponieważ przykładowy edytor Java nie definiuje własnego rozszerzenia dostawcy dokumentów, dziedziczy on ogólnego dostawcę dokumentów przeznaczonego dla wszystkich typów danych wejściowych (interfejs IStorageEditorInput). Gdy użytkownik otwiera plik do edycji, platforma zarządza szczegółami tworzenia instancji odpowiedniego dostawcy dokumentów. Jeśli dla danego rozszerzenia pliku jest zarejestrowany konkretny dostawca dokumentów, to zostanie on użyty. Jeśli dla danego rozszerzenia pliku nie ma określonego dostawcy dokumentów, do wyszukania odpowiedniego dostawcy zostanie użyty typ danych wejściowych edytora.
Używając ogólnego dostawcy plików platformy, przykładowy edytor Java może skorzystać z zalet wszystkich funkcji tego dostawcy dokumentów, takich jak buforowanie plików i inne optymalizacje.
Skoro edytor Java używa dostawcy dokumentów tekstowych platformy, to w jaki sposób może zapewnić specjalne zachowanie na potrzeby obsługi plików Java?
Rozszerzenie org.eclipse.core.filebuffers.documentSetup jest używane do definiowania odwzorowań między rozszerzeniami plików a interfejsem IDocumentSetupParticipant. Uczestnik konfiguracji zainstaluje dokument wraz z wszelkimi specjalnymi opcjami w momencie dostarczenia go do edytora.
<extension id="ExampleJavaDocumentSetupParticipant" name="%documentSetupParticipantName" point="org.eclipse.core.filebuffers.documentSetup"> <participant extensions="jav" class="org.eclipse.ui.examples.javaeditor.JavaDocumentSetupParticipant"> </participant> </extension>
Taka definicja rozszerzenia jak w przykładzie pozwala skonfigurować dokument pod kątem czynności specyficznych dla języka Java. Do czego zatem służy rozszerzenie JavaDocumentSetupParticipant? Oto uproszczona wersja metody setup (konfiguracja).
public void setup(IDocument document) { ... IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES); partitioner.connect(document); ... }
Kod konfiguracji tworzy obiekt zwany partycjonerem.
Partycjoner (interfejs IDocumentPartitioner) odpowiada za dzielenie dokumentu na niepokrywające się regiony zwane partycjami. Partycje (reprezentowane przez interfejs ITypedRegion) są przydatne przy traktowaniu różnych sekcji dokumentu w różny sposób, z uwzględnieniem takich cech, jak wyróżnianie składni czy formatowanie.
W przypadku przykładowego edytora Java dokument jest podzielony na partycje reprezentujące komentarze javadoc, komentarze wielowierszowe i pozostałą część dokumentu. Każdy region ma przypisany typ treści oraz pozycję w dokumencie. Pozycje są aktualizowane w trakcie edytowania tekstu.
Zadaniem każdego edytora jest ustalenie właściwej implementacji partycjonera dokumentu. Obsługa skanowania dokumentów opartych na regułach jest udostępniana przez pakiet org.eclipse.jface.text.rules. Korzystanie ze skanera opartego na regułach pozwala edytorowi na używanie klasy FastPartitioner udostępnianej przez środowisko.
IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);
Klasa RuleBasedPartitionScanner jest nadklasą skanerów opartych na regułach. Podklasy odpowiadają za numerowanie i implementowanie reguł, które mają być stosowane w trakcie skanowania do rozróżniania elementów takich jak ograniczniki wierszy, znaki spacji i ogólne wzorce. W przykładzie klasa JavaPartitionScanner definiuje reguły rozróżniania komentarzy jednowierszowych, stałych znakowych, elementów javadoc, komentarzy wielowierszowych i wyrazów. To wszystko znajduje się w konstruktorze skanera:
public JavaPartitionScanner() { super(); IToken javaDoc= new Token(JAVA_DOC); IToken comment= new Token(JAVA_MULTILINE_COMMENT); List rules= new ArrayList(); // Dodanie reguły dla komentarzy jednowierszowych. rules.add(new EndOfLineRule("//", Token.UNDEFINED)); // Dodanie reguły dla łańcuchów i stałych znakowych. rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); // Dodanie reguły dla wyrazów o specjalnej pisowni. rules.add(new WordPredicateRule(comment)); // Dodanie reguły dla komentarzy wielowierszowych i elementów 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); }
Więcej informacji na temat definiowania reguł i typów dostępnych reguł zawiera sekcja dotycząca klas pakietu org.eclipse.jface.text.rules. O skanerach będzie jeszcze mowa w sekcji Kolorowanie składni.