级别: 中级 Brian Leonard, Lotus Notes 客户机开发人员, IBM
2008 年 7 月 14 日 为定制和扩展 Eclipse 插件的用户体验,IBM Lotus Notes V8 的新架构提供了多种新的方式。本文描述了如何在该构架下访问和创建 Lotus Notes 内容。
在近期的文章 “扩展 IBM Lotus Notes V8 侧栏和工具栏” 中,我们了解了如何通过向客户机的侧栏和工具栏添加新组件扩展用户的 IBM Lotus Notes V8 体验。确切的说,加入了 SideNote 和 QuickNote 两个应用程序后,解决了存储和管理少许文本的问题。对于如何在这些位置上放置自己的组件,我们创建的插件是个很好的学习示例。
使用过 SideNote 和 QuickNote 的人可能认为它们只不过是两个存储库,和存储关键信息的其他存储库一样。如果您使用了 Lotus Notes 日志程序,特别是将所有信息都保存在日志中时,您就不会这么想了。
建造了自己的组件后,将会遇到类似的难题。如果不能够以某种方式与所拥有的数据和系统进行交互,那么您所能做的事非常有限。然而幸运的是,lotus Notes 的可编程模型给我们提供了多种与系统交互的方式。例如,任何提供了 Web 服务的系统能够很容易的按照所需的方式进行集成。可以更加轻松地使用提供了 java 接口或库文件的应用程序。
IBM Lotus Notes 用 Notes.jar 库与 Lotus Notes 数据库和文件进行交互。本文阐述了如何使用该库文件和其它技术来扩展新组件的功能。
设置
首先,需要安装 Lotus Notes V8 软件。
然后,还需要设置 Eclipse,该软件提供免费下载。要使用 Lotus Notes 环境,还需要对 Eclipse 进行设置。如下的步骤假定 Notes 被安装在默认的路径 C:\Program Files\IBM\Lotus\Notes 中并且数据目录在路径 C:\Program Files\IBM\Lotus\Notes\Data 下。如果环境有稍许的不同,请在相应的位置上使用您的路径。
启动 Eclipse IDE,并通过以下步骤设置目标平台:
- 选择 Window - Preferences。
- 展开 Plug-in Development。
- 选择 Target Platform。
- 在 Location edit control 控件中,输入 C:\Program Files\IBM\Lotus\notes\framework\eclipse.
- 单击 Reload 按钮,然后单击 OK。
接着,创建一个附加安装的 JRE:
- 选择 Window - Preferences。
- 展开 Java。
- 选择 Installed JREs。
- 单击 Add。
- 对于 JRE name,输入 Notes JRE 作为名称。
- 输入 C:\Program Files\IBM\Lotus\notes\framework\rcp\eclipse\plugins\com.ibm.rcp.j2se.win32.<version number> 作为 JRE 的主目录.
对于 Lotus Notes Beta 3 版本, 该值是: com.ibm.rcp.j2se.win32.x86_1.5.0.SR4-200705170110
(注意: 这一步会将 JAR 文件填充到弹出框中较低的部位。)
接下来,通过以下步骤创建一个新的运行时配置:
- 选择 Run - Run,然后选择 Eclipse Application。
- 单击右键,选择 New。
- 输入一个名称(例如 Notes)。
- 在 Program to Run 下,选择 Run a product,然后选择 com.ibm.notes.branding.notes。
- 在 Runtime JRE 中,选择 Notes JRE。
- 在 Arguments 附签中,在 Program arguments 文本框中输入以下内容:
-personality com.ibm.rcp.platform.personality
-product com.ibm.notes.branding.notes
-debug
-console
在 VM arguments 文本框中输入以下参数:
-Drcp.home=${notes.install}\framework
-Drcp.data=${notes.data}\workspace
-Drcp.install.config=user
-Dosgi.install.area=${notes.install}\framework\eclipse
-Dcom.ibm.pvc.osgiagent.core.logfileloc=${notes.install}\framework\rcp
-Dcom.ibm.pvc.webcontainer.port=0
-Declipse.pluginCustomization=${notes.install}\framework\rcp\plugin_customization.ini
-Declipse.registry.nulltoken=true
-Djava.protocol.handler.pkgs=com.ibm.net.ssl.www.protocol
-Djava.util.logging.config.class=com.ibm.rcp.core.internal.logger.boot.LoggerConfig
-Dosgi.hook.configurators.exclude=org.eclipse.core.runtime.internal.adaptor.EclipseLogHook
-Dosgi.framework.extensions=com.ibm.rcp.core.logger.frameworkhook
-Xbootclasspath/a:${notes.install}\framework\rcp\eclipse\plugins\${rcp.base}\rcpbootcp.jar;
接下来,通过以下步骤完成运行时配置:
- 单击 Variables。
- 单击 Edit Variables。
- 单击 New。
- 输入 notes.install 作为名称。
- 在 value 栏输入 Notes 的安装路径 ,然后单击 OK。该路径中不能包含空格符。例如,如果安装在了 C:\Program Files\Lotus\Notes 中,notes.install 的值应该为:
C:\PROGRA~1\IBM\Lotus\Notes.
- 重复 1 至 3 步。
- 输入 notes.data 作为名称。
- 在 value 栏输入数据目录的路径,然后单击 ok。例如,使用缺省值:
C:\PROGRA~1\IBM\Lotus\Notes\Data。
- 重复 1 至 3 步。
- 输入 rcp.base 作为名称。
- 在 value 栏输入安装的 com.ibm.rcp.base 插件文件夹名称,然后单击 ok。为此,查看如下路径:<notes install location :>\framework\rcp\eclipse\plugins。可以看到类似 com.ibm.rcp.base_6.1.1.<date> 的文件夹。
例如, 在 Lotus Notes Beta 3 中, 该值是:
com.ibm.rcp.base_6.1.1.200705170110
- 单击 OK,然后单击 Select Variable 对话框中的 Cancel(如果单击 OK 来选择变量,那么它将把变量添加到插入点)。
为了从 IDE 中启用 Notes 安全性,需要对两行代码解除注释。在 <notes install location>\framework\shared\eclipse\plugins\com.ibm.notes.branding_3.0.0.<version number>\notes_plugin_customization.ini 中,通过去掉前面的 # 字符,对以下两行代码解除注释:
com.ibm.rcp.security.auth/loginEnabled=true
com.ibm.rcp.security.auth/loginConfigName=NOTES
现在,选择 Run/Debug,启动 Lotus Notes。
最后,下载本文附带的代码,并将它解压到一个新文件夹中。为了将它导入到 Eclipse 中,需要导入已有的项目。
- 选择 File - Import。
- 选择 General - Existing Projects into Workplace,单击 Next。
- 浏览并选择之前将代码解压到的那个文件夹,单击 OK。
- 单击 Finish 完成导入过程。
SideNote
Lotus Notes 侧栏包含了 SideNote 应用程序,该程序为用户提供了一个快速输入和保存文本的区域。在上篇文章 “扩展 IBM Lotus Notes V8 侧栏和工具栏” 中,您了解了如何通过 Eclipse 的扩展点将菜单动作加入到侧栏组件中。确切的说,我们在 SideNote 中加入 Save as 和 Load from 文件动作,如图 1 所示。
图 1. SideNote and menu 选项
Email 动作
当文本输入到 SideNote 之后,您可能会想到要将内容发送电子邮件。如图 2 所示,加入一个菜单项后就能完成该项任务。
图 2. Email It! 动作
通过使用操作系统的 API 就能完成该动作,而不需要使用到 Lotus Notes 的 API。确切的说,email 动作使用了 mailto URL 协议来创建新的消息。
但是,链接 规范 也允许传送其它的几种数据,动作特别地使用了指定消息体的功能。同样,您也能够删除收件人,因此链接的形式与 mailto:?body=It+would+be+nice+to+email+from+here 相似。
由于 Lotus Notes 实现了该协议,拥有上述形式的链接能够正确地创建具有指定消息体的电子邮件。
在上篇文章中,实现了 org.eclipse.ui.viewActions 扩展点在该菜单中加入新的动作。如图 3 所示,在 viewActions 扩展点中包括以下字段和值:
- class: com.ibm.lotuslabs.sidenote.email.EmailSideNote
- enablesFor: *
- id: com.ibm.lotuslabs.sidenote.email.EmailSideNote
- label: Email it!
- menubarPath: additions
- tooltip: Email this SideNote
图 3. Plugin.xml 和扩展点
因此,com.ibm.lotuslabs.sidenote.email 插件根据约定指向了 EmailSideNote 类,必须实现 IViewActionDelegate 接口,类的 run 方法检索文本并打开链接以创建新的消息。
Save to Journal 动作
其另一个插件 com.ibm.lotuslabs.sidenote.journal 把保存 SideNote 内容的动作加到用户的日志中,新的动作如图 4所示。
图 4. Save to Journal 动作
可以看到遵循了相同的模式。plugin.xml 构成扩展点,并指向类 JournalSideNote。方法 run 如清单 1 所示
清单 1. 类 JournalSideNote 的 run 方法
private SideNoteViewPart part;
// save it
public void run(IAction arg0) {
if(part!=null) {
String text = part.getText();
if(text==null)
text="";
JournalEntry.createJournalEntry(null, text);
}
}
|
可以看出,调用 JournalEntry 的类执行了所有的工作。这是插件 com.ibm.lotuslabs.notes.pim 中的一个帮助器类,该类通过 Notes.jar 库处理与 Lotus Notes 的所有交互。
与 Lotus Notes 数据交互
引入这个新的 Java 环境后,库 Notes.jar 在客户机的数据集成中起到了重要的作用。这个库在几个发行版本中都有,现在已经绑定到 IBM Lotus Notes V8 的 com.ibm.notes.java.api 插件中。
注意: 在 Lotus Notes V8 beta 版本中,还没有正式支持该插件,但是,现在可作为技术预览使用。
该插件与 Notes.jar 库合作处理了很多复杂的事情,包括保护和装配系统变量。所需做的全部事情就是将 com.ibm.notes.java.api 添加到插件的 MANIFEST.MF 文件的依赖关系中。
此外,com.ibm.notes.java.api 提供了类 NotesJob 来使用 Notes.jar 库。类 NotesJob 同步 Lotus Notes 线程访问且与类 UIJob 的使用方式相同,该类在 Eclipse 中同步显示访问。类 NotesJob 如清单 2 所示。
清单 2. NotesJob 示例
NotesJob job = new NotesJob("Job description") {
protected IStatus runInNotesThread(IProgressMonitor mon) {
Session session = NotesPlatform.getInstance().getSession();
// your notes.jar code here
return Status.OK_STATUS;
}
};
job.schedule();
|
一旦在 NotesJob.runinNotesThread 方法中运行代码时,您就可以参照 Lotus Notes 文档和使用指南使用 Notes.jar 中的类和对象。一般而言,Notes.jar 中的类十分贴切地反映了 LotusScript 提供的类。例如,提供了表示数据库、视图和文档的类。在这些组件中是一些表示组件各部分构成的类。例如,在文档中,您可以在富文本中访问字段值和各个单独的段落。更多信息请参考 IBM Lotus Domino Designer Help。
在 Notes.ini 文件中设置变量 BSAFE_ALLOW_REPARENT = 1 的额外步骤可能非常实用。有了该设置,您可以访问后台的类而无需多次提示输入密码。启用该设置后,将阻止随机出现默认的登录对话框。通常,很少会访问 Lotus Notes ID 文件,直到有函数需要访问时才会出现登录提示。启用该项设置后,使 Lotus Notes V8 Eclispe/Java 进程和 Lotus Notes 工作站进程协调了对 ID 文件的访问。这也可以阻止默认密码提示在不必要的情况下出现,同时也没有折损安全性。
应用程序
com.bim.lotuslabs.notes.pim 插件依赖 com.ibm.notes.java.api 使用 Notes.jar 功能,从而使用邮件、日历、联系人和日志应用程序以及所含文档。
类 Applications 提供了在应用程序中启动和执行 Notes.jar 代码的能力。每个应用程序被赋予一个由该类定义的静态 ID,如清单 3 所示。
清单 3. 应用程序类型
public final static int APP_MAIL = 1;
public final static int APP_CALENDAR = 2;
public final static int APP_TODO = 3;
public final static int APP_CONTACTS = 4;
public final static int APP_JOURNAL = 5;
|
将相应的 ID 传递给启动方法,启动对应的应用程序:
Applications.launch(Applications.APP_JOURNAL);
通过调用该类中的 execute 方法,该类能够执行任何这些数据库中的代码。创建一个新接口 IDatabaseRunnable,其中定义了您想调用的代码。该接口提供了一个方法:
public void run(Session session, Database database);
通过使用给定的会话和数据库以及 Notes.jar API,这段代码以完全封闭的方式运行。调用者只需关心代码,而不用关心初始化、依赖项或者前面提到的 NotesJobs。 清单 4 给出了一个示例。
清单 4. 在一个数据库中执行代码
IDatabaseRunnable run = new IDatabaseRunnable() {
public void run(Session session, Database db) throws NotesException {
Document doc = db.createDocument();
// set the fields to make a task
doc.save();
doc.recycle();
}
};
// schedule the creation
Applications.execute(Applications.APP_TODO, "Create task", run);
|
日志交互
在这个模式中,日志程序要比其他应用程序稍微复杂些,因为它没有一个已知的 URL。可以看出,在内部 DatabaseUtil 类中,用户的邮件和联系人的 URL 都已经定义好了。这些用来启动或打开数据库,但是日志程序不同,它的首要任务是决定哪个数据库作为用户的日志。
如图 5 所示,您可以从 Lotuts Notes 主页中启动日志程序。
图 5. Lotus Notes 主页
第一次点击 Personal Journal 按钮时,可以看到如图 6 所示的对话框。它询问您是否已经有了一个日志。如果您没有,它允许您创建一个新的日志。如果您已经有了一个日志,您可以通过点击 Select Personal Journal 按钮告诉 Lotus Notes 它在什么位置。
图 6. Select Personal Journal
com.ibm.lotuslabs.pim 插件使用该机制来定位用户日志。具体来说,它知道日志数据存储在数据库 bookmark.nsf 中的 HPSettings 配置文档中。一旦它找到了该文档,它知道日志服务器和数据库分别保存在 JServer 和 JDatabase 字段中。在第一次访问时,类 JournalUtil 的 getJournalDatabase 方法将会完成查找。
该方法也有可能找不到日志数据库的位置;这可能是因为在日志中尝试执行代码的结果。在这种情况下,类 JournalUtil 打开了一个文件浏览器窗口,用户可以选择本地日志,如图 7 所示。
图 7. 选择日志数据库对话框
数据库的查找需要在预定的 NotesJob 线程中进行。因为这是一个后台线程,无法启动文件浏览器。要进行浏览,需调用 executeJournalUI 方法来启动一个新的 UIJob。假设用户选择了一个日志文件,代码跳回到一个新的 NotesJob 以更新书签的配置文件并运行调用者想要执行的代码。调用者通过传递 IDatabaseRunnable 对象而不是请求 Databse 对象来启用这个多线程的行为。
知道数据库路径后,则可以轻松打开一个应用程序并执行传入的代码。当需要在 launchJournal 方法中启用日志时,可以使用 IDatabaseRunnable 对象。通过请求给定数据库的 URL 并启动该 URL 来实现;如清单 5 所示。
清单 5. 启动日志
public static void launchJournal(final String description, final String append) {
executeJournalThread(description, new IDatabaseRunnable() {
public void run(Session session, Database database) throws NotesException {
String server = database.getServer();
String repId = database.getReplicaID();
if(repId!=null) {
if(server==null)
server = "";
String url = "notes://"+server+"/"+repId;
if(append!=null) {
url += append;
}
DatabaseUtil.launchUrl(url, description);
}
}
});
}
|
SidesNote 动作调用的类 JournalEntry 使用这些机制保存新文档。createJournalEntry 方法使用必需的 IDatabaseRunnable 调用 execute 方法。所执行的代码只需创建一个新的文档以及所有必需的字段,使它成为一个功能完整的日志文档。这些代码可以在类 createJournalDocuemnt 中看到。
Lotus Notes 交互策略
您也许已经注意到了一些模式,库 Notes.jar 擅长于处理数据库内部的数据。您已了解到,com.ibm.lotuslabs.notes.pim 插件演示了如何使用该库从文档中读取数据和创建新的文档。
但是,当涉及到内存操作时,该模型仍然存在着一些缺陷。注意,当您创建一个新的邮件信息时,没有调用 Notes.jar,但是启动了一个 URL。这也完成了目标 - 即创建了一个新的文档, 但没有进行保持。类似地,使用相同的 URL 启动机制,类 JournalEntry 又让您启动了一个新条目以显示日志本身。此方式的局限性是该 URL 不能填充新日志文档的所有字段。
可以使用一些方法解决这个问题。第一,在应用程序中,使用 Notes.jar 创建文档并保存它。然后询问 URL 并启动它。这种方法的缺点是如果自动填充的数据不完整,您就有可能在数据库中留下一个未完成的文件。
第二个方法非常依赖应用程序,它要求数据库和表单完成彼此之间的连接(handshake)。例如,您可以在一个事先命好名的临时文件工作。将 Java 代码写进该文件,然后启动一个新的表单。该表单知道查找那个临时文件,读取它,如果必要的话填充它,然后删除它。您可以想象几种不同形式的连接。
其他的方法就是使用 SWT(Standard Widget Toolkit) 创建您自己的用户界面,使用 Notes.jar 加载数据和保存数值到数据库中。com.ibm.lotuslabs.pim.ui.package 包的 JournalNote 示例如图 8 所示。
图 8. SWT JournalNote
创建该示例的代码如清单 6 所示。
清单 6. 创建一个 JournalNote
public static void showJournalNote(final Composite parent,
final String url) {
IDatabaseRunnable run = new IDatabaseRunnable() {
public void run(Session session, Database database) throws NotesException {
Document doc = (Document) session.resolve(url);
final Map map = JournalNote.createValueMap(doc);
parent.getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
JournalNote note = new JournalNote(parent,map);
});
};
// do it
Applications.execute(Applications.APP_JOURNAL, "Opening journal document", run);
}
}
|
Journal 工具栏
您也许已经注意到了我们并没有使用集成代码中的所有方法。如图 9 所示,大部分代码为经常使用日志的用户提供工具栏支持。该工具栏,由 com.ibm.lotuslabs.journal.ui 插件构成,允许用户启动日志,在编辑模式下创建一个新的空白项以及快速记下一个新的项。
图 9. 日志工具栏
实现启动用户日志的代码是 Applications.lauch 方法。通过传递给日志一个 ID ,启动一个 URL 以显示数据库。以类似的方式,New 按钮调用 JournalEntry.launchNewEntry 方法来显示合适的表单。
之前的文章 “扩展 IBM Lotus Notes V8 侧栏和工具栏” 描述过关于 QuickNote 的概念。日志工具栏使用了相同的代码,但使用了类 JournalEntry 创建一个新的日志文档,而不是在文本文档中保存内容。该特性的优点是用户能快速实现日志记录。优于 QickNote 的另一个优点是不需要创建一个新的信息存储库。
结束语
集成 Lotus Notes 数据能让您的工作变得更加有趣。到目前为止,已经把这些技术应用到了简单的动作上,与此同时,也可以创建出您需要的任何组件。这甚至包括在侧栏中独立存在的完整 IViewPart 实例,或者做为复合应用程序的一部分。
这些使用 Notes.jar 库的简单示例和 IBM Lotus Notes V8 中的其他技术足够支持您开始构建自己的组件了。
下载 | 名字 | 大小 | 下载方法 |
|---|
| notes_data.zip | 26 KB | HTTP |
参考资料 学习
获得产品和技术
讨论
关于作者  | |  | Brian Leonard 是一名 Lotus Notes 客户机开发人员。在 IBM Lotus Notes V8 中,他从事搜索、电子邮件显示、显示图片的装载、拼写检查和可扩展性等方面的工作。他想长高一点,但是没法找到合适的 “扩展点”。 |
对本文的评价
|