• 在 Lotus Notes 8 中开发复合应用


    在 Notes 8 中开发复合应用

    下载提示

    Lotus Note 8/Domino Designer 8 均有免费试用版可以下载(链接请看 参考资源)。本文所用范例及其源码均提供 下载,可在 Notes 8 中部署运行,建议读者切身感受一下复合应用带来的全新用户体验。

    作为 Lotus 的售前工程师,回顾整个 2007 年,我最经常被客户和合作伙伴问到的问题是:你认为 Domino/Notes 8( 以下简称 ND 8) 中最大的技术突破是什么?是生产力工具?还是对 DB2 的正式支持 ?

    毫无疑问,上述这些功能都是 ND 8 非常出彩的地方,即使放在整个 ND 的发展史上看也将会占有一席之地。但最终我的答案只有一个:ND8 中最大的突破当然是复合应用(Composite Application)。因为这的确是一种非常有“内涵”和革命性的新型应用模式。

    很难简单的说明复合应用究竟意味着什么?从企业 Web 2.0 的观点,你可以说它代表着混搭 Mashup 的思想;站在企业集成的角度,它是 SOA 在用户前端的具体实现;对用户而言,它是一种全新的界面体验;而对传统的 Lotus 开发者来说,复合应用带给了他们新的挑战和机遇。

    所以无论你出于什么原因打开了 Notes 8 客户端,复合应用都是你绝对无法视而不见的亮点,因为它代表的是 ND 的未来——也许还不仅仅是代表 ND 的未来,而是整个 IBM 软件在企业前端上的未来。


    复合应用的基本定义与 Property Broker 编程模式

    那么什么是复合应用(Composite Application)?一个标准的定义如下:复合应用是 为了满足特定的业务目的而被放在一起的一套组件。如果觉得这个定义太抽象,那么下面这个例子可以给大家一个感性认识。


    图 1. 复合应用范例
    图 1. 复合应用范例

    这是一个用 Notes 8 打开的应用(ComAppTest.NSF),你一眼能看出它和过去你所见到 Notes 的帧结构、视图、表单等等这些元素全不相同但又似曾相识。在这个应用中,你看到了左上方展示新闻列表的 Notes 视图,看到了右下方展示每篇新闻内容的 Notes 表单。此外,你还会看到左下方的图片缩略表,和右上方的图片大图展示,但它们都不是 Notes 元素,而是两个 Eclipse 插件。所有这些东西(当然,它们有个正式的名称——组件),为了一个业务目的(展现新闻内容和图片)而组装在一起,这就构成了一个复合应用

    不只是组装,组件之间还可以传递消息。还是看上面这个例子,当我们点击左上方新闻列表中的某篇新闻时,会把该新闻的新闻编号传递给其他组件,这样右下方的 Notes 表单组件会根据该编号显示新闻的详细信息,右上方的 Eclipse 组件会根据该编号显示新闻的图片内容。这里我们把所传递这个信息叫做“属性”(Property),把各个组件根据外来属性所做的动作称为“操作”(ActionOperation)。通过 Notes 8 环境中提供的 Property Broker 机制,复合应用可以在不同的组件之间传递属性,执行操作。这种编程模式,我们也称之为 Property Broker 的编程模式。


    图 2. Property Broker 编程模型
    图 2. Property Broker 编程模型

    Property Broker 编程模式的基本设计理念总结如下:

    • 属性是类型化的可交换数据
    • 操作是消费属性的行为
    • 组件定义自身的属性和操作
    • 连接(Wire)将属性和操作相关联

    在这种编程模式下,程序的开发很大程度上就是组件的开发。而开发组件首先要定义组件的属性和操作,并把这种定义通过 WSDL 描述出来。然后实现组件属性的发布,以及其他组件如何接收属性并执行对应的操作。开发好组件之后,用户可以把这些组件加入到一个复合应用中去,并通过连接(wire)将类型匹配的属性操作相关联。这样在复合应用运行时,以上图为例,当新闻列表发出了一篇新闻的 News ID 作为属性时,property broker 将通过连接查找到与之相关的组件和操作,并把该 News ID 值传递给相应组件(上例中为缩略图展现组件),由该组件执行缩略图展现操作。

    熟悉 IBM WebSphere Portal 开发的人会意识到,这和 Portal 中的点击即动Click To Action 以下简称 C2A)的功能非常类似。事实上,不只是形似,Notes 8 中的复合应用在实现上与 Portal 的 C2A 也有非常紧密的关系。举个例子,为了描述每个组件的属性和操作,需要有一个 WSDL 描述文件,而 Notes 8 中这个文件的格式几乎完全照搬了 C2A。

    如果探循的再深一些你会发现,整个复合应用的概念最早正是来自于 IBM WebSphere Portal。所以我们强调一点:复合应用并不是绑定到 Notes 8 的一种应用模式。复合应用有很多种实现载体(Portal,Lotus Expeditor 等等),Notes 8 上的复合应用只是其中一种。

    但无论那种模式,复合应用体现了用户前端组件化,标准化的趋势。谁说 SOA 只做企业系统后端的集成?复合应用是对 SOA 前端的一次非常好的诠释。


    复合应用的创建

    用 Notes 8 可以打开两种形式的复合应用,基于 Portal 的和基于 NSF 的,二者的差别主要在于存放应用文件(XML 格式)的方式不同。这里主要介绍基于 NSF 的复合应用。在 Notes 8 中创建一个复合应用是非常简单的一件事情,因为基于 NSF 的复合应用就是一个 NSF 数据库,在创建时,和一个传统的 NSF 数据库没有什么区别。所不同的是选择模板时必须选择空白组合应用程序模板。


    图 3. 在 Notes 8 中创建复合应用
    图 3. 在 Notes 8 中创建复合应用

    创建之后,你将得到一个空白的复合应用页面。接下来点击 操作 中的 编辑复合应用,Notes 8 会启动 CAE(Composite Application Editor)。通过这个工具,你可以把 NSF 组件或者 Eclipse 组件拖拽到这个复合应用的页面上。此外,通过这个工具,你也可以创建多页面的复合应用。


    图 4. 复合应用编辑器
    图 4. 复合应用编辑器

    创建空白复合应用 NSF,然后填充组件,这就是创建一个复合应用的过程。这个过程本身并不复杂。不过随之而来一个非常关键的问题:这些 NSF 组件和 Eclipse 组件是如何开发的?


    NSF 组件的开发

    对一个复合应用的组件而言,最基本的部分是属性和操作。所以对组件的开发而言,最重要的部分也将围绕着属性和操作来进行,大体上可以分为 三个步骤:定义属性和操作,属性的发布,操作的实现

    下面我们将用上面这个复合应用中的两个组件为例,描述 NSF 组件开发的过程。

    这两个 NSF 组件一个是 Notes 视图(ImageNewsList),用于展示新闻列表。一个是 Notes 表单 (ImageDescForm),用于显示新闻具体内容。

    定义属性和操作

    属性和操作的定义过程首先是一个思考的过程:将一个 Notes 元素封装成一个组件,需要它对外发布什么属性,接收什么属性,完成什么操作。这个分析的过程与具体的编码实现同等重要。因为在设计组件时,模块化与可重用性是组件非常关键的要素,所以在构思一个组件时,考虑的不仅仅是实现功能,还应该考虑如何从一个特定功能中抽取出可通用的服务。

    ImageNewsList 是一个非常典型的 NSF 组件。作为一个 Notes 视图,它本身提供了将新闻文档列举的功能,现在考虑把它封装成 NSF 组件,我们希望它能够在单击视图中的每个新闻文档时,对外发送一个属性:该篇新闻的新闻号。


    图 5. NSF 组件——ImageNewsList
    图 5. NSF 组件——ImageNewsList

    为此,我们需要给这个视图所在的 NSF 数据库定义一个 WSDL,在 Domino Designer 8 中增加了这样一个名为“连线属性”的新设计元素。在这个 WSDL 中我们将描述可对外发布的属性 NewsIDChanged。作为一个 XML 文件,WSDL 可以通过文本编辑器直接编写(复合应用的熟练开发者一般青睐这种方式),也可以利用 Domino Designer 8 里附带的 WSDL 可视化编辑器 Property Broker Editor 进行编辑,后者会自动生成 XML 代码。


    图 6. Property Broker Editor——定义属性
    图 6. Property Broker Editor——定义属性

    如图,我们在 WSDL 中直接加入了一个叫 NewsIDChanged属性。该属性的类型是 ImageNewsIDType(这是一个自定义的类型),名称空间是com.ibm.xna。属性叫什么名称并不重要,重要的是名称空间和类型,因为这才是 Property Broker 在匹配属性和操作时的依据。

    该属性在 WSDL 文件中的代码片断如下:


    清单 1. WSDL 中对属性的定义
    				
    <message name="NewsIDChanged_Message">
    <part name="NewsIDChanged_Part" type="cus:ImageNewsIDType"/>
    </message>
    
    

    接下来介绍如何在 WSDL 中定义操作。属性用于对外发布,而操作用于接收属性,所以每一个操作的定义都是和一个属性相关的。ImageDescForm 是一个 Notes 表单,该表单将接收前面定义的这个 NewsIDChanged 属性,并执行一个操作 ShowImageDesc,该操作将在表单中展现新闻号为 NewsIDChanged 的新闻文档的文字信息。


    图 7. NSF 组件——ImageDescForm
    图 7. NSF 组件——ImageDescForm

    这样一个操作在 Property Broker Editor 中的定义如下:


    图 8. Property Broker Editor——定义操作
    图 8. Property Broker Editor——定义操作

    如图,操作 ShowImageDesc 与属性 NewsIDChanged 关联,一旦组件接收到 NewsIDChanged 类型的属性 —— 再次提醒:名称不重要,重要的是类型和名称空间匹配——就会执行 ShowImageDesc 的操作,该操作的具体实现将在后文中提到。

    操作 ShowImageDesc 的定义在 WSDL 中的代码片断如下:


    清单 2. WSDL 中对操作的定义
    				
    <operation name="ShowImageDesc">
     <portlet:action activeOnStartup="true" caption="ShowImageDesc"
     description="Used in tutorial" name="ShowImageDesc"
     selectOnMultipleMatch="false" type="standard"/>
     <input>
     <portlet:param boundTo="request-attribute"
     caption="NewsIDChanged" name="NewsIDChanged" partname="NewsIDChanged"/>
     </input> 
    </operation>
    

    在 WSDL 中定义好属性和操作之后,接下来的问题就是如何在 Notes 元素中实现属性的发布和操作的执行。

    NSF 组件中属性的发布

    ImageNewsList 这个 Note 视图组件而言,有两种方式实现属性 NewsIDChanged 的发布。我们先介绍最简单的一种做法,这也是在这个例子中我们所使用的方法。

    首先我们需要在这个视图中添加一个列,该列的值为新闻文档的新闻号。


    图 9. 在 Domino Desginer 中设计可发布属性的列
    图 9. 在 Domino Desginer 中设计可发布属性的列

    然后选择列属性窗口的 编程栏,赋予一个程序使用的列名称。最重要的是在 编写设置 中选择所要对应的属性:NewsIDChanged。然后保存整个视图即可。这样就可以实现 NewsIDChanged 属性的发布。无需编程,非常方便!


    图 10. 在编写设置中指定所要发布的属性
    图 10. 在编写设置中指定所要发布的属性

    很简单,不是吗?这种方法不需要写任何代码即可在 Notes 视图中实现属性的发布,但目前也只有 Notes 视图可以这样做。如果想在其他 Notes 元素中实现属性的发布,可以通过另一种更加通用的方法:编写 Lotusscript 代码来实现。

    在这个例子中,我们也可以通过 Lotusscript 代码来发布 NewsIDChanged 属性。我们只需在 ImageNewsListOnselect 事件中添加如下的内容:


    清单 3. 发布属性的 Lotusscript 样例代码
    				
    Sub Onselect(Source As Notesuiview)
        ...
        获取选中的文档的 ImageNewsID 域值
        ...
    
        On Error 4719 Goto err4719 // 一旦不是复合应用环境,则跳至报错处
        Dim pb As NotesPropertyBroker // 定义 NotesPropertyBroker 对象
    
        Set pb = s.GetPropertyBroker() 
    
        If Not (pb Is Nothing) Then
            Call pb.setPropertyValue("NewsIDChanged",ImageNewsID ) 
            // 指定要发布的属性名和属性值
    
            Call pb.Publish() // 发布属性
            Exit Sub
    
        End If
    
        Exit Sub
    
        err4719:
        Print "Error" & Str(Err) & ": " &Error$
        Messagebox "It's not run in a Composite context"
    
    End Sub
    

    在代码中我们看到,Notes 8 中新增了一个 Notes 类 NotesPropertyBroker,通过该类,我们可以在 Lotusscript 中获得当前 Notes 8 客户端中的 Property Broker 对象,并执行相应的操作。在发布属性的时候,只要调用 propertyBrokersetPropertyValue 方法写入属性名和属性值,再调用 propertyBrokerpublish方法即可完成属性的发布。同样非常简便!

    了解了如何在 NSF 组件中发布属性之后,下面我们再来看看 NSF 组件中操作是如何获取这些属性值的。

    NSF 组件中操作的实现

    现在我们为 ImageDescForm 来具体实现 ShowImageDesc 操作。该操作将接收到一个值为新闻编号 ImageNewsID 的属性 NewsIDChanged,然后在表单中显示新闻编号为 ImageNewsID 的新闻文档的标题,作者,正文等信息。

    熟悉 Notes 的人知道,Notes 开发中本来就有操作(Action)这种设计元素,为了与之区分,我们称 NSF 组件中的复合应用操作为 WSDL 操作(WSDL Action)。在设计时为了便于 Notes 开发人员使用,创建 WSDL 操作的步骤沿袭了 Notes 操作的创建方法。

    因此,为了实现这个名为 ShowImageDesc 的 WSDL 操作,我们首先要在 ImageDescForm 表单中创建一个普通 Notes 操作 ImageIDChangedAction


    图 11. 在 Domino Designer 中定义 WSDL 操作
    图 11. 在 Domino Designer 中定义 WSDL 操作

    在该操作的高级属性中,我们会发现一个新增设置:“组合设置”,在这里可以选择之前在 WSDL 中定义的操作 ShowImageDesc。通过这样一步简单的操作,一个普通的 Notes 操作 ImageIDChangedAction 就成为了一个 WSDL 操作,实现了ShowImageDesc。(一般情况下,建议将这个操作在操作条上隐藏)。


    图 12. 在组合设置中选择对应的操作名
    图 12. 在组合设置中选择对应的操作名

    接下来我们需要在该操作的 click 事件中添加代码,实现下列内容:

    1. 接收属性 NewsIDChanged
    2. 根据属性 NewsIDChanged 的值,在新闻库中查找到对应新闻编号的新闻文档;
    3. 将该新闻文档的对应域值显示在 ImageDescForm 表单上。

    由于后两步对 Lotus 开发人员并不陌生,这里就不再赘述,在此仅列出接收属性 NewsIDChanged 的 LotusScript 代码,这是整个 WSDL 操作实现过程中最核心的部分:


    清单 4. 接收属性并执行操作的 Lotusscript 代码
    				
    Sub Click(Source As Button)
        ...
        On Error 4719 Goto err4719
        Dim pb As NotesPropertyBroker
        Set pb = session.getPropertyBroker() // 获取 PropertyBroker 对象
    
        Dim pbInputProperty As NotesProperty
        Dim pbcontext As Variant
        pbContext = pb.InputPropertyContext 
        Set pbInputProperty = pbContext(0) // 获取属性
    
        Dim InputPropertyName As String
    
        InputPropertyName = pbInputProperty.Name 
    
        Dim pbvalue As Variant
        pbValue = pb.GetPropertyValue(InputPropertyName) // 获取属性值
        ...
        // 对该属性值进行处理,在表单中显示相应文档标题,作者和内容。
        …
        Exit Sub
    err4719:
        Print "Error" & Str(Err) & ": " &Error$
        Messagebox "error"
        ...
    End Sub
    

    如上,通过 Notes 8 中提供的 PropertyBroker 相关的类和方法,WSDL 操作 ShowImageDesc 操作可以获得属性 NewsIDChanged 的值,存放到变量 pbValue 中。在此基础上,可以对该值进行处理,在表单中显示相应文档标题,作者和内容。

    通过 定义属性和操作,发布属性,实现操作,我们得到了两个 NSF 组件:ImageNewsListImageDescForm。对广大 Notes 用户而言,将 Notes 元素封装成组件的好处在于:用户可以充分利用现有的 Notes 数据库,以模块化,组件化的 SOA 思想对它们加以改造。


    Eclipse 组件的开发

    当然很多情况下,只依靠 NSF 组件构建 Notes 8 复合应用是不够的。在做报表展现,图形处理,以及一些其他业务应用的时候,传统 Notes 开发会遇到一些瓶颈。在 Notes 8 中,我们可以通过 Eclipse 组件来弥补 NSF 组件功能上的不足。

    开发复合应用的 Eclipse 组件需要具有 Eclipse 的插件(plug in)开发技能。关于 Eclipse 插件开发细则以及 Eclipse 组件开发环境的配置,请参考 http://www.eclipse.org 上的相关文档,此处不再赘述。

    与 NSF 组件一样,Eclipse 组件的开发同样遵循着 定义属性和操作,属性的发布,操作的实现 三个步骤。

    定义属性和操作

    ImageView 组件为例,该组件接收 NewsIDChanged 属性(该属性值为新闻号),执行 ShowImage 操作:显示该新闻号对应的新闻的图片。要在 Eclipse 组件中定义该属性和操作,需要执行下列步骤。


    图 13. Eclipse 组件——ImageView
    图 13. Eclipse 组件——ImageView

    首先,创建 WSDL。Eclipse 组件中同样使用 WSDL 来描述组件的属性和操作,并且其格式与 NSF 组件的完全一致。这意味着我们同样可以用前面提到的 Property Broker Editor 这个可视化工具来编写 Eclipse 组件的 WSDL(当你已经熟悉了 Eclipse 中复合应用组件的开发之后,你会更愿意使用文本编辑工具来编辑)。调用 Property Broker Editor 的方法是 <notes install directory>\framework\rcp\rcplauncher.exe -config wsdledit


    图 14. 利用 Property Broker Editor 定义 Eclipse 组件的属性
    图 14. 利用 Property Broker Editor 定义 Eclipse 组件的属性

    利用上图的 Property Broker Editor 工具我们得到了一个描述文件 actions.wsdl。接下来,需要把得到的 action.wsdl 导入到 Eclipse 组件中。在 Eclipse 的项目中,新建一个名为 wsdl(该名称不做限定)的文件夹,把 WSDL 文件导入到该文件夹中。下面这步非常关键:在该 Eclipse 插件的扩展中加入 com.ibm.rcp.propertybroker.PropertyBrokerDefinitions,并在该扩展下新建一个 handler。


    图 15. 扩展 PropertyBrokerDefinitions
    图 15. 扩展 PropertyBrokerDefinitions

    在这里,此扩展将会把描述文件 WSDL 与具体实现类相结合。如下图所示。File 属性指定为我们刚刚生成的 actions.WSDL 文件,Type 处选择 SWT_ACTION,Class 属性则选定将会具体实现 Eclipse 组件的操作的类 com.ibm.xna.actions.ImageViewAction


    图 16. 扩展详细信息
    图 16. 扩展详细信息

    保存后在 Eclipse 插件的 plugin.xml 中会多出如下代码:


    清单 5. Eclipse 组件的 Plug.xml 片断
    				
    <extension 
    id= "com.ibm.xna.properties" 
    name= "xnapbdefs" 
    point= "com.ibm.rcp.propertybroker.PropertyBrokerDefinitions" > 
    …… 
    <handler 
    class= "com.ibm.xna.actions.ImageViewAction" 
    file= "wsdl/actions.wsdl" 
    type= "SWT_ACTION" /> 
    …… 
    </extension> 			
    			

    至此,我们就完成了 Eclipse 组件属性和操作的定义工作。需要强调的是,对某些之前没有接触过 Eclipse 插件开发的 Notes 开发者而言,上述内容也许比较陌生,因为要掌握 Eclipse 中的扩展,扩展点等概念通常需要一些时间。但从长远来看,考虑到这门技术在未来给他们带来的价值,这种技术上的投入毫无疑问是值得的。

    属性的发布

    在 Eclipse 组件中,属性的发布同样也非常简单。这里我们以另一个 Eclipse 组件 SnapshotView 为例,该组件用于展示若干篇新闻的图片缩略图。一方面,它可以接受 ImageNewsList 传递给它的属性,执行缩略图展现的操作;另一方面,当用户点击某篇新闻的缩略图时,它会把该新闻的 NewsID 作为属性发布出去。在这里我们只介绍 SnapshotView 组件中属性发布的实现。


    图 17. 扩展详细信息
    图 17. 扩展详细信息

    在双击某张缩略图时,我们会执行如下的代码:

    PropertyBrokerUtil.publishProperty("com.ibm.xna",viewID, "NewsIDChanged", id);
    

    其中 PropertyBrokerUtil.publishProperty 方法是我们自定义的一个函数,通过该函数,SnapshortView(视图号为viewID)将发送名称空间为 com.ibm.xna,名称为 NewsIDChanged 的属性,值为某篇新闻的编号 id

    该方法的实现代码如下:


    清单 6. 发布属性的 Eclipse 代码
    				
    public void publishProperty(String namespace,String viewID, 
        String property, String value) { 
        PropertyBroker pb = PropertyBrokerFactory. getBroker ();
        // 获取 PropertyBroker 实例 
        PropertyValue[] values = new PropertyValue[1]; 
        try { 
            Property prop = pb.getProperty(namespace, property);
            // 根据名称空间和属性名获取属性 
            if (prop != null ) { 
                values[0] = PropertyFactory. createPropertyValue (prop, value);
                // 生成属性值 
                pb.changedProperties(values, viewID);// 发布属性 
            } 
        } catch (PropertyBrokerException e) { 
            e.printStackTrace(); 
        } 
    }
    			

    在上面这个函数中,我们首先获取一个 Property Broker 的实例,再通过名称空间和属性名获取 Property 实例。实际用来发布属性的方法是 PropertyBrokerchangedProperties 函数,此函数有两个参数,一个是 PropertyValue 数组,用于存放多个要发布的属性值对;另一个是字符串,用于标志属性变化时的上下文,应该与连接(Wiring)源组件的 EntityID 匹配。本例中,该 viewID 是通过 snapShotView.getViewSite().getId() + ":" + snapShotView.getViewSite().getSecondaryId() 拼接而成的。

    如果觉得拼接这个 viewID 麻烦,还有一种做法更加简单。可以使用 SWTHelper (com.ibm.rcp.propertybroker.swt.api.SWTHelper) 类的 changedProperties 函数发布属性。该函数的函数头为:SWTHelper.changedProperties(PropertyValue[] arg0, IViewPart arg1),与 PropertyBroker 的同名函数的不同之处在于,该函数的第二个参数是指向 ViewPart 的指针。如果是在 ViewPart 类内部调用该方法的话,那么很多情况下你只需要简单写一个 this 即可。

    操作的实现

    回到本节一开始介绍的 ImageView 组件,该组件接收 NewsIDChanged 属性(该属性值为新闻号),执行 ShowImage 操作:显示该新闻号对应的新闻的图片。以它为例,接下来我们看看 Eclipse 组件中操作是如何实现的。

    前文提到,在定义 ImageView 的属性和操作时,我们在 Plugin.xml 中指定了 WSDL 操作的实现类 com.ibm.xna.actions.ImageViewAction。该类继承自 org.eclipse.core.commands.AbstractHandler,实现了该类的 excute()方法。

    该方法的代码如下:


    清单 7. 接收属性并操作的 Eclipse 代码
    				
    public Object execute(ExecutionEvent ee) throwsExecutionException {
        Object event = ee.getTrigger();
        if (event instanceof PropertyChangeEvent) {
            // 判断是否是属性更改事件
            PropertyChangeEvent e = (PropertyChangeEvent)event;
            PropertyValue propValue = e.getPropertyValue();
            // 获取属性值
            finalString Val = propValue.getValue().toString();
            Wire wire = e.getWireDefinition();
            String targetName = wire.getTargetName();
            // 获取目标操作名
            if (targetName.equalsIgnoreCase("ShowImage")) {
                // 判断操作名是否匹配
                ……
                IViewPart part = SWTHelper.locateView (SAMPLE_VIEW); ImageView view = 
    			    ( ImageView ) part; view.setVal(Val );
                // 把属性值传递给对应的新闻展示视图,展示图片。
                ……
            }
        }
    returnevent;
    }
    

    从上面的代码可以看到,通过处理 PropertyChangeEvent 类的实例,我们可以得到 ShowImage 操作所接收到的属性值,并对该属性值进行相应的处理。

    简而言之,只要我们对复合应用的 Property Broker 编程模式有了一个比较清晰的认识,那么实现 Eclipse 组件中的操作将会是非常轻松的一件事。

    总的来说,开发 Eclipse 组件对传统的 Notes 开发者是一个全新的挑战,不过作为 Notes 开发者,他们已经习惯于接收种种新鲜事物。举个例子,现在 Notes 开发中常用的 HTML,javascript,Java,Servlet 等技术,在一开始也是和 eclipse 一样,作为一种新技术加入到 Lotus 开发中来的。所以对 Lotus 自身和 Lotus 开发者而言,ND 8 会给他们带来一片新的天地。


    复合应用的组装

    创建好了复合应用,开发好了组件,接下来就可以将这些组件加入到复合应用中,并进行组装了。

    回到复合应用的编辑界面 CAE(Composite Application Editor)中,右边的 sidebar 是组件选用板。PIM 栏中列举出了 Notes 8 中提供的开箱即用的组件,主要是邮件,日历,待办等内容,常规栏中则是用户自定义的组件。右键菜单中点击 添加组件,可以选择 添加 NSF 组件 还是 Eclipse 组件。其中 Eclipse 组件又分为了 来自更新站点的,或者是 来自于本地的 两种。后者在 Eclipse 组件的开发调试过程中使用的比较多,正式使用时,一般会将 Eclipse 组件打包放到一个更新站点上,客户端可以自动下载安装。


    图 18. 组件选用板
    图 18. 组件选用板

    添加 NSF 组件时需要指定组件的名称,描述,以及 Notes URL。如果不熟悉 Notes URL 的写法,可以通过浏览的方式获取对象的 Notes URL。


    图 19. 加入 NSF 组件
    图 19. 加入 NSF 组件 图 19. 加入 NSF 组件

    添加来自更新站点的 Eclipse 组件时需要指定站点描述文件 site.xml 的位置,然后从该站点的可用组件中选择自己想要添加的组件。至于如何将 Eclipse 组件打包并放到更新站点上,请参考相应文档,此处不再赘述。


    图 20. 加入 Eclipse 组件(从更新站点)
    图 20. 加入 Eclipse 组件(从更新站点) 图 20. 加入 Eclipse 组件(从更新站点)

    现在我们就可以通过拖拽的方式将组件选用板上的组件添加到复合应用中去了。各个组件的位置也可以通过拖拽的方式进行调整。


    图 21. 调整组件位置
    图 21. 调整组件位置

    在确定好组件的布局之后,接下来的工作是非常关键的一步:连接。前文我们说到了 Property Broker 编程模式,其中一个基本的设计理念是:组件之间需要进行连接(Wiring)以匹配属性和操作。而 CAE 中提供了可视化的界面帮助开发者快速进行组件之间的连接。


    图 22. 连接(Wiring)
    图 22. 连接(Wiring)

    在复合应用的组件名称处右键点击菜单进入连接界面。在这个图形界面中,用户可以直接在类型匹配(属性名称可以不一致)的属性和操作之间连线,从而将各个组件有机的联系在一起,实现应用的复合。复合,但绝不复杂,大部分的时候,它就是这么简单!


    结束语

    现在你就可以感受一下你刚刚组装完成的这个图片新闻复合应用了。你会感受到,来自于不同系统,由不同技术实现的一组组件,为了某个业务目的被组装到一起,既充分利用了现有资源,又满足了实际需求,既改进了用户的界面体验,又颠覆了传统的前端整合模式。这,就是复合应用。它带给你的震撼将不仅仅是 Notes 应用的扩展,更确切的说,它是一次企业前端的革命;它所承担的也不仅仅是 Lotus 的未来,更确切的说,它是 IT 前端整合的未来。所以无论你现在是否是 Notes 用户,复合应用都是值得你关注的一门技术。

    组件独立开发,以服务的形式定义接口,在不同的应用中扮演不同的角色;应用以松耦合的方式对组件进行组装,应用开发者不用再关心各个组件的底层实现——复合应用的构建模式体现了 SOA 中模块化,标准化的思想。从这个层面上说,复合应用的开发让“SOA”这个对许多开发者而言有些雾里看花的概念变得非常具体。还在等什么?赶紧打开你的 Notes 8 开始你自己的复合应用之旅吧!



    下载

    描述 名字 大小 下载方法
    本文范例及其源码 demo.zip 3 MB HTTP

    关于下载方法的信息


    参考资料

    学习

    获得产品和技术

    讨论

    关于作者

    陈原,IBM 软件部 Lotus 高级工程师,具有多年的企业协作类项目的咨询经验,为金融,制造,流通等多个领域的客户提供过协作类项目支持。近来关注于 SOA,Web 2.0 等理念与企业前端的融合,并基于 IBM Notes 8 这一最新协作平台为部分客户成功设计规划了新一代企业级前端雏形。

  • 相关阅读:
    [译]async/await中使用阻塞式代码导致死锁
    C# 对象与JSON字符串互相转换的三种方式
    C# form 传参数的几个方法
    C# 跨线程调用控件的4中方法
    Task的取消
    Task总结
    一个开发10年程序员论:学习Python最正确的步骤
    阿里大神总结的Python基础知识实例,超详细
    十条Python面试题陷阱,看看你是否会中招
    Python程序员编程10大原则,请牢牢记住,避免吃亏
  • 原文地址:https://www.cnblogs.com/hannover/p/1899762.html
Copyright © 2020-2023  润新知