级别: 中级 Soumya Sreeram, 高级软件工程师, IBM Derek Carr, 咨询软件工程师, IBM Gregory Melahn, 架构师和高级技术人员, IBM
2009 年 8 月 03 日 通过本文,您将学习如何连接几个协作工具来共享内容。您将下载 IBM Lotus Quickr Document Linker,并学习如何用它将 IBM Lotus Connections 活动发布到 Lotus Quickr 空间。
通过使用 Web 2.0 风格的协作工具,人们可以更高效地工作。一个常见的难题是如何更好地管理这些工具所使用的内容。跟踪分布在许多系统上的所有内容是很困难的。本文的目标是通过一个示例演示如何将几个协作工具连接在一起,让它们能够共享内容。
在这个示例中,IBM Lotus Connections 和 IBM Lotus Quickr 使用简单的发布服务共享内容。这个实现使用一个简单的 Eclipse 插件,这个插件使用 Lotus Connections 和 Lotus Quickr 服务访问两个系统中的内容。按照 Web 2.0 风格,这些服务依靠基本的 HTTP 方法(GET、POST、PUT 和 DELETE)创建和修改用 URI 标识的资源。
先决条件
您需要了解 IBM Lotus Connections 和 IBM Lotus Quickr REST 服务,并掌握 Eclipse 框架、Eclipse 插件开发、Java 和 Apache Abdera 的一些知识。关于 Lotus Quickr REST 服务的更多信息,请参考 developerWorks 文章 “IBM Lotus Quickr REST 服务简介”。
关于 Lotus Quickr Document Linker
我们来考虑一个场景:组织使用以活动为中心的计算来管理工作并支持协作型工作环境。组织已经部署了 Lotus Connections 软件,从而围绕职员的日常活动组织工作。在 Lotus Connections 中,活动是一个工作单元,涉及组织中为同一目标工作的一个或多个人员。例如,活动可能是准备一次会议、获取关于一个业务过程的知识或者组织一次营销活动。当活动最终完成时,常常产生文档作为最终结果;文档可以是演示文件、电子表格、文本文档或其他类型的文档。
假设公司还决定部署 Lotus Quickr,从而围绕共享团队空间的概念组织和共享内容。在 Lotus Quickr 中,空间是一个共享的工作区,职员可以使用简单的协作工具(比如文档管理程序和 wiki)在这里一起工作。为了更好地利用 Lotus Quickr 的文档管理功能(比如版本化、签入/签出和存档),公司希望能够轻松地将文档从活动发布到空间。
作为开发人员,您的任务是实现这种将文档从活动发布到空间的功能。您决定编写一个连接器,它从 Lotus Connections 活动获取文件并将这些文件发送到 Lotus Quickr 空间,而且用户只需一次单击就能够完成这个操作。在这个示例中,连接器是一个称为 Lotus Quickr Document Linker 的 Eclipse 插件,它适用于 Lotus Quickr 的 J2EE 和 IBM Lotus Domino 两个版本。Lotus Quickr Document Linker 允许将活动内容发布到 Lotus Quickr 空间,并用 Lotus Quickr 中文档的链接更新活动。Lotus Quickr Document Linker 用一个树视图显示活动和每个活动中的文件。可以用特定 Activity 服务器和 Lotus Quickr 服务器的 URL 配置这个应用程序。
这个应用程序执行以下操作:
- 获取活动
- 将文档从活动发布到 Lotus Quickr 空间
- 刷新活动
在这个示例中,使用 Lotus Connections REST 服务从一个 Lotus Connections 活动获得文档,然后使用 Lotus Quickr REST 服务将文档发布到一个 Lotus Quickr 空间。因为 Lotus Quickr 和 Lotus Connections 都使用 Atom 作为标准协议,所以我们还使用开放源码的 Apache Abdera 客户机解析 Atom feed 并创建 HTTP 请求。
设置环境来配置和执行插件
下面解释如何设置 Eclipse 开发环境以及如何执行 Lotus Quickr Document Linker。
创建 Lotus Quickr Document Linker 项目
下载本文提供的 Lotus Quickr Document Linker。在 Eclipse 中导入这个示例来创建一个项目。
提供 Lotus Quickr 库路径
已经定义了一个属性文件(libraryConfig.properties),其中配置了活动文档要发布到的 Lotus Quickr 库。图 1 所示的路径是 Lotus Quickr 库路径。将这个路径替换为您的 Lotus Quickr 库的路径。当需要发布文档时,这个插件会动态地从属性文件中获取这个路径。
图 1. 显示 Lotus Quickr 库路径的 Eclipse 视图
执行 Lotus Quickr Document Linker
执行这个插件的方法是作为 Eclipse 应用程序运行它。这会打开另一个 Eclipse 实例,见图 2。
图 2. 启动 QuickrDocumentLinker
为了查看这个插件,在新的 Eclipse 实例中选择 Window - ShowView - Other。这会打开一个显示可用插件的窗口。选择 QuickrDocumentLinker - Activities,见图 3。
图 3. 在 Eclipse 中打开 QuickrDocumentLinker 视图
Activity Plug-in 视图打开。在右边出现工具提示的地方单击图标来配置服务器。这会打开 Activity 和 Lotus Quickr 服务器的配置窗口,见图 4。
图 4. 在 Eclipse 中启动的 QuickrDocumentLinker
配置服务器
为了访问活动的内容并将它们发布到 Lotus Quickr,需要服务器 URL 和凭证细节。在 Eclipse 中编写一个 ConfigDialog 控件,URL 和登录信息作为 ConfigDialog 控件的参数。创建一个获取和设置值的 Dialog 区域,可以通过 HTTP 方法访问这些值。在插件启动时,ConfigDialog 像图 5 这样。
图 5. Lotus Quickr Document Linker 的 Server Settings 对话框
更多细节请参考示例中的 configDialog.java。
获得活动内容
Lotus Quickr Document Linker 包含一个 Eclipse 树视图,它将活动显示为第一级节点,将每个活动中的文件显示为第二级节点。为了构建这个树视图,首先要访问 Activity 服务器来获取所有活动的列表。
对以下 URL 执行 HTTP GET 操作来获取所有活动的列表:
https://activities.abc-corp.com/activities/service/atom/activities
清单 1 获取活动的列表并构建第一级节点。
清单 1. 获取所有活动并处理响应的代码片段
private void getActivities() {
if (serverConfig != null && serverConfig.getUrl() != null) {
try {
httpClient.addCredentials(serverConfig.getUrl(), null, null,
new UsernamePasswordCredentials(serverConfig.getUserId(), serverConfig.getPassword()));
httpClient.usePreemptiveAuthentication(true);
ClientResponse response = httpClient.get(
serverConfig.getUrl()+ "/activities/service/atom/activities");
if (response.getStatus() == 200) {
Document activityRes = response.getDocument();
Feed feed = (Feed) activityRes.getRoot();
if (feed != null) {
Iterator entries = feed.getEntries().iterator();
while (entries.hasNext()) {
TreeParent entry = new TreeParent((Entry) entries.next(), true);
invisibleRoot.addChild(entry);
}
feed = feed.getNextSibling();
}
} else {
showMessage("Could not connect to Activity server.
Please check server configuration");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
这个 GET 请求的结果是一个 Atom 提要,其中每个条目表示一个活动,见清单 2。循环遍历提要中的条目来构建第一级活动节点。
清单 2. 对 Activity 服务器执行 GET 操作所返回的提要
<feed>
<entry>
<id>urn:lsid:abc-corp.com:oa:6A3G091E0E4B373A9D79D2CED14BD2003410</id>
<title type="text">First activity</title>
<updated>2007-10-17T15:26:53Z</updated>
<published>2007-10-17T13:52:03Z</published>
<author>
<name>Mark case</name>
<email>mcase@us.abc-corp.com</email>
<snx:ldapid>21EG091E0E4B9E7E3C2F5CD9D61E9300B79C</snx:ldapid>
</author>
<contributor>
<name>Mark case</name>
<email>mcase@us.abc-corp.com</email>
<snx:ldapid>21EG091E0E4B9E7E3C2F5CD9D61E9300B79C</snx:ldapid>
</contributor>
<category scheme="http://www.ibm.com/xmlns/prod/sn/type" term="activity"
label="Activity"/>
<category scheme="http://www.ibm.com/xmlns/prod/sn/priority" term="1"
label="Normal"/>
<link rel="http://www.ibm.com/xmlns/prod/sn/member-list" type="application/atom+xml"
href="https://activities.abc-corp.com/activities/service/atom/
acl?activityUuid=6A3G091E0E4B373A9D79D2CED14BD2003410" />
<link rel="http://www.ibm.com/xmlns/prod/sn/history" type="application/atom+xml"
href="https://activities.abc-corp.com/activities/service/atom/activity/
history?activityUuid=6A3G091E0E4B373A9D79D2CED14BD2003410" />
<app:collection href="https://activities.abc-corp.com/activities/service/atom/
activity?activityUuid=6A3G091E0E4B373A9D79D2CED14BD2003410">
<title type="text">First activity</title>
<app:categories href="https://activities.abc-corp.com/activities/service/
atom/activity/
categories?activityUuid=6A3G091E0E4B373A9D79D2CED14BD2003410"/>
</app:collection>
<snx:activity>6A3G091E0E4B373A9D79D2CED14BD2003410</snx:activity>
<link rel="edit" type="application/atom+xml"
href="https://activities.abc-corp.com/activities/service/atom/activitynode?
activityNodeUuid=6A3G091E0E4B373A9D79D2CED14BD2003410" />
<link rel="self" type="application/atom+xml"
href="https://activities.abc-corp.com/activities/service/atom/activity?
activityUuid=6A3G091E0E4B373A9D79D2CED14BD2003410"/>
<link rel="alternate" type="text/html"
href="https://activities. abc-corp.com/activities/service/html/activity/recent?
activityUuid=6A3G091E0E4B373A9D79D2CED14BD2003410"/>
<snx:permissions>none, create_activity, view_activity, edit_activity,
delete_activity, activity_owner, edit_activity_tags, design_activity,
edit_statements, delete_statements, add_members, delete_members,
create_entries, edit_personal_entries, edit_all_entries, delete_personal_entries,
delete_all_entries, edit_personal_entry_tags, edit_all_entry_tags,
view_members</snx:permissions>
<snx:icon>
https://activities.abc-corp.com/activities/images/activityIcon16.gif
</snx:icon>
<content type="text">Learning</content>
</entry>
<entry>
……
…………
</entry>
</feed>
|
对于每个活动,用活动中的内容构建第二级节点。为了获取每个活动中的文件,使用 TreeParent 对象中的另一个方法获取活动(第一级节点)的 URL,并对活动 URL 执行一个 GET 请求,见清单 3。这个操作返回活动的内容列表。返回的提要对于每段内容包含一个条目,内容包括书签、文本和文件。在这个示例中,只选用类型为 File 的媒体内容来构建第二级节点。选择类型为 File 的内容是因为这些是活动产生的内容(比如图像、演示文件、字/文本文档和 PDF 文件),还因为它们是您希望在 Lotus Quickr 空间中使用的内容。
清单 3. 获取每个活动的文件内容(第二级节点)
public TreeObject[] getChildren() {
if (!getChildren) {
getChildren = true;
if (activityURL != null) {
ClientResponse response = httpClient.get(activityURL);
if (response.getStatus() == 200) {
Document activityDoc = response.getDocument();
Feed feedRoot = (Feed) activityDoc.getRoot();
Iterator entriesIterator =
(Iterator) feedRoot.getEntries().iterator();
while (entriesIterator.hasNext()) {
Entry entry = (Entry) entriesIterator.next();
if (((Category) entry.getCategories().get(0).getLabel().equals("File")) {
TreeObject activity = new TreeObject(entry);
addChild(activity);
}
}
}
}
}
return (TreeObject[]) children.toArray(new TreeObject[children.size()]);
}
|
对特定活动的 HTTP GET 请求会返回一个包含活动内容的提要。图 6 显示这个插件中活动及其媒体文件的树视图。
图 6. 活动内容的树视图
在 Lotus Quickr Document Linker 的树视图中构建第一级和第二级节点之后,现在就可以将内容发布到 Lotus Quickr 服务器了。
将内容发布到 Lotus Quickr
右键单击一个活动并选择 “Publish to Lotus Quickr” 选项。选择这个选项之后,出现一个显示活动状态的确认对话框。
图 7. 将活动内容发布到 Lotus Quickr 的菜单项
清单 4 给出将活动内容发布到 Lotus Quickr 的代码片段。
清单 4. 将活动内容发布到 Lotus Quickr 的代码片段
ClientResponse res = null;
Library lib = new Library();
try {
String libpath = lib.getLibProps().getProperty("quickr.lib");
if ((enclosureLink != null) && (name != null)) {
String QuickrLibURI = Activator.getDefault()
.getPluginPreferences().getString("quickrserver.url");
QuickrLibURI = QuickrLibURI + libpath
+ "feed?replace=true&lock=true";
String QuserName = Activator.getDefault().getPluginPreferences()
.getString("quickr.user");
String QPassword = Activator.getDefault().getPluginPreferences().
getString("quickr.pwd");
ClientResponse response = httpClient.get(enclosureLink);
if (response.getStatus() == 200) {
InputStream is = response.getInputStream();
CommonsClient httpQuickrClient = new CommonsClient();
httpQuickrClient.addCredentials(QuickrLibURI, null, null,
new UsernamePasswordCredentials(QuserName,QPassword));
httpQuickrClient.usePreemptiveAuthentication(true);
RequestOptions options = new RequestOptions();
options.setSlug(name);
options.setContentType(contentType);
res = httpQuickrClient.post(QuickrLibURI, is, options);
}
}
}
|
按照以下步骤将内容发布到 Lotus Quickr:
- 获取所选活动文件的 URL。
- 对 Activity 服务器执行 GET 请求,读取活动文件的内容。
- 对 Lotus Quickr 服务器执行 POST 请求来发布文件。在这个步骤中,需要 Lotus Quickr 库;库路径从属性文件中取得,而且是可配置的。
- 读取 Lotus Quickr 服务器上的内容位置,这是 HTTP POST 请求返回的一个条目。需要利用这一信息用书签更新活动。
图 8 显示一个文档从活动发布到 Lotus Quickr。
图 8. 发布到 Lotus Quickr 的文档
用 Lotus Quickr 书签更新活动
对 POST 请求的响应是一个从 Lotus Quickr 返回的条目,它描述刚才发布的文档的位置和细节。从这个条目获取媒体链接,然后更新这个活动,在活动上创建这个文档的链接。这个任务需要对 Activity 服务器执行一个 HTTP POST 请求。清单 5 给出的代码用一个书签更新活动,这个书签指向 Lotus Quickr 中的内容位置。
清单 5. 用书签更新活动内容
public int updateActivities(Entry entry, TreeObject target) {
ClientResponse postResponse = null;
try {
RequestOptions ro = new RequestOptions();
ro.setContentType("application/atom+xml");
Entry updateEntry = Abdera.getNewFactory().newEntry();
updateEntry.setId(target.getId());
updateEntry.setTitle(target.getName());
updateEntry.addLink(target.getActivityURL(), "edit");
updateEntry.addLink(target.getActivityURL(), "self");
updateEntry.addCategory("http://www.ibm.com/xmlns/prod/sn/type",
"bookmark", "Bookmark");
updateEntry.addLink(entry.getEditMediaLinkResolvedHref().toString());
ClientResponse deleteResponse = httpClient.delete(target
.getActivityURL());
postResponse = httpClient.post(target.getParent().getActivityURL(), updateEntry, ro);
} catch (Exception e) {
e.printStackTrace();
}
return postResponse.getStatus();
}
|
在图 9 中,从 Eclipse 插件发布到 Lotus Quickr 的活动内容已经加上了一个书签,这个书签指向 Lotus Quickr 中的文档 URL。
图 9. 用指向 Lotus Quickr 文档位置的书签更新的活动
将活动内容发布到 Lotus Quickr 之后,这个文件就不再在活动中存在了。它被替换为一个指向 Lotus Quickr 位置的书签。当右键单击活动并在出现的菜单中选择刷新这个活动时,会看到文件不再作为第二级节点出现。(请记住,只能操作作为第二级节点出现的活动媒体内容。)
结束语
在这个示例中,我们演示了如何结合使用两个协作工具,以一种简单方便的方式将文档从 Lotus Connection 活动发布到 Lotus Quickr 空间。可以应用这种设计模式将两个或更多系统连接起来,从而满足自己的特殊需要。
下载 | 名字 | 大小 | 下载方法 |
|---|
| LotusQuickrDocumentLinker.zip | 2121KB | HTTP |
参考资料 学习
讨论
作者简介  | |  | Soumya Sreeram 是在北卡罗莱那 Research Triangle Park 的 IBM Lotus Quickr 团队工作的高级软件工程师。 |
 | |  | Derek Carr 是在北卡罗莱那 Research Triangle Park 的 IBM Lotus Quickr 团队工作的咨询软件工程师。 |
 | |  | Greg Melahn 是 IBM Software Group 的 Lotus 部门的架构师和高级技术人员。 |
对本文的评价
|