`
Jameslyy
  • 浏览: 408976 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Eclipse 运行时概述 Part 2 —— 内容类型

阅读更多

内容类型(Content Type)

        org.eclipse.core.runtime.content 提供了对数据流内容类型检测的支持。Eclipse 中对内容敏感的几个功能部件使用到了内容类型的概念,例如自动检测编码,编辑器和菜单扩展部分。Eclipse 运行时提供了一个集中的内容注册表,插件可以检测内容类型,发现可用的内容类型,以及和内容类型之间的关联关系,内容类型注册表是可扩展的,插件可以扩展新的内容类型。

 

1. 使用内容类型

注:为了方便讨论,在谈到 内容 时,我们没有使用 文件 这个词语。运行时内容引擎不假设内容是包含在文件中的,但是运行时提供了能够把内容类型和文件命名模式关联起来的方法。事实上,文件名称代表着系统中的文件,但是并能够通过内容类型确定内容数据来源于文件系统。 File encoding and content types 讨论了平台资源插件提供的面向文件的内容类型支持,如果开发者需要在这种环境下使用内容类型 API,推荐阅读这篇文章。

 

1.1 发现内容类型

        内容类型由接口 IContentType 表示,这个接口定义如何读取数据流和获取特定内容类型信息的方法。内容类型本质上是分层的,例如,表示XML 数据的内容类型可以看作文本内容类型的子类型,这使得新的内容类型可以利用更为通用的内容类型的属性和行为。

 

        IContentTypeManager 是访问平台运行时提供的大多数内容类型相关API的入口,客户程序可以通过Platform API 获得平台IContentTypeManager 对象的引用:

IContentTypeManager contentTypeManager = Platform.getContentTypeManager();

 

通过平台IContentTypeManager 对象可以获得系统中的内容类型。

  • getAllContentTypes 获取系统中全部的内容类型
  • getContentType      通过唯一标识获取一个内容类型
1.2 检测数据流的内容类型
给定一个字节流,通过调用IContentTypeManager API可以获得其内容类型,如下:
InputStream stream = ...;
IContentType contentType = contentTypeManager.findContentTypeFor(stream, "file.xml");
stream.close();
        这个方法将会根据给定的参数,返回一个最合适的IContentType 对象,如果没有发现内容类型对象,将会返回null。一个给定的数据流可能满足多种内容类型的标准,对于这种情况,平台使用启发式的方法确定应该返回哪一个内容类型。文件名是确定内容类型的第一个标准,可以忽略文件名,但是将会引起两个问题,第一个问题是,由于同一个数据流可能满足多种内容类型,获得的结果可能不是我们想要的结果;另外,存在很大的性能问题,因为平台中的所有的内容类型都将会可能需要分析数据流,以获取一个合适的内容类型。所以,除非无法获取文件名,提供数据流参数的同时都应该提供一个文件文明。

1.3 数据流描述
另外一个Eclipse 平台提供的内容类型特性是描述一个二进制或字符流的内容的能力,下面的代码片段展示了具体的方法:
InputStream stream = ...; 
IContentDescription description = contentTypeManager.getDescriptionFor(stream, "file.xml");
stream.close();
        返回的 IContentDescription 实例描述了内容类型和其他提取自内容数据的相关信息。内容描述包含键值对形式的和特定内容相关的属性。Eclipse 平台本身也能够描述内容描述属性,例如字符集和文本数据流的字节序数据,但是内容类型可以定义更多的属性。

1.4 创建新的内容类型
        新的内容类型通常被定义为已经存在的内容类型的特例。这种层级关系在继承的内容类型和基本类型之间确立了一个“是一个” 的关系。插件开发者在实现内容类型功能是必须遵守这一点。如果一个给定的特性适用于一个给定的内容类型,这个特定也必须适应于任何既成的内容类型。 IContentType.isKindOf(IContentType superType)  方法可以检测两个IContentType 是否关联。IContentType.getBaseType() 方法用于检测给定IContentType 的基类型。

2. 扩展内容类型

 

2.1 创建新的内容类型

        Eclipse 平台定义了一些基本的内容类型,例如普通文本和XML。这些内容类型的实现方式和其他任何插件实现方式是相同的,我们先看看Eclise 平台是怎样定义自己的内容类型的,以更好地理解内容框架。

 

        插件是通过创建扩展点org.eclipse.core.runtime.contentTypes 扩展的方式定义内容类型的。插件在扩展中为内容类型指定了一个简单的id 和名称(完整的id是当前命名空间作为前缀的id)。下面是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(在这个例子没有用到)定义相关联的完整文件名。在执行内容类型检测和描述时,这两种属性都会被Eclipse 平台使用到(如果客户程序提供了文件名称)。

 

2.2 检测和描述内容

        如果存在能够实现内容类型自动检测的可辨认的特性,或者属于内容类型的任何有用数据属性,都应该提供一个内容描述对象。例如 org.eclipse.core.runtime.text, 仅仅看文本内容,是不可能区分内容类型的。但是,可以在文本数据流的前面添加一个字节顺序标记,客户程序可能需要这个标记以实现所需的功能,所以,这里就需要用到内容描述对象了。

 

        内容描述对象是 IContentDescriber or ITextContentDescriber 的实现,后者是前者的一个特例,文本内容类型的内容描述对象需要实现后面这个接口。不管内容类型的形式如何,描述对象都实现两个功能:帮助检测内容类型是否对应于一个给定数据流,和从属于特定内容类型的数据流中抽取需要的属性数据。

 

        只要平台试图检测特定数据流的内容类型,或者描述它的数据内容,就会调用到方法 describe(stream, description) 。如果仅仅是检测内容类型,则描述将会为null 。否则,数据描述对象应该把通过读取数据流得到的任何属性存入到内容描述中,并且,内容描述应该仅包含这些属性数据。内容类型标记应该仅用于声明具有默认值的属性(例如,org.eclipse.core.runtime.xml 声明 UTF-8 作为默认的字符集)。

 

        执行内容描述对象的功能应该尽可能快,读取的数据流越少越好。并且,内容描述对象应该声明于一个不会激活插件的包中。所有的内容描述对象是在内容类型框架初始化时创建的,不遵循此要求将会引起插件过早激活,应该避免这种情况的发生。如果这样做会引起对于插件的激活,平台的错误实现将不会初始化内容描述对象。

 

2.3 扩展一个存在的内容类型

        内容类型在本上是分层的,这是的新的内容类型可以利用更为通用的内容类型的属性和行为,例如,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内容类型的数据流是,如果描述对象没有提供一个字符集属性,平台会把它设置为“UTF-8” 。

 

再举一个例子,org.eclipse.ant.core.antBuildFile 内容类型扩展了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>

 

注意字符集属性默认值是继承的, 通过声明为空的字符串值,可以取消继承的默认属性或描述对象。

 

2.4 添加文件关联

        新的文件关联可以添加到已存在内容类型,例如,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"/>
	...

 

2.5 内容类型别名

        由于Eclipse 的可扩展特性,在一个给定的产品配置中,有可能多不到插件所依赖的内容类型,这个问题可以通过使用内容类型别名机制绕过。内容类型别名是另外一个无法确保能够获取的内容类型的占位符,例如,Runtime 在Java开发工具 JDT 中为Java 属性内容类型声明了一个别名(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>		

        这种方法向插件提供了一个能够参照的占位符,不管需要的内容类型是不是存在。如果是存在的,内容类型分类目录会隐藏别名内容类型,任何的引用都会解析为对目标内容类型的引用。如果不存在,别名用作原始内容类型。

 

 

分享到:
评论

相关推荐

    深入浅出Hibernate中文版 part2

    第2章 Hibernate概述 第3章 快速起步 3.1 准备工作 3.2 Hibernate配置 3.3 日志配置 3.4 第一段代码 3.5 代码初解 第4章 Hibernate基础 4.1 Hibernate基础语义 4.2 基础配置 4.3 Hibernate O/R映射 4.4 ...

    深入浅出Hibernate中文版 part1

    第2章 Hibernate概述 第3章 快速起步 3.1 准备工作 3.2 Hibernate配置 3.3 日志配置 3.4 第一段代码 3.5 代码初解 第4章 Hibernate基础 4.1 Hibernate基础语义 4.2 基础配置 4.3 Hibernate O/R映射 4.4 ...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    主要包括Java Web开发环境、JSP语法、JSP内置对象、Java Bean技术、Servlet技术、EL与JSTL标签库、数据库应用开发、初识Struts2基础、揭密Struts2高级技术、Hib锄劬e技术入门、Hibernate高级应用、Spring核心之IoC、...

    Getting Started with OSGi_ Part3

    《OSGi初识系列教程——第三部分:模块间的依赖关系》 在OSGi(Open Service Gateway Initiative)框架中,理解并管理模块间的依赖关系是至关重要的。本篇教程将深入探讨这一主题,帮助开发者们更好地掌握OSGi环境...

    GEF开发指南---插件开发

    这通常涉及到从`org.eclipse.ui.part.EditorPart`类继承,并实现必要的方法来支持图形编辑功能。 - **图形绘制**:文档虽然没有详细描述具体的图形绘制逻辑,但可以推测这部分工作是在Editor类中完成的,利用GEF提供...

Global site tag (gtag.js) - Google Analytics