Текстовая среда платформы задает модель документа для работы с текстом, а также предоставляет программу просмотра для отображения текста в соответствии с этой моделью. Сначала рассмотрим, каким образом эта модель применяется в примере редактора 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. Сканнеры также рассматриваются в разделе, посвященном выделению синтаксиса цветом.