[编者注:IBM Lotus Sametime 7.5 尚未面市,但有望今年面市,本文描述的是 Lotus Sametime 7.5 Connect 的 Beta 版。]
IBM Lotus Sametime 7.5 众多功能强大的功能之一就是其天生的可扩展性。因为 Lotus Sametime 客户机以 Eclipse 为基础,所以您可以添加您开发的 Eclipse 插件作为新功能。在本文中,将展示如何构建用于扩展 Lotus Sametime 客户机的用户界面的 Eclipse 插件。本文向您展示的并不是一个简单的 hello world 插件,而是一个许多企业都想添加到他们自己的 Lotus Sametime 客户机中的插件,即 Partner Lookup 插件,该插件可以从目录服务中查看 Sametime 合作伙伴的信息。
本文将带您遍历编写 Partner Lookup 插件时所采用的开发过程。我们将展示如何使用可免费获得的 Eclipse Software Development Kit (SDK),SDK 包括用于插件开发的插件开发环境(PDE)。在阅读本文之后,您可以很好地掌握创建自己的 Eclipse 插件来扩展 Lotus Sametime 7.5 客户机的方式。
可以从 Eclipse Web 站点下载 Eclipse SDK。还可以从本文的 “下载” 部分下载 Partner Lookup 插件。
许多组织使用目录服务来存储有关组织成员的数据。这类目录服务包含有关组成组织的个体的信息,该信息包括这些个体的电子邮件、电话号码以及其他使组织的成员能够彼此保持联系的重要联系信息。市场上有许多目录服务,比如 Microsoft Active Directory 和 OpenLDAP。对于本文,我们选择使用 IBM Tivoli Directory Server 作为我们的 LDAP 服务器。可以从 IBM Software Trials 和 Beta Web 站点下载 Tivoli Directory Server 的试用版。本文假定您已经安装了 Tivoli Directory Server 并正在使用它。
如果不熟悉 Tivoli Directory Server,那么可以阅读 developerWorks 文章 “Introduction to LDAP: Part 1: Installation and simple Java LDAP Programming”,这篇文章将带您遍历 Tivoli Directory Server 的安装过程。
如果使用 Tivoli Directory Server,则需要使用 IBM Tivoli Directory Server Configuration Tool 中的 Manage suffixes 工具(如图 1 所示)为 LDAP 模式添加后缀 dc=ibm, dc=com
,正如 “Introduction to LDAP” 中所描述的那样。
图 1. IBM Tivoli Directory Server Configuration Tool
![IBM Tivoli Directory Server Configuration Tool](https://i-blog.csdnimg.cn/blog_migrate/1f9305bbac29011d767cfaddaaefcc41.png)
为了演示 Partner Lookup 插件的功能,需要使用一些样例数据填充 LDAP 目录。可以从命令行使用 ldapadd 命令将一个条目从轻量级数据交换格式(Lightweight Data Interchange Format,LDIF)文件添加到 LDAP 服务器中。“Introduction to LDAP” 一文描述了如何去做。我们的 LDIF 文件的内容如下所示。
注意:在填充 LDAP 目录之前,必须修改文件的内容。为了使 Partner Lookup 插件收集关于特定 Sametime 合作伙伴的信息,该合作伙伴必须存在于 LDAP 目录中。
我们使用合作伙伴的电子邮件地址查找该合作伙伴的信息。因此,电子邮件地址必须 存在于 LDAP 目录中,因此必须 包含在 LDIF 内容中。您应该修改下面的 LDIF 内容,以反映将在其上执行合作伙伴查找的电子邮件。例如,下面使用的 LDIP 文件的内容包含与电子邮件地址 kbhogal@us.ibm.com 和 talbotm@us.ibm.com 关联的条目的样例数据。
dn: dc=ibm, dc=com dc: ibm description: IBM is a fun place to work. objectClass: dcObject objectClass: organization objectClass: top o: International Business Machines |
为了访问 LDAP 服务器,Java 程序可以使用 Java Naming and Directory Interface (JNDI)。我们假定您了解如何利用 JNDI 使 Java 程序能够访问 LDAP 服务器的基本原理。再一次推荐阅读 “Introduction to LDAP”,这篇文章介绍了掌握我们演示的概念所需要的基础知识。正如您一看就能明白的那样,该 Sametime 插件使用 JNDI 来收集存储在 Tivoli Directory Server 中的 Sametime 联系信息。下面图 2 中所展示的是正在使用的 Partner Lookup 插件的预览。
图 2. Lotus Sametime 7.5 中的 Partner Lookup 插件
![Lotus Sametime 7.5 中的 Partner Lookup 插件](https://i-blog.csdnimg.cn/blog_migrate/9f06ea15b8c46f3c2dbe9c763715e056.png)
除了 Tivoli Directory Server 之外,我们还假定您已经安装了 Lotus Sametime 7.5 客户机。出于学习的目的,我们在同一台物理机器上安装了 Tivoli Directory Server 和 Lotus Sametime 7.5 客户机。当然,在生产环境下,在物理上客户机应该与目录服务器分离。此外,为了开发插件,有必要安装 Eclipse 3.2 SDK,可以从 Eclipse Web 站点 免费获得它。正如前面提到的那样,Eclipse SDK 包括插件开发环境 (PDE) 以及集成开发环境 (IDE),后者是一个工具仓库,您需要用该仓库来创建一个扩展 Lotus Sametime 客户机的开箱即用功能的 Eclipse 插件。
Lotus Sametime 7.5 是基于 Eclipse 的
在我们的指导中,没必要为了开发 Eclipse 插件(如 Partner Lookup 插件)而深入了解 Eclipse。但是,我们假定您对 Eclipse IDE 的概念有基本的了解(请参阅 “参考资料” 部分以获得更多信息)。为了开始着手进行 Eclipse 插件开发,让我们了解一些基本的 Eclipse 术语。
Eclipse 插件是用于 Eclipse 平台的组件。您可以配置一个插件,将它用于 Eclipse 平台的用户界面,或者为 Eclipse 平台提供非基于用户界面的(non-user-interface-based)服务。Eclipse 插件可以使用扩展点模式来定义扩展 点。扩展点模式定义了某一插件(称为 extender 插件)如何通过声明扩展 来修改主机插件。扩展点是在主机插件上定义的,所以这些扩展由 extender 插件声明。
例如,扩展点可以定义修改主机插件的菜单项的方式。Lotus Sametime 7.5 客户机有一个插件,该插件定义了一个 ID 为 com.ibm.collaboration.realtime.people.personAction 的扩展点。在本文中,将创建一个扩展此扩展点的功能的扩展。更具体地说,将添加图 2 中以图形方式描述的 Partner Lookup 功能。
在本文的其余部分,我们将 Eclipse 3.2 SDK 称为 Eclipse。在已经安装 Eclipse 之后,请打开它。要开发 Eclipse 插件,请选择 Window - Open Perspective - Other 切换到 Plug-in Development 透视图。出现 Select Perspective 对话框,如图 3 所示。然后请选择 Plug-in Development 并单击 OK。
图 3. Select Perspective 对话框
![Select Perspective 对话框](https://i-blog.csdnimg.cn/blog_migrate/d3fdcb85bfd742e91dc7ac7daa9ca64e.png)
默认情况下,PDE 通常被设置来扩展 Eclipse 平台。不过,我们打算编写一个插件来扩展 Sametime 客户机应用程序。为此,需要配置 PDE 来扩展 Lotus Sametime 而不是 Eclipse。在更改 Target Platform 时就会了解到这一点。要更改 PDE 中的目标平台,请选择 Window - Preferences。Preferences 对话框将会出现。在左侧窗格中展开 Plug-in Development 项。然后选择 Target Platform preference,如图 4 中所示。
图 4. 选择 Target Platform Preference
![选择 Target Platform Preference](https://i-blog.csdnimg.cn/blog_migrate/7bee96388f56d39e8861493fba50e7dc.png)
接下来,使用 Browse 按钮将目标平台的位置更改为 Sametime 客户机目录。然后单击 Reload 按钮,通过这样做来加载 Sametime 插件。如果 Sametime 插件没有出现,请检查一下,确保为 Sametime 客户机目录输入的路径是正确的。该路径必须指向包含插件目录的文件夹。单击 Apply,然后单击 OK。
使用 Partner Lookup 插件扩展 Sametime 用户界面
现在就已经准备好 PDE 了,您可以卷起袖管,开始实际开发插件了。在 Eclipse 中选择 File - New Project,并从随后出现的 New Project 对话框中选择 Plug-in Development - Plug-in Project,如图 5 中所示,然后单击 Next。
图 5. New Project 对话框
![New Project 对话框](https://i-blog.csdnimg.cn/blog_migrate/aef003c178a993549f48d8fc6eebc045.png)
接下来会出现 New Plug-in Project 向导。将项目命名为 com.devWorks.example.ldaplookup,接受默认值,然后单击 Next。取消对 “This plug-in will make contributions to the UI” 选项的选定。如果该选项被选定,则 Activator 类将扩展 AbstractUIPlugin。不过,如果取消选择该选项,则 Activator 类将扩展 Plugin 类(这正是您所希望的)。
Activator 类以用户的名义指定插件的生命周期。AbstractUIPlugin 扩展 Plugin 类。AbstractUIPlugin 提供少量额外的方法,并提供对 Eclipse GUI 的直接访问。因为没有直接作用于用户界面,所以没有必要扩展 AbstractUIPlugin 类。您可以通过扩展点作用于 Eclipse 用户界面。在取消选择上述选项之后,请单击 Finish。Package Explorer 窗格将会出现,如图 6 所示。
图 6. Package Explorer
![Package Explorer](https://i-blog.csdnimg.cn/blog_migrate/c1e6dc73029f3198e84f6dfe1db5a0cb.png)
接下来将编辑插件的清单文件。更具体地说,将修改清单文件来指定额外的插件,Partner Lookup 插件需要使用这些插件来扩展 Lotus Sametime 客户机的用户界面。双击 META-INF/MANIFEST.MF 文件。这将打开 Plug-in Manifest Editor。如果 Plug-in Manifest Editor 没有出现,则双击 MANIFEST.MF 并选择 Open With - Plug-In Manifest Editor。在 Manifest Editor 中选择 Dependencies 选项卡。然后单击 Add 按钮,如图 7 所示。
图 7. Plug-In Manifest Editor 中的 Dependencies 选项卡
![Plug-In Manifest Editor 中的 Dependencies 选项卡](https://i-blog.csdnimg.cn/blog_migrate/8c94067cb5b4678d6f5d0512e913987a.png)
Plug-In Manifest Editor 是 build.xml、plugin.xml 和 MANIFEST.MF 的 GUI 表示形式。在单击 Add 按钮之后,将出现一个带有可用插件列表的对话框。将 com.ibm.collaboration.realtime.people 插件和 org.eclipse.jface 插件都添加到您所需要的插件列表中。
如果已经有了 org.eclipse.ui 插件作为依赖项,则 org.eclipse.jface 依赖项就不再是必需的。如果对话框中没有出现任何一种插件,则需要验证目标平台是否正确。在完成上述操作之后,请保存并关闭 Plug-in Manifest Editor。
接下来,将创建一个类,当 Sametime 用户右击合作伙伴的名称并从上下文菜单中选择 Partner Lookup 项时,将调用该类。这个类(我们将其命名为 com.devWorks.example.ldaplookup)扩展了 RefreshPersonAction 类,后者是从 com.ibm.collaboration.realtime 插件中获得的,前面我们曾为该插件声明了一个依赖项。
在创建 LDAPLookup 类之后,可使用通过 com.ibm.collaboratoin.realtime.people 插件公开的扩展点将 LDAPLookup 类绑定到 Lotus Sametime UI。
使用包名称 com.devWorks.example.ldaplookup 创建一个名为 LDAPLookup 的 Java 类,如图 8 所示。该类扩展 com.ibm.collaboration.realtime.people.actions.RefreshPersonAction 类。RefreshPersonAction 类扩展抽象类 com.ibm.collaboration.realtime.people.actions.PersonAction。
图 8. New Java Class 对话框
![New Java Class 对话框](https://i-blog.csdnimg.cn/blog_migrate/1164c97fa2202190c565a102df01289f.png)
在调用扩展点的标签中定义的菜单名时,将调用扩展 PersonAction 类的对象的 public void runWithEvent(Event arg0) 方法。在本例中,我们用代码覆盖(override)了 runWithEvent 方法,以连接到 LDAP 服务器并显示与合作伙伴有关的联系信息。
为了更清楚起见,我们定义了一个叫做 com.devWorks.example.ldaplookup.LDAPConfig 的类。要具体化 LDAP 服务器的配置信息,需要连接到带有属性文件的 LDAP 服务器。在生产环境中,应该将作为配置项的字符串具体化为一个 Eclipse 首选项。应该将显示给用户的字符串国际化。要了解有关 Eclipse 首选项的更多信息,以及 Eclipse 如何处理国际化的更多信息,请参阅 “参考资料” 部分。为了简便起见,我们没有使用 Eclipse 首选项实现具体化,也没有使用国际化实现具体化。
在启动 Lotus Sametime 客户机时,Partner Lookup 插件将尝试建立到 LADP 服务器的连接。此连接用于用户的整个 Sametime 会话。更具体地说,将触发 Activator 类的 start 方法,而该方法又调用了 Activator 类的 initializeLDAP 方法。
注意:每个插件都有一个 Activator 实例。因此,我们会将 LDAP 连接缓存为 Activator 实例的一部分,而不是每次使用 Partner Lookup 上下文菜单时都建立一个 LDAP 连接。
在下面的代码中,将获得 javax.naming.directory.DirContext 对象的一个句柄。
private void initializeLDAP() { try { Properties props = new Properties(); // Setup your environment here props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); props.setProperty(Context.PROVIDER_URL, LDAPConfig.getString("LDAPLookup.ldapserver")); props.setProperty(Context.URL_PKG_PREFIXES, "com.sun.jndi.url"); props.setProperty(Context.REFERRAL, "ignore"); props.setProperty(Context.SECURITY_AUTHENTICATION, "simple"); |
正如前面所提到的,在前面的代码中,利用了一个叫做 LDAPConfig 的辅助类,该类指示如何连接到 LDAP 服务器。
public class LDAPConfig { private static final String BUNDLE_NAME = “com.devWorks.example.ldaplookup.ldapconfig"; private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); |
LDAPConfig 类期望显示一个保存 LDAP 服务器的配置信息的资源绑定(以名为 ldapconfig.properties 的文件的形式)。您需要更新 ldapconfig.properties 文件,以反映您自己的 LDAP 服务器位置、属性以及用来访问服务器的经授权的凭证:
LDAPLookup.ldapserver=ldap://<server-name>:389 LDAPLookup.ldapusername=<cn=yourusername> LDAPLookup.ldappassword=<yourpassword> LDAPLookup.EOL= |
查找特定 Sametime 合作伙伴的相关 LDAP 条目的逻辑是用 runWithEvent 方法执行的,我们将详细分解该方法,以帮助您理解它。正如前面所提到的,当调用扩展点标签中定义的菜单名时,会触发 runWithEvent 方法。
用 runWithEvent 方法做的第一件事就是提取您感兴趣的 Sametime 合作伙伴的邮件地址。我们的 Sametime 合作伙伴是 com.ibm.collaboration.realtime.people.IPerson 对象。通过调用 getContactId 方法获得 IPerson 对象的邮件地址。此邮件地址字符串被用作执行 LDAP 查询的标准(用 LDAP 术语来说是搜索过滤器)。
IPerson person = getPersons()[0]; String id = person.getContactId(); String ldapMessage = “”; System.out.println("Performing Lookup for" + id); |
接下来,将获得前面使用 Activator 类的 initializeLDAP 方法建立的 LDAP 连接的一个句柄。通过 javax.naming.directory.DirContext 对象,您就有了一个到 LDAP 服务器的连接。
DirContext ctx = Activator.getDefault().getLDAPConnection();
接下来,将使用 SearchControls 对象建立 LDAP 的搜索范围以及搜索返回的结果:
SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); constraints.setReturningAttributes(new String[] { "sn", "description", "homephone", "cn" }); String filter = "mail=" + id; String BASE_SEARCH = ""; |
过滤标准是邮件地址。所请求返回的是姓氏 (sn)、描述、住宅电话和普通名称 (cn)。
接下来,将利用以下调用,使用刚才建立的约束条件和过滤器来执行 LDAP 服务器查询。返回结果将以 javax.naming.NamingEnumeration 对象的形式返回给您。
NamingEnumeration results = ctx.search(BASE_SEARCH, filter,constraints);
接下来,将在结果上进行循环遍历,将它们连接成一个字符串 (ldapMessage),插件提供该字符串作为响应。
SearchResult sr = (SearchResult) results.next(); Attributes attributes = sr.getAttributes(); NamingEnumeration attributeNames = attributes.getIDs(); ldapMessage = ""; while (attributeNames.hasMoreElements()) { String attributeName = (String) attributeNames.next(); Attribute attribute = attributes.get(attributeName); String attributeValue = (String) attribute.get(); ldapMessage = ldapMessage.concat(attributeName + "=" + attributeValue + Messages.getString("LDAPLookup.EOL")); } |
最后,使用一个 org.eclipse.swt.widgets.MessageBox 小部件来显示 LDAP 查询的结果:
Shell shell = new Shell(); MessageBox messageBox = new MessageBox(shell, SWT.OK); messageBox.setMessage(ldapMessage); messageBox.setText("LDAP lookup for " + id); messageBox.open(); |
在创建了 PersonAction 类之后,还需要创建一个 Partner Lookup 菜单项来访问 Lotus Sametime GUI 中的 Partner Lookup 插件。要为 Lotus Sametime GUI 创建上下文菜单项,必须扩展通过 Sametime com.ibm.collaboration.realtime.people 插件向您公开的扩展点。
要做到这一点,需要使用 Plug-in Manifest Editor 打开 plugin.xml 文件。如果 plugin.xml 不存在,则使用 Plug-in Manifest Editor 像刚才所做的一样打开 MANIFEST.MF 文件,并选择 Extensions 选项卡。当完成在 Extensions 选项卡中定义扩展时,将创建 plugin.xml(如果它不存在)。在 Extensions 选项卡中单击 Add 按钮。
选择 com.ibm.collaboration.realtime.people.personAction 扩展点并单击 Finish,如图 9 所示。
图 9. 添加一个新的扩展
![添加一个新的扩展](https://i-blog.csdnimg.cn/blog_migrate/8347b562c22a0d0f3a811c5f01700a03.png)
如果 plugin.xml 选项卡在使用 Plug-In Manifest Editor 之前没有显现,那么现在它应该显现了。单击 plugin.xml 选项卡并编辑 plugin.xml,这样它就会具有下面的扩展点声明:
<extension point="com.ibm.collaboration.realtime.people.personAction"> <personAction class="com.devWorks.example.ldaplookup.LDAPLookup" id="com.devWorks.example.ldaplookup.LDAPLookup" label="Partner Lookup"/> </extension> |
我们为 com.ibm.collaboration.realtime.people.personAction 扩展点定义了三个配置项。首先定义了扩展 PersonAction 抽象类的类。对于这个类,我们定义了我们创建的类 (com.devWorks.example.ldaplookup.LDAPLookup)。对于 id,我们定义了等同于 Lotus Sametime 7.5 客户机的 id。标签描述了如何将菜单显示给用户。在本例中,我们决定创建一个叫做 Partner Lookup 的菜单项。
从 Eclipse 的 Run 菜单中选择 Run。在 Run 对话框的左窗格中,右击 Eclipse Application 并选择 New_configuration。您就可以配置您的应用程序了,如图 10 所示。
图 10. Run 对话框
![Run 对话框](https://i-blog.csdnimg.cn/blog_migrate/f2efd0d78088192fb191d9c936fb80a8.png)
Lotus Sametime 客户机应该表现为就像在 Eclipse 以外的地方运行一样,如图 11 所示。
图 11. Eclipse 中的 Lotus Sametime 7.5 客户机
![Eclipse 中的 Lotus Sametime 7.5 客户机](https://i-blog.csdnimg.cn/blog_migrate/21b02e1aa498f718b07c398923de5cce.png)
出于测试目的,我们使用 IBM 公共 Lotus Sametime 服务器 messaging.ngi.ibm.com 来登录。从 IBM Community Tools Web 站点 可以了解有关公共 Lotus Sametime 服务器的更多信息。当与 IBM 公共 Lotus Sametime 服务器交互时,使用的用户名和口令与您的 IBM 用户名和口令相同。可以通过注册为 IBM Web 站点的一名用户来获得 IBM 用户名和口令。我们假定在您的列表中至少有一个 Sametime 合作伙伴,还假定您已经将前面获得的信息添加到 LDAP 服务器中(请参阅 “Partner Lookup 插件的预览和准备” 一节)。
在登录后,Lotus Sametime 7.5 将如图 12 所示。右击一名合作伙伴的姓名。正如前面所声明的那样,在您的 LDAP 服务器中,应该包含根据 Sametime 合作伙伴的相关邮件地址为他们建立的目录信息。还应该看到一个 Partner Lookup 上下文菜单项。请选择 Partner Lookup 菜单项。
图 12. Lotus Sametime 7.5 客户机
![Lotus Sametime 7.5 客户机](https://i-blog.csdnimg.cn/blog_migrate/98979ba03040e86b06d8d4efde8973a3.png)
调用创建的插件并查询 LDAP 服务器。如果所有一切都正确设置,则将会出现如下所示的对话框(参见图 13),它反映了存储在您的 LDAP 服务器上的 Sametime 合作伙伴的信息。
图 13. LDAP 查询对话框
![LDAP 查询对话框](https://i-blog.csdnimg.cn/blog_migrate/f3fb28993ed62e9163f79fe624f41c8d.png)
部署新的插件并在 Lotus Sametime 客户机应用程序(而不是 Eclipse)中实际使用它非常简单。先从 Eclipse 公开插件的 JAR 文件。然后将导入的插件 JAR 文件复制到 <sametime-root>/eclipse/plug-in 目录中,其中 <sametime-root> 是安装 Lotus Sametime 客户机的目录。如果 Lotus Sametime 目前正在运行,则重新启动它,以检测该插件。然后 Eclipse 插件成为了 Lotus Sametime 客户机的一部分。
对于开发人员,使用上述开发方法将插件添加到 Lotus Sametime 就应该足够了。但是,为包含数百或数千名客户的企业环境供应插件又是另外一回事。在这种情况下,企业可以创建他们自己的更新站点,基于 Eclipse 的客户机可以从该站点获得更新。有关插件供应和更新站点的使用的更多信息,请参阅 “参考资料” 部分。
在本文中,学习了如何扩展 Lotus Sametime 7.5 客户机的功能。因为 Lotus Sametime 客户机是基于 Eclipse 的,所以扩展 Lotus Sametime 客户机是有可能的。Lotus Sametime 客户机公开了可以通过创建定制插件来插入的插入点。此定制插件可以通过声明一个扩展来修改主机插件。在本文中,我们演示了如何创建可访问 LDAP 服务器和检索与 Sametime 合作伙伴有关的信息的定制插件。
描述 | 名字 | 大小 | 下载方法 |
---|---|---|---|
Sample plug-in code | sametimeLDAP.zip | 6 KB | HTTP |
学习
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
- developerWorks Lotus 文章 “了解 IBM Lotus Sametime 7.5 中的新特性和新技术”
- developerWorks 文章 “Introduction to LDAP: Part 1: Installation and simple Java LDAP Programming”
- Lotus Sametime 7.5 页面
- Eclipse 文档
- 来自 Eclipse.org 的 “Notes on the Eclipse Plug-in Architecture”
- 来自 Eclipse.org 的 “How to Keep Up To Date” 提供了关于 Install/Update Site 和客户机 Update Manager 的更多信息
- 来自 Eclipse.org 的 “Preferences in the Eclipse Workbench UI”
- 来自 Eclipse.org 的 “How to Internationalize your Eclipse Plug-In”
获得产品和技术
- 从 Eclipse.org 下载 Eclipse SDK。
- 从 IBM.com 下载 IBM Tivoli Directory Server 的免费试用版。
讨论
Kulvir Singh Bhogal 是 IBM 的 Software Services for WebSphere 顾问,在美国各地的客户站点上开发和实现以 Java 为中心的解决方案。您可以通过 kbhogal@us.ibm.com 与 Kulvir 联系。