我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:九肖六肖三肖全年资料 > 取标记组件 >

设计复合应用程序:为 IBM Lotus Notes 编写 Eclipse 组件

归档日期:06-06       文本归类:取标记组件      文章编辑:爱尚语录

  developerWorks 中国 正在向 IBM Developer 过渡。 我们将为您呈现一个全新的界面和更新的主题领域,并一如既往地提供您希望获得的精彩内容。

  编者注:本文是复合应用程序系列文章的第 5 篇。在接下来的几个月中,developerWorks Lotus 还会继续发布本系列的其他文章。查看以前发布的 developerWorks 文章,包括 “设计复合应用程序:单元测试”、“设计复合应用程序:设计模式”、“设计复合应用程序:组件设计” 和 “IBM Lotus Notes V8 中的 Lead Manager 应用程序:概览”。

  复合应用程序是面向服务体系结构(Service-Oriented Architecture,SOA)和上下文协作策略中的关键元素。它们为公司和组织提供业务灵活性,从而能够快速响应当今竞争激烈的市场中的需求变化。复合应用程序由松散耦合的用户界面 (UI) 组件组成,支持组件之间的通信。

  组件可以在多个复合应用程序中重用。能够将多种技术组合成一个应用程序,这种能力可以提供巨大的商业价值。它可以保护和扩展公司现有的软件资产,增加业务灵活性。与传统的应用程序开发方式相比,创建复合应用程序要容易得多,这帮助公司快速且成本高效地响应业务需求。

  复合应用程序体系结构的这种松散耦合还使位于不同地点的小组可以相互分享工作成果并进行协作。例如,一个部门正在为一家公司开发会计应用程序,而另一个小组正在开发销售趋势跟踪应用程序。复合应用程序的设想是将销售趋势跟踪应用程序中的一些组件添加到会计应用程序中,从而按照会计学的上下文提供相关的资产视图。同样,在销售趋势跟踪应用程序中也可以添加会计应用程序中的组件,从而按照资产的上下文提供会计信息。随着您的公司开发出的复合应用程序越来越多,共享组件的机会会呈指数式增长。这种体系结构的目的就是让整体大于部分之和。

  复合应用程序模型是 IBM WebSphere Portal 开发人员已经熟悉的模型。这种方式已经扩展到 Lotus Notes 8 中,这让 Lotus Notes 开发人员能够在复合应用程序中以组件形式提供他们的 Lotus Notes 应用程序。IBM Lotus Domino Designer 已经可以使用属性代理,并提供一个更直观的用户环境。Lotus Notes 8 还支持插入 Eclipse 组件。复合应用程序可以是 Lotus Notes 组件和 Eclipse 组件的任意组合。这些组件可以同时出现在界面(on-the-glass)集成的同一个用户界面 (UI) 中;如果进行扩展,也可以通过属性代理让组件可以互相操作。可以使用复合应用程序编辑器或 WebSphere Portal 应用程序模板编辑器定义复合应用程序。

  复合应用程序的组件开发不同于传统的 Eclipse 或 Notes 应用程序开发。这种开发的目标是创建具有足够灵活性的组件,让它们可以简便地部署在应用程序中,而不需要做重大修改。

  本文以以上提到的内容为基础并介绍一些 helper 类,这样您就能够快速构建和部署特性丰富、可重用并且基于 Eclipse 的组件。我们讨论的组件在 IBM Lotus Expeditor 和 Lotus Notes 中都可以使用,但为了保持简洁,我们仅在 Lotus Notes 中介绍组件。本文引用的代码可以在发布到复合应用程序组件库 Help - About 文档包含的.cloud 项目中找到。

  组件视图不仅仅是一个 UI。它是一个与外部通信并参与外部活动的程序单元。借助这种通信功能,可以将几个组件视图连接起来,构成一个复合应用程序。现在我们看看 Lotus Expeditor 和 Lotus Notes 平台上一些用于实现复合应用程序的特性。

  。这个特性允许您在组装期间为组件视图设置静态值。拓扑处理程序在运行时使用这些值在 Lotus Notes 客户机上展示组件视图。其他值可能是特定于组件视图的,用于在运行时定制视图的表示和功能。通过在 Lotus Notes 中使用复合应用程序编辑器(Composite Application Editor,CAE),您可以通过 Advanced Component Properties 对话框访问组件视图的属性(见图 1),以在组装期间配置组件视图。

  图 1. CAE 中的 Advanced Component Properties

  例如,标记云组件允许您在组装期间设置高级的组件属性 drawHeader 和 drawFooter。然后组件视图在运行时检查这些属性的值,如果值为 true,就绘制相应的 UI 部分。

  。这个组件允许创建从一个组件视图到另一个组件视图的连接。属性是一个源值,组件视图可以设置它来表示值的变更。操作是一个目标值,组件视图可以表示它所使用的操作。

  。可以在组装期间建立连接,从而将组件视图输出的属性与组件视图中的处理属性变更的行为连接起来。在 Lotus Notes 中,使用 CAE 连接组件。

  在运行时,组件视图可以通知属性代理它的一个属性值已经被更改。属性代理通过向已连接的组件视图传递一个新值进行响应。属性的新值被作为一个参数传递给选中的行为。例如,图 2 中的连接显示了当标记云的选择改变时,如何在运行时传递标记云的 FocusedEntity 值并将其设置为文档查看器的 Set Column Filter 值。

  。属性和行为都涉及到在组件视图中获取或设置数据元素的值。在 Java 中储存数据元素集的常用结构是 JavaBean,它有一个用于传递更改的好机制,这非常方便。注意,除了 JavaBean 之外,还有很多方法可以在 Java 中维护数据模型。使用 JavaBean 不要求具有基于 Eclipse 的组件视图;不过,本文使用这种组件视图作为数据模型的一个例子,因为大部分 Java 程序员都非常熟悉它。这些技巧也适用于其他数据模型。

  在讲解这个例子时,我们将介绍许多 helper 类。尽管我们创建的简单组件视图不需要这些类,但它们可以跨组件重用,在开发更加复杂的组件时非常有用。

  Eclipse 组件视图基于与数据模型结合的 ViewPart。组件视图的每个实例都有它自己的数据模型实例。其他工作就是如何将这些部分连接起来。数据模型与视图连接起来,以向用户显示数据,并允许用户与数据进行交互并更改数据。在后端,数据模型与属性代理连接起来,以将更改传递给数据模型中的值,并监听来自其他组件视图的更改。最后,数据模型还与拓扑处理程序连接起来,以将初始实例的值读取到数据模型中。这个策略与流行的模型-视图-控制器(Model-View-Controller,MVC)设计模式相兼容(见图 3)。

  我们为这个组件视图创建一个标记云组件视图。我们有一个需要公开的 SWT 控件(参见.cloud 包中的 TagCloud.java)。我们使用它来显示讨论数据库中的类别,如图 4 所示。

  第一个重要的决定就是公开哪些数据元素。为简单起见,我们仅讨论两个数据元素:PrimaryData,作为驱动显示模型的键-值对的 HashMap;以及 FocusedEntity,它表示当前持有焦点的标记。例如,图 4 显示了一个复合应用程序,它带有一个讨论数据库 Notes 组件视图和一个标记云。在这里,数据库中所有类别的信息都是按文章的数量排列的,并且将这些信息显示到标记云中。此外,可以在标记云中选择类别,并将这个信息传回到讨论数据库组件视图中。这种方式使用视图过滤,仅显示包含在该类别中的文章。

  对于 Lotus Expeditor 6.x 和 Lotus Notes 8,在 Eclipse 组件和 Lotus Notes 组件之间只能发送字符串形式的属性值。不过,HashMap 一个复杂类型。处理复杂类型的技巧是创建能够在一个简单字符串中表示复杂类型的序列。尽管仅支持基本类型的字符串,但可以添加类型数据来从语义上区分字符串的类型。我们通过这种做法来确保仅将 TagCloudDataString 的值传递到标记云中。因为 FocusedEntity 只是一个键,所以我们使用通用的 xsd:string 类型。

  这个数据模型的最后部分是创建向属性代理描述它的 Web Services Description Language (WSDL) 文件。WSDL 文件描述组件视图的公共接口。CAE 使用它来显示有哪些属性和行为是可以连接的,以及 TagCloudView.wsdl 包含什么。您可以以这个文件为模板,为自己的组件创建 WSDL 文件。

  随 Lotus Domino Designer 附带的属性代理编辑器(Property Broker Editor)提供一个用户界面,您可以通过它定义属性、类型和行为,而不用编写 WSDL 文件。尽管您可以使用编辑器,但理解 WSDL 文件的结构是非常有帮助的。

  Eclipse 集成开发环境 (IDE) 框架还提供一个图形 WSDL 编辑器。但这个编辑器使用 WSDL 格式的文件定义 Web 服务。尽管复合应用程序也使用这种格式,但它的用法大不相同,所以 Eclipse IDE 编辑器并不总是最好的选择。

  types 决定属性的类型。在这个实现中,它们都是字符串;不过在 WSDL 文件中我们可以为其添加一个语义类型。这些语义类型在各个组件之间要保持一致。您只能在相同语义类型的属性和行为之间创建连接。对于 PrimaryData 属性,我们决定调用格式 TagCloudDataType。我们在 types 元素中声明它,如清单 2 所示。

  注意:属性除了需要具有相同的语义类型之外,还必须在相同的名称空间中。要确保多个组件的 WSDL 文件中使用一致的名称空间。

  消息是参数的集合,这些参数用作确定函数调用的输入和输出值的配置文件。每个 getter 和 setter 都必须有一个消息,如清单 3 所示。

  对于其他元素,再添加这两条相同的消息,并将 PrimaryData 更改为您的属性的基本名称,然后将 TagCloudDataType 添加到属性的类型。或者对通用的字符串类型使用 xsd:string。

  port 类型将操作连接到消息以获取输入和输出参数。因为我们是为 bean 处理简单的访问方法,所以包含一个输入消息的 setter 和包含一个输出消息的 getter 都有一个 portType。如清单 4 所示。

  最后,我们在 binding 元素中创建操作(见清单 5)。这些元素完整地定义配置文件并引用前面定义的结构。我们还为这些属性声明标题和描述。在 CAE 中将用此进行显示。(注意,您可以使用传统的位置命名模式,声明一个 WSDL 文件和一个 Properties 文件。在标题或描述前面添加 % 表明 CAE 应该在适当的属性文件中查找位置的值)。

  对于其他属性,复制两个 operation 标记,将 PrimaryData 更改为您的属性的基本名称,并添加适当的描述。

  注意,在这个例子中,我们为数据类型公开 set 和 get 访问函数。对于 FocusedEntity,同时公开这两个函数是有必要的。外部组件视图可以告诉这个组件视图应该将焦点放在哪里。如果用户单击相应的区域,这个组件视图可以将这个新的选择传递给其他组件视图。

  显然,我们希望能够在这个组件视图上设置 PrimaryData,但是在其他组件中是否设置它并不明显。因为组装在组件创建之后才发生,并且组装也可能由其他人在完全不同的应用程序中进行,所以值得考虑公开这些东西,尽管目前还没有用到它们。最好在开始构建时就考虑到灵活性。

  我们已经创建并定义数据模型,现在必须通过编程的方式将它们连接到属性代理机制。

  在这里,我们引入 PBBroadcast.java helper 类,以管理从数据模型到属性代理的属性变更的传递(见清单 6)。该类构建完成之后,我们将它传递到数据模型 bean 中与之关联的视图。在构造器中,它作为一个附加到 bean 中。

  当 bean 中的某个值发生变化时,将调用 propertyChange() 方法。为了传递已经变化的值,我们需要组装一组属性-值对,并将它们发布到代理。在这个简单的例子中,我们仅处理一个属性变更。在更加具体的实现中,可以同时发布多个属性变更。

  在清单 6 的第一行代码中,我们使 PropertyBroker Property 类与属性对应,该属性来自事件中已变更的属性名。在第二行代码中,我们创建一个数组来储存变更的值。在第三行中,我们从事件中已变更的属性的值创建 PropertyValue 对象。在最后一行中,我们将已变更的值传递给属性代理。(为了保持简洁,这里省略了错误检查代码。参见源代码获得完整细节)。

  每个组件视图必须有一个注册处理程序,以接收属性变更通知。我们通过 PBHandler.java helper 类帮助管理这件事情。由于该类是由 Lotus Expeditor 框架构造的,所以不能使用我们的数据模型初始化这个特定的实例。事实上,组件视图的所有实例都使用相同的处理程序。然而事件通知包含关于哪个 Eclipse 视图是通知目标的信息。我们将获取这个 Eclipse 视图,用它实现 IDataProvider helper 接口,然后通过该接口获取数据模型。然后提取已变更的属性的名称和新的值,并将它们传递给一个函数,该函数通过反射对值进行设置(见清单 7)。

  在清单 7 的第二行中,我们将事件连接到特定于该操作的 PropertyChangeEvent。在第三行中,我们从事件中提取连接,并从连接中提取视图 ID,接着使用 SWTHelper 从该框架查找 Eclipse 视图。在第五行中,我们使用数据模型(从视图提取)、已变更的属性的名称(从事件的操作定义提取)和新的值(从事件提取)调用 setValue helper 函数。(为了保持简洁,这里省略了错误检查代码。参见源代码获得完整细节)。

  TopologyHelper 能够帮助在数据模型中设置初始值。它包含一个负责初始化的静态函数。将该函数传递到插件上下文、数据模型和视图的 ID。这个函数访问 TopologyHandler,提取专门为组件视图(通过视图 ID 识别)设置的键,并为每个键查找值,然后尝试将这些键设置到数据模型中(见清单 8)。

  在清单 8 中,前两行从上下文中获取 TopologyHandler。第三、第四行获取特定于这个组件视图的设置。然后循环遍历这些设置。在循环内部,我们为遍历到的键提取值,然后使用在 PBHandler 中定义的 helper 函数通过反射将该值放置到 bean 中。

  我们通过将所有这些 helper 类与数据模型一起使用,从而创建自己的 View 类。框架使用该类扩展 ViewPart,而我们使用该类实现 IDataProvider 接口,随后需要从该接口获取数据模型:

  当构造 PBBroadcast 类时,我们在创建数据模型之后创建该类的一个实例。我们向该实例传递视图、数据模型和所用的名称空间的列表。因为该类自己会连接到数据模型,所以我们不需要保留一个指向它的引用(见清单 9)。

  首先,我们在第一行中创建实际的控件并将其放到我们的视图中。其次,我们为数据模型的变更注册一个,以建立一个从数据模型到控件的连接。当接收到变更时,它会进行处理(如果需要,还会改变格式)并将其传递给控件。

  第三,我们建立从控件到数据模型的连接。这个过程与前面的步骤一样,不过当检测到变更时,则将其传递回去。最后,我们使用一些 helper 函数完成一些设置。registerData() 方法将数据模型绑定到一个内部映射,让操作处理程序能够找到它。TopologyHelper 类中的初始化函数和 setupNames() 函数帮助为数据模型设置默认值。因为数据模型已经和控件连接,所以这些值会自动传播。

  因为每个组件视图需要一个惟一的处理程序,我们必须创建一个 TagCloudHandler 类,然后用它创建 PBHandler helper 类的子类。不需要为它添加任何方法。我们不能直接使用 PBHandler helper 类,因为操作的调用由它的处理程序的类名决定。子类使用惟一的类名,并且使实际的处理具有通用性。

  现在,所有代码已经完成,我们必须通过填充一个扩展点让 PropertyHandler 知道已经准备就绪。我们在 com.ibm.rcp.propertybroker.ProperBrokerAction 扩展点下面创建一个扩展,并填充类字段,使其指向处理程序。然后再填充文件字段,使其指向 WSDL 文件(见图 5)。

  最好异步访问 Lotus Notes 数据。当您需要查找数据时,使用 NotesThread 对象执行查找。查找完成之后,如果数据涉及到 UI 更新,记得将该更新添加到一个与 UI 线程一起运行的线 中的代码为模板。您可以看看 Lead Manager 示例附带的.leadbrow 包,它提供一个例子。

  在您的数据模型中创建其他字段和 accessor 函数。在这个过程中,您必须确保 accessor 函数通过 JavaBean 属性变更机制传递更改。此外,如果需要的话,使用惟一的类型定义将这些值添加到您的 WSDL 文件中。

  将这些字段连接到 ViewPart,从而可视化这些新的值。如果适当的话,可以允许用户更改这些值。确保新的值被传递时,不需要进行任何更改。

  PBBroadcast helper 类监听 JavaBean 的所有更改,并且只要这些字段的名称与 WSDL 文件中定义的名称保持同步,它们就能正确传递。同样,从其他组件视图接受这些值的更改时,不需要进行任何更改。将它们的值添加到 WSDL 文件,确保它们能够连接起来。PBHandler 类接受这些值并通过内省(introspection)将它们绑定到数据模型。

  注意:我们建议每个插件只放置一个组件视图。WSDL 文件与组件相关联,这意味着所有声明的值对同一个插件内的所有组件视图都是有效的。当在 CAE UI 中只引用一个组件视图时,显示来自不同组件的属性可能会造成混乱,但在每个插件中仅放置一个组件视图能够解决这个问题。

  添加其他组件时,重复这些步骤即可。OpenNTF 库中所有基于 Eclipse 的插件都是以这种方式完成的,从而为您提供大量例子,您可以根据需求复制和更改它们。

  通过这个练习,我们介绍了几个 helper 函数,它们创建的组件可以部署到复合应用程序中。此外,我们还演示了如何构建一个基础组件,您可以基于它快速便捷地创建其他组件。在简单的组件中,还用不到这些函数,因为简单组件的代码就包含了这些步骤,或者可以找到其他方式实现这些 API 的通用用法。在这里,使用这些函数的目的是帮助您超越简单的组件,建立自己的第一套组件。

本文链接:http://odigallery.com/qubiaojizujian/142.html