Текстовая среда платформы задает модель документа для работы с текстом, а также предоставляет программу просмотра для отображения текста в соответствии с этой моделью. Сначала рассмотрим, каким образом эта модель применяется в примере редактора Java. Основные способы регистрации расширения редактора были описаны в разделе, посвященном org.eclipse.ui.editors, поэтому далее они не рассматриваются. Вместо этого основное внимание уделено особенностям реализации класса редактора в этом примере.
В рабочей среде редактор открывается в результате выбора элемента домена (например, файла или элемента, расположенного в архиве) и его открытия. В процессе создания редактор связывается с вводом редактора (IEditorInput), описывающим обрабатываемый объект.
Пример редактора Java предназначен для работы с файлами "*.jav". В этом случае в качестве ввода редактора применяется IFileEditorInput. Текстовая среда платформы не обладает полной информацией о вводе редактора. Она взаимодействует с моделью оформления IDocument, позволяющей эффективно отображать текст и управлять им.
Такой подход предусматривает преобразование между ожидаемой моделью домена (вводом редактора) и моделью оформления. Это преобразование определено в IDocumentProvider. В соответствии с вводом редактора источник документов возвращает соответствующий интерфейс IDocument.
Пример редактора Java наследует класс TextFileDocumentProvider, определенный в модуле org.eclipse.ui.editors. Расширение org.eclipse.ui.editors.documentProviders задает записи преобразования между типами ввода редактора (расширениями файлов) и источниками документов. В модуле редактора источник документов задан следующим образом:
<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>
Эта точка расширения позволяет модулю зарегистрировать источники и связать их с расширением файлов, либо классом ввода редактора. Поскольку пример редактора Java не задает собственное расширение источника документов, он наследует стандартный источник документов, указанный для всех типов ввода, относящихся к IStorageEditorInput. При открытии файла для внесения изменений платформа управляет данными, необходимыми для создания подходящего экземпляра источника документов. По умолчанию применяется источник документов, связанный с расширением файлов. Если такой источник не зарегистрирован, выполняется поиск источника в соответствии с типом ввода редактора.
Применение стандартного источника документов платформы в примере редактора Java позволяет получить доступ ко всем функциям этого источника документов, в том числе буферизации файлов и различным операциям оптимизации.
Если редактор Java применяет источник текстовых документов платформы, каким образом в нем реализованы дополнительные функции обработки файлов Java?
Расширение org.eclipse.core.filebuffers.documentSetup позволяет задать записи преобразования между расширениями файлов и IDocumentSetupParticipant. Объект настройки позволяет добавить дополнительные функции обработки документов.
<extension id="ExampleJavaDocumentSetupParticipant" name="%documentSetupParticipantName" point="org.eclipse.core.filebuffers.documentSetup"> <participant extensions="jav" class="org.eclipse.ui.examples.javaeditor.JavaDocumentSetupParticipant"> </participant> </extension>
Данное определение расширения позволяет указать для документа задачи, связанные с обработкой исходного кода Java. Что же делает JavaDocumentSetupParticipant? Рассмотрим простой метод setup.
public void setup(IDocument document) {
...
IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);
partitioner.connect(document);
...
}
В этом примере настраивается объект разбиения на разделы.
Объект разбиения на разделы (IDocumentPartitioner) отвечает за разбиение документа независимые фрагменты, называемые разделами. С помощью разделов (определяемых интерфейсом ITypedRegion) в документе можно создать несколько областей с разными параметрами таких функций, как выделение синтаксиса и форматирование.
В случае примера редактора Java документ разделяется на разделы документации по Java, многострочных комментариев и прочего текста. Для каждой области указывается отдельный тип содержимого, а также расположение в документе. Расположения разделов обновляются по мере внесения изменений в текст.
Подходящая реализация объекта разбиения на разделы определяется непосредственно редактором. В пакете org.eclipse.jface.text.rules предусмотрена поддержка просмотра документов в соответствии с правилами. В этом случае редактор применяет объект разбиения на разделы по умолчанию FastPartitioner, предоставленный средой.
IDocumentPartitioner partitioner= new FastPartitioner(JavaEditorExamplePlugin.getDefault().getJavaPartitionScanner(), JavaPartitionScanner.JAVA_PARTITION_TYPES);
RuleBasedPartitionScanner представляет собой базовый класс сканера документов, основанного на правилах. Производные классы отвечают за порядок применения и реализацию правил, используемых для поиска маркеров, таких как ограничители строк, пробелы и базовые шаблоны. В рассматриваемом примере JavaPartitionScanner задает правила поиска однострочных комментариев, символьных констант, документации по Java, многострочных комментариев и слов. Ниже приведен фрагмент исходного кода конструктора сканера:
public JavaPartitionScanner() {
super();
IToken javaDoc= new Token(JAVA_DOC);
IToken comment= new Token(JAVA_MULTILINE_COMMENT);
List rules= new ArrayList();
// Добавление правила для однострочных комментариев.
rules.add(new EndOfLineRule("//", Token.UNDEFINED));
// Добавление правил для строк и символьных констант.
rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\'));
rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\'));
// Добавление правила для слов.
rules.add(new WordPredicateRule(comment));
// Добавление правил для многострочных комментариев и документации по Java.
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);
}
Дополнительную информацию об определении правил, а также список доступных типов правил можно найти в описании классов, входящих в состав org.eclipse.jface.text.rules. Сканнеры также рассматриваются в разделе, посвященном выделению синтаксиса цветом.