Sametime Helper Toolkit 是 IBM Lotus Sametime 8.0 新增的一个开发包,它为 Lotus Sametime Connect 客户端的基本功能提供了一个外部应用程序接口。 Sametime Helper Toolkit 并不是为了直接扩展 Sametime 客户端的功能。它与其他 Sametime 客户端开发包的区别在于:它为本地桌面运行的 Lotus Sametime Connect 客户端应用程序暴露出一些基本功能的调用接口。集成了 Sametime Helper API 的应用程序能够使用本地运行的 Sametime 客户端的功能(管理联系人,开启会话,提醒通知等)。
Sametime Helper Toolkit 提供了微软 Windows 本地和面向对象的 Java 编程接口,方便在桌面应用程序和 Sametime 客户端之间进行进程间通信,它支持三种语言:C++、C# 和 Java 。本文着重介绍 Java 编程接口的用法。
Lotus Symphony 是 IBM 推出的一组集文字处理、电子表格和演示幻灯片于一身的办公套件。它的特点之一就是开放的可扩展性。 Symphony 提供了软件开发包,方便用户进行定制和二次开发。
本文利用一个示例插件来讲解 Sametime Helper API 的用法,以及如何将 Sametime 客户端功能集成到 Lotus Symphony 中。该示例通过 Sametime Helper Java API:
- 连接 Sametime 客户端;
- 获得和改变本地登录用户状态;
- 快速查找 Sametime 联系人;
- 将 Symphony Document 中的文本内容发送给 Sametime 用户;
- 为 Symphony Document 增加联系人智能标签,并通过智能标签出发联系人操作。
如何搭建 Symphony 的集成开发环境的详细步骤请参阅 Lotus Symphony SDK 相关文档,本文仅列出简要步骤:
- 安装 Lotus Symphony 和 Eclipse ;
- 安装 Lotus Expeditor 工具包和 Symphony 支持包;
- 配置 Symphony 运行环境。
现在我们开始创建插件,执行以下步骤:
- 选择 File > New > Project,在 New Project 项目中选择 Plug-in Project ;
- 命名项目为 com.ibm.devworks.sample.sthelper,点击 Next ;
- 在 Plug-in Content 页面中,选择“ Generate an activator, a Java class that controls the plug-in ’ s life cycle ”,以及“ This plug-in will make contributions to the UI ”,点击 Finish 按钮。
为了实现演示的功能,需要为创建的项目添加依赖的插件:
- org.eclipse.ui
- org.eclipse.core.runtime
- com.ibm.rcp.ui
- com.ibm.rcp.jfaceex
- com.ibm.rcp.autorecognizer
- com.ibm.rcp.propertybroker
- com.ibm.productivity.tools.ui.toolbar
- com.ibm.productivity.tools.ui.views
为了能够使用 Sametime Helper Java API,需要引入三个额外的 Jar 包:
- com.ibm.collaboration.realtime.jsthelper_xxxx.jar
- com.ibm.micro.utils_xxxx.jar
- com.ibm.mqttclient_xxxx.jar
这三个文件可以在 Sametime Connect 的安装目录中找到,例如:
C:\Program Files\IBM\Sametime Connect\jsthelper\eclipse\plugins\
首先将这三个文件拷贝到项目的工程目录中,然后将其加入到 Runtime Classpath 中,如图 1 所示。
图 1. 添加 Sametime Helper 开发包
我们为 Symphony 添加了一条工具栏,执行以下步骤:
- 在 plugin.xml 中扩展 com.ibm.rcp.ui.controlSets 扩展点;
清单 1 中的 xml 代码扩展了 com.ibm.rcp.ui.controlSets 扩展点,并为新增的工具栏添加了三个控件:
- StatusControl 用来展现和改变本地 Sametime 用户的状态
- QuickFindControl 用来打开 Sametime 快速查找窗口
- SendSelectedTextControl 用来将选择的文本发送给指定的 Sametime 联系人
清单 1. 工具栏扩展点定义<extension point="com.ibm.rcp.ui.controlSets"> <controlSet id="com.ibm.devworks.sample.sthelper.controlset" label="STHelper Control Set" align="left" visible="true"> <toolBar id="com.ibm.devworks.sample.sthelper.toolBar" path="BEGIN_GROUP" /> <control class="com.ibm.devworks.sample.sthelper.StatusControl" id="com.ibm.devworks.sample.sthelper.statusControl" toolbarPath="BEGIN_GROUP/com.ibm.devworks.sample.sthelper/slot1" /> <control class="com.ibm.devworks.sample.sthelper.QuickFindControl" id="com.ibm.devworks.sample.sthelper.quickfindControl" toolbarPath="BEGIN_GROUP/com.ibm.devworks.sample.sthelper/slot2" /> <control class="com.ibm.devworks.sample.sthelper.SendSelectedTextControl" id="com.ibm.devworks.sample.sthelper.SendSelectedTextControl" toolbarPath="BEGIN_GROUP/com.ibm.devworks.sample.sthelper/slot3" /> </controlSet> </extension>
- 将工具栏与 Symphony 视图关联;
com.ibm.productivity.tools.ui.toolbar.controlSetSODCAssociations 扩展点可以定义工具栏与 Symphony 视图之间的关联,被关联的工具栏只有在 Symphony 视图被激活的时候才会显示。
清单 2. 关联 Symphony 视图<extension point="com.ibm.productivity.tools.ui.toolbar.controlSetSODCAssociations"> <controlSetSODCAssociation> <controlSet id="com.ibm.devworks.sample.sthelper.controlset" visible="true"> </controlSet> </controlSetSODCAssociation> </extension>
- 为控件分别定义 Java 实现类。
使用 JSTHelper 连接 Sametime Connect
Sametime Helper Java API 提供了:
- JSTHelper 对象负责创建与 Sametime 客户端的连接,以及调用 Sametime 客户端的功能;
- JSTCallback 接口提供了一系列的回调函数接口,用以处理 JSTHelper 对象所触发的事件。这是在 Java 开发中常用的事件驱动模型。
从设计的角度出发,我们提供了一个 STHelperUtil 工具类,由它来负责处理所有与 JSTHelper 对象的交互。 JSTHelper.connect 方法试图连接 Sametime 客户端,连接成功后 JSTCallback 接口中的 onSametimeAvailable 方法会被调用。
清单 3. 连接 Sametime 客户端
public class STHelperUtil {
......
private void initialize() {
stHelper =newJSTHelper();
stEventHandler =newSTHelperEventHandler();
stHelper.addSametimeCallback(stEventHandler);
stHelper.connect();
}
private void uninitialize() {
stHelper.disconnect();
stHelper.removeSametimeCallback(stEventHandler);
stHelper =null;
stEventHandler =null;
}
}
public class STHelperEventHandlerimplementsJSTCallback {
......
public void onSametimeAvailable(intcode) {
System.out.println("onSametimeAvailable");
}
public void onSametimeUnavailable(intcode) {
System.out.println("onSametimeUnavailable");
}
} |
获取本地用户状态的方法是 JSTHelper.getLocalUserDetails,而为了能够监听状态的变化,需要将本地用户添加到监听列表中:
- 获得本地用户的 ID ;
- 将本地用户添加到监听列表;
- 在 STHelperUtil 中添加一个状态监听器(StatusListener);
- 当状态发生变化时,JSTCallback.onPersonUpdate 方法被调用;
- STHelperUtil 通知监听器状态变化发生;
- StatusListener 接口的 statusChanged 方法被调用。
清单 4. 监听用户状态变化
public class StatusControlextendsSActionContribution Itemimplements StatusListener {
private String localUserId;
publicStatusControl() {
super( newStatusAction(null, IAction.AS_DROP_DOWN_MENU));
// register StatusListener in STHelperUtil,
// so that get notified when someone's(user in the watch list)
// status is changed,
STHelperUtil.getInstance().addStatusListener(this);
Display.getDefault().asyncExec(newRunnable() {
public void run() {
Map map = STHelperUtil.getInstance().getLocalUserDetails();
if(map !=null) {
// add myself in watch list
localUserId = (String)map.get("id");
STHelperUtil.getInstance().setWatch(localUserId);
}
}
});
}
public void statusChanged(Map event) {
if(event !=null) {
String userId = (String)event.get("partnerID");
if(userId.equals(localUserId)) {
// refresh tooltip text according to status text
((StatusAction)getAction()).refreshText((String)event.get("statusText"));
}
}
}
}
public class STHelperEventHandler implements JSTCallback {
public void onPersonUpdate(Map partnerInfo) {
......
// status is changed, notify listeners
STHelperUtil.getInstance().notifyStatusListener(partnerInfo);
}
} |
而要改变本地用户的状态,则需要调用 JSTHelper.updateLocalUserStatus 方法。
清单 5. 改变用户状态
public class StatusAction extends Action {
......
publicIMenuCreator getMenuCreator() {
// Create drop down menu
// The menu will change local user's statusreturn
newIMenuCreator() {
Menu cachedMenu;
public Menu getMenu(org.eclipse.swt.widgets.Control parent) {
cachedMenu =new Menu(parent);
MenuItem itemAvaliable =new MenuItem(cachedMenu, SWT.PUSH);
itemAvaliable.setText("Avaliable");
itemAvaliable.addSelectionListener(newSelectionAdapter() {
public void widgetSelected(SelectionEvent selection) {
STHelperUtil.getInstance().updateLocalUserStatus(1);
}
});
MenuItem itemAway =new MenuItem(cachedMenu, SWT.PUSH);
itemAway.setText("I am Away");
itemAway.addSelectionListener(newSelectionAdapter() {
public void widgetSelected(SelectionEvent selection) {
STHelperUtil.getInstance().updateLocalUserStatus(2);
}
});
returncachedMenu;
};
......
};
}
} |
图 2. 获取状态信息
图 3. 改变用户状态
Sametime Helper Toolkit 同时提供了打开快速查找联系人窗口的方法 JSTHelper.quickFind 。
清单 6. 调用快速查找
public class QuickFindAction extends Action {
......
public void run() {
// Open Quick Find window
STHelperUtil.getInstance().openQuickFind();
}
} |
图 4. 快速查找
为了完成此项功能,如图 5 所示,我们需要:
- 获得本地用户的联系人列表
- 选择一个联系人
- 获取 Symphony 文档中的选择文本
- 将文本发送至联系人
像其它 JSTHelper 对象的方法一样,获得联系人方法 getContacts 和 getGroups 的返回结果分别在 JSTCallback 接口的 onGetContacts 和 onGetGroups 中给出。
需要注意的是,首先要获得联系人列表中所有的 Group 名称,再根据 Group 的名称得到分组内所有的联系人。
清单 7. 获得联系人列表
publicString[] getSametimeContacts() {
// Sametime Group type
String strGroupType = "all";
// Invoke the Sametime Helper to obtain the group names.
getGroups(strGroupType);
// Wait for the event data to return the group names.
String eventData[] = stEventHandler.waitContactsData(60000);
// Assign a Vector to hold the list of contact names
Vector contacts =newVector();if(eventData !=null) {
// Assign the array that has the Sametime Contact Group names.
String strGroupNames[] = eventData;
// Loop through the Sametime Contact Group names and retrieve
// the Sametime Contact names for each group.
for(inti = 0; i < strGroupNames.length; i++) {
// Assign the current group name.
String strGroupName = strGroupNames[i];
// Invoke the Sametime Helper to obtain the contact
// names for the current group.
stHelper.getContacts(strGroupName);
// Wait for the event data to return the contact names.
eventData = stEventHandler.waitContactsData(60000);
if(eventData !=null) {
// Assign the current contact.
String strContactNames[] = eventData;
// Loop through the Sametime Contact names and add each name
// to the Vector of contact names.
for(intct = 0; ct < strContactNames.length; ct++) {
contacts.add(strContactNames[ct]);
}
}
}
}
String[] array =new String[contacts.size()];
for(inti = 0; i < contacts.size(); i++) {
array[i] = (String)contacts.get(i);
}
return array;
} |
在 Eclipse 中,Eclipse workbench 提供了选择服务(Selection Service),每个 workbench 窗口拥有自己的选择服务实例。此服务跟踪当前活动部件(Part)中的选择变化,并将变化消息传播给所有已注册的监听器(Listener)。每一个 Lotus Symphony 文档作为一个 Eclipse 视图部件(ViewPart)被打开,视图将选择提供者(Selection Provider)注册到 Eclipse workbench 中。这样,应用程序就能够监听 Symphony 文档中选择部分的变化,以及访问选择的内容。
清单 8. 取得选择文本
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
ISelectionService service = window.getSelectionService();
ISelection selection = service.getSelection();
IAdaptable adaptable = (IAdaptable)selection;
RichDocumentContentSelection textSel = RichDocumentContentSelection)adaptable.
getAdapter(RichDocumentContentSelection.class);
String text = textSel.getPlainText();
if(text !=null&& text.length() > 0) {
STHelperUtil.getInstance().openChat(contactId, text,true);
} |
调用 JSTHelper.getContacts 方法所返回的结果是联系人的显示名(Display Name),而 JSTHelper.openChat 方法需要有联系人的用户 ID,因此之前需要调用 JSTHelper.liveNameResolve 方法根据显示名获得用户 ID 。
图 5. 发送选择文本
Lotus Symphony 文档提供了 Auto Recognizer 服务,使用它可以利用自定义的模式识别文档中的内容,并为用户提供操作的接口。关于 Auto Recognizer 的详细信息,请参阅 Lotus Symphony SDK 文档,本文不再赘述。如图 6,本示例演示了如何识别 Symphony 文档中的 Sametime 联系人,并在下拉菜单中可以发起聊天功能。
- 在 plugin.xml 文件中添加 com.ibm.rcp.autorecognizer.Recognizer 扩展点
清单 9. Recognizer 扩展点<extension point="com.ibm.rcp.autorecognizer.Recognizer"> <types> <define-method id="LiveNameRecoginzer"> <type datatype="LiveNameType" default-name="LiveNameType" multi-segment="true" namespace="http://www.ibm.com/wps/c2a" /> <custom class="com.ibm.devworks.sample.sthelper.LiveNameDetector" /> </define-method> </types> </extension>
- 添加 com.ibm.rcp.propertybroker.PropertyBrokerDefinitions 扩展点
清单 10. PropertyBroker 扩展点<extension point="com.ibm.rcp.propertybroker.PropertyBrokerDefinitions"> <handler class="com.ibm.devworks.sample.sthelper.LiveNameAction" file="wsdl/LiveNameAction.wsdl" type="SWT_ACTION"/> </extension>
- 定义 WSDL 文件
请参看示例源代码包中的 LiveNameAction.wsdl 文件。
- 实现 LiveNameDetector 类,用来识别文档中的 Sametime 联系人名称的文本
清单 11. 识别联系人public class LiveNameDetectorimplementsIDetect { publicDetectResult detect(String word) { if(word.contains("@")) { // try to resolve the input word as a live name user Map resolved = STHelperUtil.getInstance().resolveLiveName(word); if(resolved !=null) { String lookupName = (String)resolved.get("lookupName"); if(lookupName.equals(word)) { // resolve successful, return the detect result DetectResult rlt =newDetectResult(); rlt.start = 0; rlt.offset = word.length(); rlt.value = word;returnrlt; } } } return null; } }
- 实现 LiveNameAction 类,用来响应用户操作
清单 12. 响应操作public class LiveNameAction implements IHandler { ...... publicObject execute(ExecutionEvent event) throws ExecutionException { // Invoke chat action in STHelper PropertyChangeEvent evt = (PropertyChangeEvent) event.getTrigger(); STHelperUtil.getInstance().openChatByLookupName((String) evt.getPropertyValue().getValue()); return null; } ...... }
图 6. 识别联系人
在缺省情况下,Sametime Connect 客户端并没有开启 Broker Bridge 服务。在 Sametime 安装目录中的 plugin_customization.ini 文件中更改如下内容:
com.ibm.collaboration.realtime.brokerbridge/startBroker=true
下面要做的就是启动 Sametime Connect 客户端程序,以及在 Symphony 开发环境中运行了。
Sametime Helper Toolkit 作为 Sametime 软件开发包的新成员,它为开发者提供了访问 Sametime 客户端程序的外部接口,通过它可以更方便的将 Sametime 客户端功能集成到其他桌面应用程序中去。本文以 Lotus Symphony 为例,为读者讲解如何利用 Sametime Helper Toolkit 进行集成开发。
| 名字 | 大小 | 下载方法 |
|---|---|---|
| STHelperSample.zip | 384 KB | HTTP |
学习
- 开始了解 IBM Lotus Symphony 技术内容。
- 阅读 developerWorks 文章 “IBM Lotus Notes/Domino V8 新特性”。
- 阅读 developerWorks 文章 “在 Lotus Notes 8 中开发复合应用”。
- 阅读 developerWorks 文章 “IBM Lotus Symphony: 兼容与开放的办公软件”。
- 阅读 developerWorks 文章 “了解 IBM Lotus Symphony 的可编程性”。
- 阅读 developerWorks 文章 “了解 Lotus Notes 中 Lotus Symphony 的可编程性”。
- 阅读 developerWorks 文章 “通过 Eclipse 插件来扩展 IBM Lotus Symphony”。
- 阅读 developerWorks 文章 “IBM Lotus Symphony 开发人员教程: 构建一个简单的文档工作流插件”。
- 访问 “IBM Lotus Symphony 社区网站”。
-
访问:“Lotus Sametime
产品页面”,获得更多 Lotus Sametime 产品信息。
-
产品文档:“Sametime toolkit 文档”。
-
访问:“Lotus Symphony 产品页面”,获取更多 Lotus Symphony 产品信息。
获得产品和技术
- 立即下载并试用 “IBM Lotus Symphony 产品(中文版)”!
- 下载“Lotus Symphony Developer Toolkit”!