org.eclipse.ui.elementFactories

元素生成器用来根据在关闭工作台期间所保存的数据来重新创建工作台模型对象。

在仔细研究元素生成器扩展之前, 我们需要复查在整个平台中用来将特定于插件的行为添加到公共平台模型对象中的综合技术。

IAdaptables 和工作台适配器

当浏览各种工作台类时,您将注意到许多工作台接口都扩展了 IAdaptable 接口。

插件使用适配器来将特定行为添加到系统中预先存在的类型中。例如,工作台可能想要将行为添加到资源中, 以便使它们应答标号和图像,以便在 UI 中显示它们自己。我们知道,将特定于 UI 的行为添加到低级别对象中并不是很好的设计, 那么,可以如何将此行为添加到资源类型中呢?

平台定义了一种技术,用来动态地查询对象以获取特定接口的实现。插件可以注册适配器,适配器会将行为添加到预先存在的类型中。这样,以后在特定上下文中使用某个对象时, 应用程序代码就可以查询特定适配器以便找到该对象。如果为它注册了一个适配器, 则它们可以获得该适配器并使用在该适配器中定义的新行为。

通过提供设施来动态地查询适配器以获取对象, 我们还可以在系统扩展时提高系统的灵活性。可以由新插件来为平台类型注册新的适配器,而不需要更改原始类型的定义。该模式将要求对象提供特定适配器。

//给定对象 o,我们想要对其处理有关“工作台”的事项。
if (!(o instanceof IAdaptable)) {
    return null;
}
IWorkbenchAdapter adapter = (IWorkbenchAdapter)o.getAdapter(IWorkbenchAdapter.class);
if (adapter == null)
    return null;
// 现在我可以将 o 视作 IWorkbenchAdapter
...

如果没有为手中的对象注册适配器,则将返回 null 来作为适配器。客户机必须准备处理这种情况。这允许客户机妥善地处理尚未注册期望的适配器的情况。

工作台使用适配器来从基本平台类型中获得 UI 信息,例如 IResource。这就避免了基本类型需要了解 UI 的特定知识, 并允许工作台扩展其接口,而不需要更改基本类型的定义。

如果没有适配器,则在工作台 API 中可能传送的任何类都将需要实现 UI 接口。这会将类定义集中到一起并引入紧密耦合。它在核心与 UI 类之间引入了循环关系。借助适配器,每个类都实现了 IAdaptable, 并使用适配器注册表来允许插件扩展基本类型的行为。

在整个工作台代码中,您将看到通过类型来查询适配器的情况。这一切都是为了获取对象,以便知道如何应答有关平台核心类型的,面向 UI 的信息。

元素生成器

当用户关闭工作台时,它必须保存工作台中显示的 IAdaptable 对象的当前状态。这是通过以特殊格式 IMemento 来保存对象的基元数据参数来完成的,它很容易保存在文件系统中。还将存储可以根据 IMemento 来重新创建对象的生成器的标识。

重新启动平台时,工作台会查找与在备忘录中知道的生成器标识相关联的元素生成器。它通过检查 org.eclipse.ui.elementFactories 扩展的添加项的插件注册表来查找生成器。

标记相当简单。我们只需要指定生成器的标识以及实现该生成器的相应的类。

以下代码片段来自于工作台 plugin.xml

<extension
    point = "org.eclipse.ui.elementFactories">
    <factory id ="org.eclipse.ui.internal.model.ResourceFactory"
        class="org.eclipse.ui.internal.model.ResourceFactory">
    </factory>
    <factory id ="org.eclipse.ui.internal.model.WorkspaceFactory"
        class="org.eclipse.ui.internal.model.WorkspaceFactory">
    </factory>
    <factory id ="org.eclipse.ui.part.FileEditorInputFactory"
        class="org.eclipse.ui.part.FileEditorInputFactory">
    </factory>
    <factory id ="org.eclipse.ui.internal.dialogs.WelcomeEditorInputFactory"
        class="org.eclipse.ui.internal.dialogs.WelcomeEditorInputFactory">
    </factory>
</extension>