在 Lotus Notes 8 中开发复合应用文档格式.docx
《在 Lotus Notes 8 中开发复合应用文档格式.docx》由会员分享,可在线阅读,更多相关《在 Lotus Notes 8 中开发复合应用文档格式.docx(23页珍藏版)》请在冰豆网上搜索。
如果觉得这个定义太抽象,那么下面这个例子可以给大家一个感性认识。
图1.复合应用范例
这是一个用Notes8打开的应用(ComAppTest.NSF),你一眼能看出它和过去你所见到Notes的帧结构、视图、表单等等这些元素全不相同但又似曾相识。
在这个应用中,你看到了左上方展示新闻列表的Notes视图,看到了右下方展示每篇新闻内容的Notes表单。
此外,你还会看到左下方的图片缩略表,和右上方的图片大图展示,但它们都不是Notes元素,而是两个Eclipse插件。
所有这些东西(当然,它们有个正式的名称——组件),为了一个业务目的(展现新闻内容和图片)而组装在一起,这就构成了一个复合应用。
不只是组装,组件之间还可以传递消息。
还是看上面这个例子,当我们点击左上方新闻列表中的某篇新闻时,会把该新闻的新闻编号传递给其他组件,这样右下方的Notes表单组件会根据该编号显示新闻的详细信息,右上方的Eclipse组件会根据该编号显示新闻的图片内容。
这里我们把所传递这个信息叫做“属性”(Property),把各个组件根据外来属性所做的动作称为“操作”(Action或Operation)。
通过Notes8环境中提供的PropertyBroker机制,复合应用可以在不同的组件之间传递属性,执行操作。
这种编程模式,我们也称之为PropertyBroker的编程模式。
图2.PropertyBroker编程模型
PropertyBroker编程模式的基本设计理念总结如下:
∙属性是类型化的可交换数据
∙操作是消费属性的行为
∙组件定义自身的属性和操作
∙连接(Wire)将属性和操作相关联
在这种编程模式下,程序的开发很大程度上就是组件的开发。
而开发组件首先要定义组件的属性和操作,并把这种定义通过WSDL描述出来。
然后实现组件属性的发布,以及其他组件如何接收属性并执行对应的操作。
开发好组件之后,用户可以把这些组件加入到一个复合应用中去,并通过连接(wire)将类型匹配的属性和操作相关联。
这样在复合应用运行时,以上图为例,当新闻列表发出了一篇新闻的NewsID作为属性时,propertybroker将通过连接查找到与之相关的组件和操作,并把该NewsID值传递给相应组件(上例中为缩略图展现组件),由该组件执行缩略图展现操作。
熟悉IBMWebSpherePortal开发的人会意识到,这和Portal中的点击即动(ClickToAction以下简称C2A)的功能非常类似。
事实上,不只是形似,Notes8中的复合应用在实现上与Portal的C2A也有非常紧密的关系。
举个例子,为了描述每个组件的属性和操作,需要有一个WSDL描述文件,而Notes8中这个文件的格式几乎完全照搬了C2A。
如果探循的再深一些你会发现,整个复合应用的概念最早正是来自于IBMWebSpherePortal。
所以我们强调一点:
复合应用并不是绑定到Notes8的一种应用模式。
复合应用有很多种实现载体(Portal,LotusExpeditor等等),Notes8上的复合应用只是其中一种。
但无论那种模式,复合应用体现了用户前端组件化,标准化的趋势。
谁说SOA只做企业系统后端的集成?
复合应用是对SOA前端的一次非常好的诠释。
复合应用的创建
用Notes8可以打开两种形式的复合应用,基于Portal的和基于NSF的,二者的差别主要在于存放应用文件(XML格式)的方式不同。
这里主要介绍基于NSF的复合应用。
在Notes8中创建一个复合应用是非常简单的一件事情,因为基于NSF的复合应用就是一个NSF数据库,在创建时,和一个传统的NSF数据库没有什么区别。
所不同的是选择模板时必须选择空白组合应用程序模板。
图3.在Notes8中创建复合应用
创建之后,你将得到一个空白的复合应用页面。
接下来点击操作中的编辑复合应用,Notes8会启动CAE(CompositeApplicationEditor)。
通过这个工具,你可以把NSF组件或者Eclipse组件拖拽到这个复合应用的页面上。
此外,通过这个工具,你也可以创建多页面的复合应用。
图4.复合应用编辑器
创建空白复合应用NSF,然后填充组件,这就是创建一个复合应用的过程。
这个过程本身并不复杂。
不过随之而来一个非常关键的问题:
这些NSF组件和Eclipse组件是如何开发的?
NSF组件的开发
对一个复合应用的组件而言,最基本的部分是属性和操作。
所以对组件的开发而言,最重要的部分
也将围绕着属性和操作来进行,大体上可以分为三个步骤:
定义属性和操作,属性的发布,操作的实现。
下面我们将用上面这个复合应用中的两个组件为例,描述NSF组件开发的过程。
这两个NSF组件一个是Notes视图(ImageNewsList),用于展示新闻列表。
一个是Notes表单(ImageDescForm),用于显示新闻具体内容。
<
Aname=N10147>
定义属性和操作
属性和操作的定义过程首先是一个思考的过程:
将一个Notes元素封装成一个组件,需要它对外发布什么属性,接收什么属性,完成什么操作。
这个分析的过程与具体的编码实现同等重要。
因为在设计组件时,模块化与可重用性是组件非常关键的要素,所以在构思一个组件时,考虑的不仅仅是实现功能,还应该考虑如何从一个特定功能中抽取出可通用的服务。
ImageNewsList是一个非常典型的NSF组件。
作为一个Notes视图,它本身提供了将新闻文档列举的功能,现在考虑把它封装成NSF组件,我们希望它能够在单击视图中的每个新闻文档时,对外发送一个属性:
该篇新闻的新闻号。
图5.NSF组件——ImageNewsList
为此,我们需要给这个视图所在的NSF数据库定义一个WSDL,在DominoDesigner8中增加了这样一个名为“连线属性”的新设计元素。
在这个WSDL中我们将描述可对外发布的属性NewsIDChanged。
作为一个XML文件,WSDL可以通过文本编辑器直接编写(复合应用的熟练开发者一般青睐这种方式),也可以利用DominoDesigner8里附带的WSDL可视化编辑器PropertyBrokerEditor进行编辑,后者会自动生成XML代码。
图6.PropertyBrokerEditor——定义属性
如图,我们在WSDL中直接加入了一个叫NewsIDChanged属性。
该属性的类型是ImageNewsIDType(这是一个自定义的类型),名称空间是com.ibm.xna。
属性叫什么名称并不重要,重要的是名称空间和类型,因为这才是PropertyBroker在匹配属性和操作时的依据。
该属性在WSDL文件中的代码片断如下:
清单1.WSDL中对属性的定义
代码:
messagename="
NewsIDChanged_Message"
>
partname="
NewsIDChanged_Part"
type="
cus:
ImageNewsIDType"
/>
/message>
接下来介绍如何在WSDL中定义操作。
属性用于对外发布,而操作用于接收属性,所以每一个操作的定义都是和一个属性相关的。
ImageDescForm是一个Notes表单,该表单将接收前面定义的这个NewsIDChanged属性,并执行一个操作ShowImageDesc,该操作将在表单中展现新闻号为NewsIDChanged的新闻文档的文字信息。
图7.NSF组件——ImageDescForm
这样一个操作在PropertyBrokerEditor中的定义如下:
图8.PropertyBrokerEditor——定义操作
如图,操作ShowImageDesc与属性NewsIDChanged关联,一旦组件接收到NewsIDChanged类型的属性——再次提醒:
名称不重要,重要的是类型和名称空间匹配——就会执行ShowImageDesc的操作,该操作的具体实现将在后文中提到。
操作ShowImageDesc的定义在WSDL中的代码片断如下:
清单2.WSDL中对操作的定义
operationname="
ShowImageDesc"
portlet:
actionactiveOnStartup="
true"
caption="
description="
Usedintutorial"
name="
selectOnMultipleMatch="
false"
standard"
input>
paramboundTo="
request-attribute"
caption="
NewsIDChanged"
partname="
/input>
/operation>
在WSDL中定义好属性和操作之后,接下来的问题就是如何在Notes元素中实现属性的发布和操作的执行。
NSF组件中属性的发布
对ImageNewsList这个Note视图组件而言,有两种方式实现属性NewsIDChanged的发布。
我们先介绍最简单的一种做法,这也是在这个例子中我们所使用的方法。
首先我们需要在这个视图中添加一个列,该列的值为新闻文档的新闻号。
图9.在DominoDesginer中设计可发布属性的列
然后选择列属性窗口的编程栏,赋予一个程序使用的列名称。
最重要的是在编写设置中选择所要对应的属性:
NewsIDChanged。
然后保存整个视图即可。
这样就可以实现NewsIDChanged属性的发布。
无需编程,非常方便!
图10.在编写设置中指定所要发布的属性
很简单,不是吗?
这种方法不需要写任何代码即可在Notes视图中实现属性的发布,但目前也只有Notes视图可以这样做。
如果想在其他Notes元素中实现属性的发布,可以通过另一种更加通用的方法:
编写Lotusscript代码来实现。
在这个例子中,我们也可以通过Lotusscript代码来发布NewsIDChanged属性。
我们只需在ImageNewsList的Onselect事件中添加如下的内容:
清单3.发布属性的Lotusscript样例代码
SubOnselect(SourceAsNotesuiview)
...
获取选中的文档的ImageNewsID域值
OnError4719Gotoerr4719//一旦不是复合应用环境,则跳至报错处
DimpbAsNotesPropertyBroker//定义NotesPropertyBroker对象
Setpb=s.GetPropertyBroker()
IfNot(pbIsNothing)Then
Callpb.setPropertyValue("
ImageNewsID)
//指定要发布的属性名和属性值
Callpb.Publish()//发布属性
ExitSub
EndIf
err4719:
Print"
Error"
&
Str(Err)&
"
:
Error$
Messagebox"
It'
snotruninaCompositecontext"
EndSub
在代码中我们看到,Notes8中新增了一个Notes类NotesPropertyBroker,通过该类,我们可以在Lotusscript中获得当前Notes8客户端中的PropertyBroker对象,并执行相应的操作。
在发布属性的时候,只要调用propertyBroker的setPropertyValue方法写入属性名和属性值,再调用propertyBroker的publish方法即可完成属性的发布。
同样非常简便!
了解了如何在NSF组件中发布属性之后,下面我们再来看看NSF组件中操作是如何获取这些属性值的。
NSF组件中操作的实现
现在我们为ImageDescForm来具体实现ShowImageDesc操作。
该操作将接收到一个值为新闻编号ImageNewsID的属性NewsIDChanged,然后在表单中显示新闻编号为ImageNewsID的新闻文档的标题,作者,正文等信息。
熟悉Notes的人知道,Notes开发中本来就有操作(Action)这种设计元素,为了与之区分,我们称NSF组件中的复合应用操作为WSDL操作(WSDLAction)。
在设计时为了便于Notes开发人员使用,创建WSDL操作的步骤沿袭了Notes操作的创建方法。
因此,为了实现这个名为ShowImageDesc的WSDL操作,我们首先要在ImageDescForm表单中创建一个普通Notes操作ImageIDChangedAction。
图11.在DominoDesigner中定义WSDL操作
在该操作的高级属性中,我们会发现一个新增设置:
“组合设置”,在这里可以选择之前在WSDL中定义的操作ShowImageDesc。
通过这样一步简单的操作,一个普通的Notes操作ImageIDChangedAction就成为了一个WSDL操作,实现了ShowImageDesc。
(一般情况下,建议将这个操作在操作条上隐藏)。
图12.在组合设置中选择对应的操作名
接下来我们需要在该操作的click事件中添加代码,实现下列内容:
1.接收属性NewsIDChanged;
2.根据属性NewsIDChanged的值,在新闻库中查找到对应新闻编号的新闻文档;
3.将该新闻文档的对应域值显示在ImageDescForm表单上。
由于后两步对Lotus开发人员并不陌生,这里就不再赘述,在此仅列出接收属性NewsIDChanged的LotusScript代码,这是整个WSDL操作实现过程中最核心的部分:
清单4.接收属性并执行操作的Lotusscript代码
SubClick(SourceAsButton)
OnError4719Gotoerr4719
DimpbAsNotesPropertyBroker
Setpb=session.getPropertyBroker()//获取PropertyBroker对象
DimpbInputPropertyAsNotesProperty
DimpbcontextAsVariant
pbContext=pb.InputPropertyContext
SetpbInputProperty=pbContext(0)//获取属性
DimInputPropertyNameAsString
InputPropertyName=pbInputProperty.Name
DimpbvalueAsVariant
pbValue=pb.GetPropertyValue(InputPropertyName)//获取属性值
//对该属性值进行处理,在表单中显示相应文档标题,作者和内容。
…
err4719:
error"
如上,通过Notes8中提供的PropertyBroker相关的类和方法,WSDL操作ShowImageDesc操作可以获得属性NewsIDChanged的值,存放到变量pbValue中。
在此基础上,可以对该值进行处理,在表单中显示相应文档标题,作者和内容。
通过定义属性和操作,发布属性,实现操作,我们得到了两个NSF组件:
ImageNewsList和ImageDescForm。
对广大Notes用户而言,将Notes元素封装成组件的好处在于:
用户可以充分利用现有的Notes数据库,以模块化,组件化的SOA思想对它们加以改造。
Eclipse组件的开发
当然很多情况下,只依靠NSF组件构建Notes8复合应用是不够的。
在做报表展现,图形处理,以及一些其他业务应用的时候,传统Notes开发会遇到一些瓶颈。
在Notes8中,我们可以通过Eclipse组件来弥补NSF组件功能上的不足。
开发复合应用的Eclipse组件需要具有Eclipse的插件(plugin)开发技能。
关于Eclipse插件开发细则以及Eclipse组件开发环境的配置,请参考http:
//www.eclipse.org上的相关文档,此处不再赘述。
与NSF组件一样,Eclipse组件的开发同样遵循着定义属性和操作,属性的发布,操作的实现三个步骤。
以ImageView组件为例,该组件接收NewsIDChanged属性(该属性值为新闻号),执行ShowImage操作:
显示该新闻号对应的新闻的图片。
要在Eclipse组件中定义该属性和操作,需要执行下列步骤。
图13.Eclipse组件——ImageView
首先,创建WSDL。
Eclipse组件中同样使用WSDL来描述组件的属性和操作,并且其格式与NSF组件的完全一致。
这意味着我们同样可以用前面提到的PropertyBrokerEditor这个可视化工具来编写Eclipse组件的WSDL(当你已经熟悉了Eclipse中复合应用组件的开发之后,你会更愿意使用文本编辑工具来编辑)。
调用PropertyBrokerEditor的方法是<
notesinstalldirectory>
\framework\rcp\rcplauncher.exe-configwsdledit。
图14.利用PropertyBrokerEditor定义Eclipse组件的属性
利用上图的PropertyBrokerEditor工具我们得到了一个描述文件actions.wsdl。
接下来,需要把得到的action.wsdl导入到Eclipse组件中。
在Eclipse的项目中,新建一个名为wsdl(该名称不做限定)的文件夹,把WSDL文件导入到该文件夹中。
下面这步非常关键:
在该Eclipse插件的扩展中加入com.ibm.rcp.propertybroker.PropertyBrokerDefinitions,并在该扩展下新建一个handler。
图15.扩展PropertyBrokerDefinitions
在这里,此扩展将会把描述文件WSDL与具体实现类相结合。
如下图所示。
File属性指定为我们刚刚生成的actions.WSDL文件,Type处选择SWT_ACTION,Class属性则选定将会具体实现Eclipse组件的操作的类com.ibm.xna.actions.ImageViewAction。
图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插件开