Добавление новых типов содержимого

Регистрация типа содержимого

В платформе определены несколько базовых типов содержимого, например: обычный текст и XML. Эти типы определяются точно так же, как и те, что добавлены другими модулями. Для того, чтобы лучше понять структуру типа содержимого, рассмотрим, как в платформе определяется текстовый тип.

В модулях тип содержимого определяется с помощью точки расширения org.eclipse.core.runtime.contentTypes. Модуль должен указывать краткий идентификатор и имя типа содержимого (полный идентификатор также указывает текущее пространство имен). Ниже приведена сокращенная версия регистрации типа содержимого org.eclipse.core.runtime.text:

	<extension point="org.eclipse.core.runtime.contentTypes">
		<content-type 
			id="text"
			name="%textContentTypeName">
			file-extensions="txt">
			<describer class="org.eclipse.core.internal.content.TextContentDescriber"/>
		</content-type>
		...

Атрибут file-extensions задает расширения файлов, связанные с типом содержимого (в примере - это ".txt"). Атрибут file-names (отсутствует в примере) позволяет связывать с типами полные имена файлов. Оба атрибута учитываются при определении типа содержимого и его описания (если доступно имя файла).

Элемент describer определяет описатель содержимого.

Определение и описание содержимого

Если содержимое данного типа всегда содержит уникальные характеристики, позволяющие точно идентифицировать его, то тип содержимого должен предоставлять описатель содержимого. Тип содержимого org.eclipse.core.runtime.text не может быть определен по анализу содержимого. Но текстовые потоки могут начинаться с метки порядка следования байтов, поэтому описатель содержимого все же будет добавлен.

Описатель содержимого - это реализация IContentDescriber или ITextContentDescriber. Последний - более детализированный первый. Он должен реализовываться типами-потомками текстового типа (т.е. не двоичными). Описатель предназначен для определения, подходит ли тип содержимого для данного потока данных, и получения свойств последнего.

Всякий раз, когда платформа пытается определить тип содержимого или получить описание входного потока данных, вызывается метод describe(stream, description). Аргумент description равен null если запрошено только определение типа. В противном случае описатель должен заполнить его свойствами, полученными с помощью чтения потока. В объявлении типа содержимого можно задавать значения свойств по умолчанию (например, org.eclipse.core.runtime.xml объявляет UTF-8 кодировкой по умолчанию).

Описатель содержимого должен выполнять свою работу как можно быстрее. Объем прочитанных данных должен быть как можно меньше. Также, предполагается, что реализация описателя содержимого объявляется в пакете, не зависимом от активности модуля (см. заголовок манифеста комплекта OSGi Eclipse-AutoStart). Т.к. при инициализации инфраструктуры типов содержимого создаются экземпляры всех описателей, помещение описателя в обычный пакет приведет к активации всего модуля, даже если он не нужен. В следующих версиях платформы возможно игнорирование таких описателей.

Расширение существующего типа расширения

По своей природе типы содержимого иерархичны. Это позволяет новым типам содержимого использовать атрибуты или поведение более общих типов, стоящих выше. Например, тип для данных XML считается дочерним для текстового типа:

<content-type 
	id="xml"
	name="%xmlContentTypeName"
	base-type="org.eclipse.core.runtime.text"
	file-extensions="xml">
	<describer class="org.eclipse.core.internal.content.XMLContentDescriber"/>
	<property name="charset" default="UTF-8"/>
</content-type>

Т.к. файл XML - по сути текстовый файл, к нему применимы все характеристики текстовых файлов.

Обратите внимание на то, что тип XML переопределяет некоторые атрибуты, определенные в стоящем выше типе Text, в частности расширение имени файла и реализацию описателя. Далее задается значение по умолчанию для свойства charset. Это означает, что если значение свойства charset останется не заполненным при описании содержимого для потока данных, принадлежащего к типу XML, оно будет установлено равным "UTF-8".

Тип содержимого org.eclipse.ant.core.antBuildFile (сценарии компоновки Ant) является производным от типа XML:

<content-type  
id="antBuildFile"
name="%antBuildFileContentType.name"
base-type="org.eclipse.core.runtime.xml"
file-names="build.xml"
file-extensions="macrodef,ent,xml">
<describer
class="org.eclipse.ant.internal.core.contentDescriber.AntBuildfileContentDescriber">
</describer>
</content-type>

Значение по умолчанию для свойства charset наследуется автоматически. Для того чтобы явно отменить наследование, переопределите свойство или описатель с пустым значением.

Дополнение файловых ассоциаций

К существующему типу содержимого можно добавлять новые ассоциации файлов. Например, модуль ресурсов ассоциирует тип org.eclipse.core.runtime.xml с файлами, имеющими имя ".project":

<extension point="org.eclipse.core.runtime.contentTypes">
	<file-association content-type="org.eclipse.core.runtime.xml" file-names=".project"/>
	...

Подстановка типов содержимого

Тип содержимого, от которого зависит определенный модуль, может отсутствовать в данной конфигурации продукта. В таких случаях можно использовать подстановку типов. Подстановка типа содержимого - это замена недоступных типов другими. Например, динамическая среда содержит подстановку (org.eclipse.core.runtime.properties) для типа содержимого "свойства Java", предоставляемого JDT (org.eclipse.jdt.core.javaProperties):

<!-- заменитель для конфигураций без JDT -->			
<content-type id="properties" name="%propertiesContentTypeName"
base-type="org.eclipse.core.runtime.text"
alias-for="org.eclipse.jdt.core.javaProperties"
file-extensions="properties">
<property name="charset" default="ISO-8859-1"/>
</content-type>

Это обеспечивает модули заменой отсутствующего типа. Если заменяемый тип будет присутствовать в конфигурации, то его замена будет исключена из иерархии типов и все обращения к ней будут перенаправляться оригинальному типу. В обратном случае будет применяться заменяющий тип.