平台定义了一些基本内容类型(例如纯文本和 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 声明为缺省字符集)。
当内容描述器执行它的职责时,它将尽可能快地执行。需要读取的数据流越少,执行效果就越好。并且,在不用激活插件的包中可能声明内容描述器实现(请参阅 Eclipse-AutoStart bundle 清单头)。由于所有描述器都是在内容类型框架初始化时实例化的,因此,如果未符合此要求,就会导致过早激活。这种情况必须避免。如果这样做触发相应插件激活时,则在将来实现平台时可能会拒绝实例化描述器。
在本质上,内容类型是分层的。这使新的内容类型能够利用更常见的内容类型的属性或行为。例如,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 内容类型覆盖了文本内容类型中最初定义的几个内容类型属性,如文件关联和描述器实现。并且,此内容类型为 charset
属性声明了缺省属性值。这意味着在被认为属于 XML 内容类型的某一数据流的内容描述期间,如果描述器未填写 charset 属性,平台将会将该属性设置为“UTF-8”。
作为另一个示例,org.eclipse.ant.core.antBuildFile
内容类型(用于 Ant Build 脚本)扩展了 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 属性的缺省值是继承的。可以通过重新声明继承的属性或描述器并将空字符串用作值来将它们取消。
可以对现有的内容类型添加新的文件关联。例如,Resources 插件使 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"/> ...
Eclipse 的可扩展性质决定了插件所依赖的内容类型在给定产品配置中可能不存在。可以通过为内容类型创建别名来解决此问题。内容类型别名是另一个首选内容类型(不保证其可用性)的占位符。例如,对于 Java Development Tooling 提供的 Java 属性内容类型(org.eclipse.jdt.core.javaProperties
),运行时为其声明了别名(org.eclipse.core.runtime.properties
):
<!-- a placeholder for setups where JDT's official type is not available -->
<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>
这为插件提供了可供它们引用的占位符,而不必考虑要使用的内容类型是否可用。如果该内容类型可用,就会从内容类型目录中禁用别名内容类型,对它的任何引用都将被解释为对目标内容类型的引用。如果该内容类型不可用,则将把别名用作普通内容类型。