Документы и разделы

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