采用 3.0 机制和 API 时所需的更改

本节描述尝试更改 2.1 插件以采用 3.0 机制和 API 时所需的更改。

除去 org.eclipse.core.runtime.compatibility

Eclipse 3.0 运行时有很大的不同。底层实现基于 OSGi 框架规范。Eclipse 3.0 运行时包括兼容性层(在 org.eclipse.core.runtime.compatibility 插件中),它保留了 2.1 API。关心附加性能和功能部件的插件开发者应考虑采用 3.0 API 并除去他们在兼容性层上的依赖项。兼容性代码出现在三个位置:

下面的文本给出有关哪些类和方法用于兼容性目的的更多详细信息以及有关如何更新插件的指导。

插件和 bundle

Eclipse 运行时已重构为两部分;类装入和先决条件管理以及扩展/扩展点管理。这一分割允许对类装入和先决条件管理自然/无缝地采用 OSGi 框架规范。这反而又会在运行时中启用一些新功能,范围从动态插件安装/更新/卸载到安全性和增加配置功能。

在我们继续在新运行时中谈到插件时,插件实际上是 bundle 加上一些扩展和扩展点。bundle 是由 OSGi 框架规范定义的,指的是一组类型和资源以及相关联的 bundle 间先决条件信息。扩展注册表是一种新形式的插件注册表,仅详细描述扩展和扩展点信息。总体来说,扩展注册表 API 与相关联的插件注册表 API 相同(有关更多信息,请参阅注册表)。

在 Eclipse 2.x 运行时中,插件对象有若干角色和责任:

在 Eclipse 3.0 运行时图中,这些角色和责任分布在不同对象中。

Bundle
Bundle 是 OSGi 模块单元。每个 bundle 都有一个类装入器,而且还可以构造类似 Eclipse 的 bundle 间类装入依赖项图。bundle 的启动和停止是有生命周期的,而且 OSGi 框架广播会将相关事件(例如安装、解析、启动、停止和卸载等等)捆绑在一起供有兴趣的人使用。与 Eclipse 插件类不同,OSGi Bundle 类是不可扩展的。即,开发者不能定义他们自己的 bundle 类。
BundleActivator
BundleActivator 是 OSGi 框架定义的接口。每个 bundle 都可以定义一个 bundle 激活器类,就象插件可以定义其 Plugin 类一样。指定类是由框架实例化的,用于实现 start()stop() 生命周期处理。不过,此生命周期处理的特性中存在主要差别。在 Eclipse 中,通常会让 Plugin 类执行初始化和注册(尽管并不建议这样做)。在 OSGi 激活器中只能执行注册。在 BundleActivator.start() 中执行大量初始化(或任何其它工作)将威胁系统的运行。
BundleContext
BundleContext 是一种 OSGi 机制,用于将一般系统功能显示给各个 bundle。每个 bundle 都有唯一且私有的 BundleContext 实例,它们可用于访问系统功能(例如,使用 getBundles() 发现系统中的所有bundle)。
插件
插件与原始 Eclipse Plugin 类非常相像,但又有以下几个不同点:Plugin 对象不再是运行时所必需的或由运行时管理的,而且各种方法已经不推荐使用。从本质上讲,它是一种非常便利的机制,可以提供很多有用的功能和机制,但不再是绝对必需的。该处提供的许多功能可从运行时中的 Platform 类获取。

插件还实现了 BundleActivator。它让大家认识到让一个中央对象表示插件的生命周期和语义的便利。但要注意,这并不意味着赞成目前在插件中常见的数据结构的过早初始化。再怎么强调插件可被激活也不为过,因为在验证某个其它插件中的类时会引用其它较外围的类。即,只是因为已经激活插件而并不一定意味着需要它的功能。而且还要注意,您可以自由定义另一 BundleActivator 类,或者根本不具有 bundle 激活器。

将 2.x Plugin 类移植至 Eclipse 3.0 的步骤取决于该类要执行的操作。如上所述,大部分启动生命周期工作落在下列其中一个类别上:

初始化
数据结构和模型初始化通常是在 Plugin.startup() 中完成的。自然/明显映射将在 BundleActivator.start() 中完成这一工作,即在插件上保留这一功能。强烈建议不要这样做。与 2.x 插件一样,可以因为许多不同情况下的许多不同原因启动 3.0 插件/bundle。
Eclipse 2.0 时代的实际示例说明了这一情况。初始化大型模型的插件需要装入一些 11MB 的代码以及许多兆字节的数据。有一些十分常见的用例,其中会激活此插件以发现导航器中显示的项目图标是否应该用特定标记修饰。此测试不需要在 startup() 中执行任何初始化工作,但对于所有用例中的所有用户而言,启动时初始化时将占用大量内存和时间。
替代方法是以经典延迟方式执行这种初始化。例如,在实际需要模型时才进行初始化(例如,在中央化模型 accessor 方法中),而不是在插件/bundle 激活时进行初始化。对于许多用例,这将意味着接近同一时间点,但对于其它方案而言,此方法将延迟初始化(可能不是很确定)。我们建议在移植 2.1 插件时花点时间重新考虑使用的初始化策略。
注册
插件启动时可以很方便地注册侦听器和服务等并启动后台处理线程(如侦听套接字)。Plugin.start() 是完成此工作的合适位置。还可以延迟至一些其它触发器(例如,使用特定功能或数据元素)。
插件全局数据
Plugin 类可执行充当这一角色。主要问题在于 Plugin 对象不再可以通过系统管理的列表全局访问。在 Eclipse 2.x 中,您可以通过插件注册表发现任何插件的 Plugin 对象。这不再行得通。在大多数情况下,不再需要这种类型的访问权。同调用特定于域的方法相比,将通过注册表访问的 Plugin 用作一般 Plugin 更为常用。可通过访问和处理相应的 bundle 对象获取相同级别的功能。

注册表和插件模型

在新运行时中,执行插件所需的信息和与插件的扩展和扩展点有关的结构有一定距离。前者是由 OSGi 框架规范定义并管理的。后者是特定于 Eclipse 的概念,由 Eclipse 运行时代码添加。相应的,原始插件注册表和相关联的对象已经分割成 OSGi bundle 和 Eclipse 扩展注册表

处理执行规范(例如 IPluginDescriptor、ILibraryIPrequisite)的 IPluginRegistry 的部分是不推荐使用的,而且与扩展和扩展点有关的余下部分已移至 IExtensionRegistry。另外,所谓的与插件注册表整体有关的模型对象现在也是不推荐使用的。这些类型是由运行时提供并实例化的,主要用来支持象 PDE 这样的工具。遗憾的是,所需信息的级别通常会超出运行时的能力或意愿(例如,记住 plugin.xml 元素的行号),最后,运行时信息的潜在使用者只能尽力维护他们自己的结构。

在新的运行时中,我们具有运行时提供的经过重新求值的设施,现在仅提供对运行时执行非常重要的或者使用其它设施执行起来特别困难的设施。如上所述,已经不推荐使用插件注册表模型对象,就象插件分析 API 一样。新扩展注册表维护与基本扩展有关的信息。新的状态(请参阅 org.eclipse.osgi.service.resolver.State 及其朋友)结构表示与基本执行有关的信息并允许处理它们。

NL 段结构

在 Eclipse 3.0 中,NL 段结构已经作了更新,变得更加一致。先前像 plugin.properties 这样的文件的转换被假定为在段提供的 JAR 中。因为原始文件在相关主机插件的根目录中,所以较一致的定位会让已转换文件位于 NL 段的根目录中。例如,

  org.eclipse.ui.workbench.nl/
     fragment.xml
     plugin_fr.properties
     plugin_pt_BR.properties
     ...
     nl1.jar

注意,此处的文件 nl1.jar 先前会包含在 plugin.properties 的转换中。这些文件现在位于段的根目录中,而且 JAR 包含主机插件中所有可翻译资源(即,通过类装入器装入的文件)的翻译。

当前,对于在 Eclipse 3.0 中运行的 2.1 主机插件,Eclipse 2.1 NL 段结构仍然是受支持的。但您不能在 3.0 插件上使用 2.1 NL 段。该段必须更新为新结构。

API 更改概述

org.eclipse.core.boot(org.eclipse.core.boot 包)

已经不推荐使用整个 org.eclipse.core.boot 包。BootLoader 已经与 org.eclipse.core.runtime.Platform 合并到一起,原因是分割引导与运行时不再有任何意义。注意,实际上 org.eclipse.core.boot 插件已经坏了,它的所有代码已移至新运行时或兼容性层。

IPlatformConfiguration 始终是由 Eclipse 安装/更新组件定义并且供其使用的类型。借助运行时的重组,我们能够让此类型返回至其合法主目录。此类基本上没有更改,已经重新打包为 org.eclipse.update.configurator.IPlatformConfiguration

IPlatformRunnable 已经移至 org.eclipse.core.runtime.IPlatformRunnable。

IExtension 和 IExtensionPoint(org.eclipse.core.runtime 包)

getDeclaringPlugin() 方法(针对两个类)分别给出指向声明扩展或扩展点的插件的上行链接。新的注册表模型将插件的执行部分与扩展/扩展点部分分开,而且不再包含 IPluginDescriptors。此 API 的用户应考虑 IExtensionIExtensionPoint 上的新方法 getParentIdentifier()

ILibrary、IPluginDescriptor、IPluginRegistry 和 IPrerequisite(org.eclipse.core.runtime 包)

在原始运行时中,插件注册表保留了运行时配置的完整图片。在 Eclipse 3.0 中,此图片在 OSGi 框架和扩展注册表上有了分歧。因此就不推荐使用这些类了。不推荐通知包含应该如何更新代码的详细信息。

平台和插件(org.eclipse.core.runtime 包)

因此在新运行时中,Plugin 对象不再由运行时管理,所以一般不能通过平台访问。同样,插件注册表不再存在或者允许访问插件描述符。但是,有一些合适的替代方法可用,而且在这些类中不推荐使用的方法的 Javadoc 中对这些方法作了详细描述。

org.eclipse.core.runtime.model(org.eclipse.core.runtime.model 包)

现在不推荐使用此包中的所有类型。有关更多信息,请参阅有关注册表的讨论。

IWorkspaceRunnable 和 IWorkspace.run(org.eclipse.core.resources 包)

IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) 方法的客户机应重新访问他们对此方法的使用情况并考虑使用功能更丰富的方法 IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor)。旧的 IWorkspace.run 方法在 IWorkspaceRunnable 执行期间获取了对整个工作空间的锁定。这表示此方法完成的操作将永远无法与正在更改工作空间的其它操作并发运行。在 Eclipse 3.0 中,许多长时间运行的操作已经移至后台线程,所以操作之间的冲突可能性大大增加了。如果模态前台操作被长时间运行的后台操作阻塞,用户界面就会被阻塞,直到后台操作完成或者直到其中一个操作被取消。

建议的解决方案是将所有引用切换至旧的 IWorkspace.run 以便将新方法与调度规则参数配合使用。调度规则应该是粒度最细的规则,它包含用于该操作进行的所有更改的规则。如果该操作尝试修改调度规则的作用域外部的资源,将发生运行时异常。给定工作空间操作所需的精确调度规则未被指定,而且可能会更改(这取决于给定项目上的已安装存储库提供程序)。工厂 IResourceRuleFactory 应该用于获取资源更改操作的调度规则。如果期望,可使用 MultiRule 来指定多个资源规则,而 MultiRule.combine 便利方法可用来合并各种资源更改操作中的规则。

如果不需要任何锁定,可使用调度规则 null。这将允许可运行程序修改工作空间中的所有资源,但不会阻止其它线程并发修改工作空间。对于对工作空间的简单更改,这通常是最简单而且并发性最好的解决方案。

IWorkbenchPage(org.eclipse.ui 包)

IEditorDescriptor(org.eclipse.ui 包)

ISharedImages(org.eclipse.ui 包)

IWorkbenchActionConstants(org.eclipse.ui 包)

IWorkbenchPreferenceConstants(org.eclipse.ui 包)

IExportWizard(org.eclipse.ui 包)

IImportWizard(org.eclipse.ui 包)

INewWizard(org.eclipse.ui 包)

WorkbenchHelp(org.eclipse.ui.help 包)

IHelp(org.eclipse.help 包)

ITextEditorActionConstants(org.eclipse.ui.texteditor 包)

IAbstractTextEditorHelpContextIds(org.eclipse.ui.texteditor 包)

BasicTextEditorActionContributor(org.eclipse.ui.texteditor 包)

TextEditorActionContributor(org.eclipse.ui.editors.text 包)

annotationTypes 扩展点(插件 org.eclipse.ui.editors)

现在已经有了注释类型的明确概念。请参阅 Annotation.getType() 和 Annotation.setType()。注释的类型可以随其生存期而更改。已经向注释类型“org.eclipse.ui.editors.annotationTypes”的声明添加了新的扩展点。注释类型具有名称而且可被声明为另一已声明注释类型的子类型。注释类型声明还可使用属性“markerType”和“markerSeverity”来指定给定类型和给定严重性的标记在文本编辑器中应该显示为特定注释类型的注释。不应再使用“org.eclipse.ui.editors.markerAnnotationSpecification”中的属性“markerType”和“markerSeverity”。因此,标记注释规范就会独立于标记,这样名称会造成误导。但是,该名称会保留下来以确保向后兼容性。

AbstractMarkerAnnotationModel 的子类的实例自动检测它们通过标记创建的注释并为其创建正确的注释类型。为了按计划检索给定标记或给定 markerType 和 markerSeverity 对的注释类型,使用 org.eclipse.ui.texteditor.AnnotationTypeLookup。

对注释类型的层次结构的访问权是由 IAnnotationAccessExtension 提供的。对于给定注释类型,可获取超类型链并检查某个注释类型是不是另一个注释类型的子类型。DefaultMarkerAnnotationAccess 实现此接口。

markerAnnotationSpecification 扩展点(插件 org.eclipse.ui.editors)

注释类型是用来查找相关联的标记注释规范的关键。因为注释类型可扩展其它注释类型,所以标记注释规范之间也存在隐式关联。因此,给定注释类型的标记注释规范是由对给定注释类型的超类型给定的标记注释规范完成的。因此,标记注释规范不必像以前要求的那么完整。标记注释规范是由 AnnotationPreferences 检索的。通过使用 org.eclipse.ui.texteditor.AnnotationPreferenceLookup,您可以检索给定注释类型的注释首选项,这将按注释超类型链透明地执行首选项的完成。

标记注释规范已经扩展了三个附加属性以允许在垂直标尺中定义给定注释类型的定制外观。这些属性包括“icon”、“symbolicIcon”和“annotationImageProvider”。“icon”的值是指向包含图标图像的文件的路径。“symbolicIcon”的值可以是“error”、“warning”、“info”、“task”和“bookmark”。属性“symbolicIcon”用于告诉平台注释应该使用平台分别用来表示错误、警告、信息、任务和书签的图像来表示。“annotationImageProvider”的值为实现 org.eclipse.ui.texteditor.IAnnotationImageProvider 的类,它允许进行完整定制注释表示。

垂直标尺使用其相关联的 IAnnotationAccess/IAnnotationAccessExtension 来绘制注释。垂直标尺不会再调用 Annotation.paint。一般说来不再建议由注释自己绘制自己。已经不推荐使用“paint”和“getLayer”方法以使注释最终与用户界面无关。DefaultMarkerAnnotationAccess 充当 IAnnotationAccess/IAnnotationAccessExtension 的缺省实现。DefaultMarkerAnnotationAccess 实现以下策略来绘制注释:如果注释实现 IAnnotationPresentation,则调用 IAnnotationPresentation.paint。如果注释未实现它,则注释图像提供程序将在注释首选项中进行查找。仅当已经指定注释图像提供程序并且已经装入定义外层标记注释规范的插件时,该提供程序才可用。如果存在注释图像提供程序,会向其转发调用。如果该提供程序不存在,将查找指定的“icon”。“symbolicIcon”用作最终回退。对于绘制注释,注释表示层是相关联的。DefaultMarkerAnnotationAccess 使用以下策略查找表示层:如果注释首选项指定表示层,将使用指定层。如果没有任何层且 注释实现了 IAnnotationPresentation,将使用 IAnnotationPresentation.getLayer,否则返回缺省表示层(为 0)。

迁移至 annotationTypes 扩展点(插件 org.eclipse.ui.editors)

下列注释类型是由 org.eclipse.ui.editors 插件声明的:

   <extension point="org.eclipse.ui.editors.annotationTypes">
      <type
         name="org.eclipse.ui.workbench.texteditor.error"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="2">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.warning"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="1">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.info"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="0">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.task"
         markerType="org.eclipse.core.resources.taskmarker">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.bookmark"
         markerType="org.eclipse.core.resources.bookmark">
      </type>
</extension>

定义的 markerAnnotationSpecification 扩展不再提供“markerType”和“markerSeverity”属性。它们使用相应的值定义“symbolicIcon”属性。因此不会再调用 MarkerAnnotation.paint 和 MarkerAnnotation.getLayer,即覆盖这些方法不会有任何影响。受影响的客户机应实现 IAnnotationPresentation。

ILaunchConfigurationType(org.eclipse.debug.core 包)

在 3.0 中引入了可扩展启动方式之后,一个启动配置类型可有多个启动代表存在。对于每个启动配置类型,3.0 之前的发行版仅支持一个启动代表。现在不推荐使用方法 ILaunchConfigurationType.getDelegate()。应在适当位置使用方法 getDelegate(String mode) 以检索特定启动方式的启动代表。不推荐使用的方法已更改为返回 run 方式的启动代表。

ILaunchConfigurationTab 和 ILaunchConfigurationTabGroup(org.eclipse.debug.ui 包)

启动完成时,将不再通知启动选项卡组和启动选项卡。不推荐使用接口 ILaunchConfigurationTabILaunchConfigurationTabGroup 中的方法 launched(ILaunch),而且也不再调用它们。依赖于启动功能的此方法总是会有问题,这是因为选项卡仅在从启动对话框中执行启动时才存在。而且,随着后台启动的引入,将不再调用此方法,因为还未生成启动对象启动对话框就关闭了。

ILaunchConfigurationTab 和 AbstractLaunchConfigurationTab(org.eclipse.debug.ui 包)

已经有两个方法添加至 ILaunchConfigurationTab 接口 - 激活和释放。在分别进入和退出选项卡时,将调用这些新的生命周期方法。对调试插件(AbstractLaunchConfigurationTab)提供的抽象类划分子类的 ILaunchConfigurationTab 的现有实现符合二进制格式,因为这些方法是在抽象类中实现的。

在之前的发行版中,激活选项卡时将发出消息 initializeFrom,释放该选项卡时将发出消息 performApply。这样一来,启动配置选项卡框架就提供了通过启动配置进行的选项卡间通信(通过在退出选项卡时以当前属性值更新配置并更新新进入的选项卡)。但是,因为许多选项卡未执行选项卡间通信,所以这可能还不够。而且无法区分要激活的选项卡与第一次显示所选启动配置的选项卡。新添加的方法允许选项卡区分激活与初始化以及释放与保存当前值。

抽象选项卡提供的 activated 的缺省实现将调用 initializeFrom。而 deactivated 缺省实现调用 performApply。希望利用新的 API 的选项卡应在必要时覆盖这些方法。对于不执行选项卡间通信的选项卡,通常建议的方法是重新实现这些方法以不执行任何操作。

launchConfigurationTabGroup 扩展点类型(org.eclipse.debug.ui 包)

在之前的发行版中,透视图切换是在启动配置中通过启动配置属性 ATTR_TARGET_DEBUG_PERSPECTIVEATTR_TARGET_RUN_PERSPECTIVE 指定的。在 3.0 中加入了可扩展启动方式之后,此方法就不再用得上了。透视图切换现在是根据启动配置类型指定的(针对启动配置类型支持的每个启动方式)。已向 DebugUITools 添加了 API 以针对特定启动方式设置并获取与启动配置类型相关联的透视图。

附加可选 launchMode 元素已添加至 launchConfigurationTabGroup 扩展点以允许添加的选项卡组对启动配置类型和方式指定缺省透视图。

从 Eclipse 用户界面中,用户可通过打开启动配置对话框并在树中选择启动配置类型节点(而不是单独配置)编辑与启动配置类型相关联的透视图。将显示一个选项卡,它允许用户以每个受支持的启动方式设置透视图。

[JDT only] IVMRunner(org.eclipse.jdt.launching 包)

已向 VMRunnerConfiguration 类添加了两个方法以支持设置和检索环境变量。IVMRunner 的实现者应调用 VMRunnerConfiguration.getEnvironment() 并将该环境传送至已执行 JVM。使用 DebugPlugin.exec(String[] cmdLine, File workingDirectory) 的客户机可通过改为调用 DebugPlugin.exec(String[] cmdLine, File workingDirectory, String[] envp) 来完成此任务。只需要传递 getEnvironment() 中的结果就足够了。

[仅适用于 JDT] VMRunnerConfiguration 和 Bootstrap 类(org.eclipse.jdt.launching 包)

在之前的发行版中,VMRunnerConfiguration 有一个属性用来描述引导路径。该属性是要在 -Xbootclasspath 自变量中指定的一组字符串。已向 VMRunnerConfiguration 添加了三个新的属性以支持允许在引导路径前后加上其它内容的 JVM。新添加的方法/属性如下所示:

旧属性 getBootClassPath() 仍然存在,而且包含等效于这三个新属性的完整路径。但是,支持 新引导路径选项的 VMRunners 应利用新属性。

[仅适用于 JDT] 改进的对工作副本的支持(org.eclipse.jdt.core 包)

Java 模型工作副本设施已在 3.0 中重新编写以使其功能大幅提高。在 3.0 之前,Java 模型允许创建编译单元的各个工作副本。可能对工作副本作了更改然后落实。以前支持在 Java 模型的余下部分的上下文中对工作副本进行有限的分析。但是一次只能对其中一个工作副本进行这些分析。

3.0 中的更改使得能够创建和管理编译单元的工作副本集合并对集合中存在的所有工作副本执行文件。例如,现在可以让象 JDT 重构这样的客户机为一个或多个编译单元创建工作副本,该客户机将考虑修改工作副本之间的类型引用然后解析它们。以前只有在落实对编译单元工作副本的更改之后才能这样做。

两种方法中的 Java 模型 API 更改用于添加这一改进支持:

(1) 先前在 IWorkingCopy 上发现且被 ICompilationUnit 继承的功能已合并到 ICompilationUnit 中。 IWorkingCopy 接口仅在这一位置使用,而且十分通用。此更改简化了 API。已经不推荐使用 IWorkingCopy。API 中 IWorkingCopy 被用作参数或结果类型的其它位置也已经不推荐使用了;替代 API 方法提到 ICompilationUnit 而不是 IWorkingCopy

(2) 接口 IBufferFactory 已经被替换为 WorkingCopyOwner。改进的对工作副本的支持要求存在一个对象拥有这些工作副本。尽管 IBufferFactory 很合适,但该名称没有充分表达新工作副本机制的工作方式。WorkingCopyOwner 更具有提示性。此外,WorkingCopyOwner 被声明为抽象类(而不是接口)以允许工作副本所有者的概念在将来有所变化。IBufferFactory 上的那个方法移至未受影响的 WorkingCopyOwnerWorkingCopyOwner 未实现 IBufferFactory 以明确 IBufferFactory 已经过时了。已经不推荐使用 IBufferFactory 了。API 中 IBufferFactory 显示为参数或结果类型的其它位置也已经不推荐使用了;替代 API 方法提到 WorkingCopyOwner 而不是 IBufferFactory

这些更改无损于二进制兼容性。

在迁移时,对类型 IWorkingCopy 的所有引用应转而引用 ICompilationUnitIWorkingCopy 的单独实现还实现了 ICompilationUnit,这表示类型为 IWorkingCopy 的对象可以安全地强制类型转换为 ICompilationUnit

实现 IBufferFactory 的类需要替换为 WorkingCopyOwner 的子类。尽管 WorkingCopyOwner 未实现 IBufferFactory 本身,但可以声明 WorkingCopyOwner 的子类,它实现 IBufferFactory 从而在新旧对象之间架设了一座桥梁(IBufferFactory 声明 createBuffer(IOpenable),而 WorkingCopyOwner 声明 createBuffer(ICompilationUnit)ICompilationUnit 扩展 IOpenable)。

因为涉及 IWorkingCopyIBufferFactory 的更改相互交错,所以建议同时处理它们。不推荐使用的详细信息如下所示:

重构 org.eclipse.help 插件

org.eclipse.help 插件用来保留向帮助系统添加功能以扩展帮助系统以及显示帮助的 API 和扩展点,该插件现在只包含用于向帮助资源添加功能和访问帮助系统的 API 和扩展点。缺省帮助用户界面实现包含在该插件中的部分已移至新插件 org.eclipse.help.base 与用于扩展实现的 API 在一起。用于向帮助用户界面添加功能和显示帮助的 API 和扩展点已移至 org.eclipse.ui 插件。此重构允许应用程序在使用帮助系统时有更大的灵活性;新结构允许基于一般工作台的应用程序提供它们自己的帮助用户界面和/或帮助实现或者完整省略帮助系统。

因为受影响的扩展点和 API 包仅计划供帮助系统本身使用;所以现有插件不太可能受到此更改的影响。在此处包括它们仅为内容完整起见:

新建搜索用户界面 API

已经在 3.0 中添加了实现定制搜索的新 API。原始 API 在 3.0 中已经不推荐使用,我们建议客户机移植至 org.eclipse.search.ui 和 org.eclipse.search.ui.text 中的新 API。

客户机必须创建 ISearchQueryISearchResultISearchResultPage 的实现。于是 ISearchResultPage 实现必须添加到新的 org.eclipse.search.searchResultViewPages 扩展点中。

ISearchResultISearchResultPage 的缺省实现是在包 org.eclipse.search.ui.text 中提供的。

MessageBox 和 DirectoryDialog 中的空消息(org.eclipse.swt.widgets 包)

在 3.0 之前,以空值字符串调用 SWT 的 DirectoryDialog.setMessage(String string) 或 MessageBox.setMessage(String string) 将导致对话框的标题中没有任何文本。这一行为未被指定(传递空值是不被允许的)并会导致不允许返回空值的 getMessage 出现问题。在 3.0 中,传递空值现在会导致抛出 IllegalArgumentException 异常,而已经更改规范声明了这一点,使用其超类 Dialog.setMessage 上的方法将其纳入行中。如果使用 Dialog.setMessage,则确保传递的字符串永远不是空值。如果想要对话框的标题中没有任何文本,则只传递空字符串。

改进模态进度反馈

支持并发操作需要较为复杂的方法来显示模态进度。作为响应工作的一部分,类 IProgressService 中实现了附加进度支持。使用 ProgressMonitorDialog 显示进度这一现有方法仍然有效。但是,要改进用户的使用体验,建议迁移至新的 IProgressService。

文档在 Eclipse 3.0 中显示模态进度描述如何迁移至新的 IProgressService。

已除去调试操作组

已除去调试操作组扩展点(org.eclipse.debug.ui.debugActionGroups)。在 Eclipse 3.0 中,工作台通过 org.eclipse.platform.ui.activities 扩展点引入对活动的支持。此支持提供调试操作组提供的所有功能,而且更容易使用(它支持模式而不用费力地指定所有操作)并且有程序化的 API 来支持它。如果未能除去对旧的扩展点的引用,也不会导致任何故障。对扩展点的引用只是被忽略。我们鼓励产品供应商使用工作台活动支持以使特定于语言的调试器操作与特定于语言的活动相关联(例如,C++ 调试操作可能与称为“开发 C++”的活动相关联)。

BreakpointManager 可被禁用

IBreakpointManager 现在定义方法 setEnabled(boolean) 和 isEnabled()。当断点管理器被禁用时,调试器应忽略所有已注册断点。调试平台还提供了新的侦听器机制 IBreakpointManagerListener,它允许客户机向断点管理器注册以便在其支持更改时得到通知。断点视图通过新的切换操作调用此 API,这允许用户“跳过所有断点”。如果用户尝试使用此功能,不采用断点管理器支持的调试器因此将会出现某种程序上的中断。

[仅适用于 JDT] Java 搜索参与者(org.eclipse.jdt.core.search 包)

接近 Java 的语言(例如 JSP、SQLJ 和 JWS 等等)应该能够参与 Java 搜索。在特定情况下,这种语言的实现者应该能够:

这种实现器称为搜索参与者。它将扩展 SearchParticipant 类。将传递搜索参与者以搜索查询(请参阅 SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor))。

要建立索引或找到匹配,搜索参与者需要定义 SearchDocument 的子类,它可以通过覆盖 getByteContents() 或 getCharContents() 检索文档的内容。此子类的实例将在 getDocument(String) 中返回。

希望对某个文档建立索引的搜索参与者将使用 SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) 以在给定索引中安排对给定文档建立索引。一旦准备对文档建立索引,底层的框架将调用 SearchParticipant.indexDocument(SearchDocument, IPath)。然后搜索参与者会获取文档的内容,对它进行解析并使用 SearchDocument.addIndexEntry(char[], char[]) 添加索引条目。

一旦完成建立索引,就可查询索引并使用 SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor) 找到匹配项。这会先使用 SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope) 向每个搜索参与者询问此查询所需的索引。对于匹配给定模式的每个索引条目,将通过询问搜索参与者来创建搜索文档(请参阅 getDocument(String))。所有这些文档将传递至搜索参与者,以便它可以使用 locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor) 找到匹配项。搜索参与者通知 SearchRequestor 使用 acceptSearchMatch(SearchMatch) 并传递 SearchMatch 的子类的实例来搜索匹配项。

搜索参与者可将部分工作委托给缺省 Java 搜索参与者。此缺省参与者的实例是使用 SearchEngine.getDefaultSearchParticipant() 获取的。例如,在被要求找到匹配项时,SQLJ 参与者可从其 .sqlj 文档创建 .java 文档并将工作委托给向其传递 .java 文档的缺省参与者。