扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
对于团队合作开发项目来说,IBM Lotus QuickPlace 是一个很好的方法。QuickPlace 提供一些基本的版本控制,比如签出、签入以及创建新的修订版的功能。它不提供对文档早先完成的编辑进行跟踪了解的方法。通过集成 QuickPlace 与 IBM Lotus Domino Document Manager,我们可以使用 Domino Document Manager 的版本控制来保存 QuickPlace 文档的修订历史。
QuickPlace 和 Domino Document Manager 集成概述
QuickPlace/Domino Document Manager 集成是通过使用 Domino Document Manager API 关联 QuickPlace 事件(比如创建和编辑一个文档)来完成的。这允许我们在 Domino Document Manager 中实时存储或查看 QuickPlace 文档。Domino Document Manager API 用于在 Domino Document Manager 中创建一个相应的文档、文档的新版本以及签出或签入一个现有的文档。
在 Domino Document Manager 中,集成还需要一个新的 QuickPlace 主题和一个新的文档类型。使用一个修改过的 QuickPlace 主题允许我们选择 QuickPlace 的外观和行为。修改过的主题隐藏了一些 QuickPlace 动作,并给存储在 Domino Document Manager 中的文档写一个链接。新的文档类型必须存储有关 QuickPlace 文档的恰当信息。
我们使用一个 Domino Document Manager 文件柜来存储 QuickPlace 中一个地方所有的内容。Domino Document Manager 将为每个文件夹创建一个相应的绑定器。在 QuickPlace 中创建一个文档会导致在 Domino Document Manager 创建一个文档。QuickPlace 页面的内容会被复制到 Domino Document Manager 中的文档,这意味着它将存在于两个地方。当编辑一个 QuickPlace 页面时,在 Domino Document Manager 中的文档会被签出。当用户发布对 QuickPlace 页面的改动时,一个新的版本在 Domino Document Manager 中创建。用户可以在任何时候单击 Domino Document Manager 文档的链接,通过 Domino Document Manager UI 来查看修订历史。在修订历史中,可以看到 QuickPlace 页面的实际内容。图 1 是该过程的图解。
图 1. QuickPlace/Domino Document Manager 集成
|
先决条件
在开始 QuickPlace 和 Domino Document Manager 集成之前,先完成下面的步骤:
在开发代码的时候,我的机器上装的是 Domino 6.5.1、QuickPlace 6.5.1 和 Domino Document Manager 6.5.1。这对我非常有用,因为我能对代码进行跟踪调试。如果您计划定制代码,我推荐在这种环境中进行开发 —— 它会使事情变得更加容易。(稍后,本文将讨论调试。)
|
创建 QuickPlace 关联
关联是这个集成示例的核心。它是实时集成发生的地方。本节描述如何在 Visual C++ 中建立一个工程、导入源代码并进行编译。本文自带的压缩文件中有一个编译过的关联文件。如果决定使用它,还应当在稍后阅读本文中描述代码的部分。您应当熟悉它是如何工作的,以了解会发生些什么。
创建一个 Visual C++ 工程
第一步是在 Visual C++ 中创建一个新的工程:
添加类
既然我们已经创建了工程,就需要添加调用 Domino Document Manager API 的类。下面几步将完成这项工作。
现在,工程中应该有 DDOC2API.CPP 和 DDOC2API.H 两个文件。
导入 C++ 文件
下一步是从压缩文件中导入 C++ 文件。如果以 QPDD 命名工程,先完成下面的步骤。
如果没有以 QPDD 命名工程,就需要从 QPDD.CPP 复制一些代码到以您的工程名命名的 C++ 文件:
//---Utility functions
#include "utilities.h"
//--- QDK header file
#include <qdk.h>
//--- Functions to process QP hook events
#include "QPPageFuncs.h"
//--- The Domino Document Manager API
#include "ddoc2api.h"
工程属性
最后,需要修改一些工程属性:
现在应该编译工程。如果接收到提示某些函数已经在 LIBCMT.lib 中定义过了的错误消息,请进入工程属性对话框,确定在对话框的左边框架里选中了整个工程。选择 Link 标签,Input 类目。在 Ignored Libraries 域中键入 libcmt.lib。这将消除错误,而且应该正确地编译并连接代码。
|
关联代码
当您阅读本节的时候,如果眼前就有代码,那将是非常有帮助的,在讨论到它的时候就有代码可以参考。
QPDD.cpp
我们将从 QPDD.cpp 文件开始讨论。该文件包含了向 QuickPlace 注册关联的代码,以及从 QuickPlace 调用的函数。向 QuickPlace 注册关联的代码在文件的底部。参见 QDK 文档数据库(qdkdoc.nsf),获取有关关联和可处理事件的更多细节。
函数 PageHook 是在 h_Page 动作事件中从 QuickPlace 调用的。h_Page 动作处理所有页面事件的所有不同方面(参见 QDK 文档获取更多信息)。我们只想处理与编辑和发布页面有关的事件。因此,我们在 PageHook 函数中首先要检查的就是页面命令是否为 h_MakeDraftFromPublishedVersion 或者 h_Publish。在确定文件正在编辑或正在发布以后,我们调用一个函数来验证该文档是否配置为进行 Domino Document Manager 集成的。进行验证的函数在 utilities.cpp 文件中定义。稍后,我们会讨论它。如果文档正在编辑,我们调用一个函数来签出 Domino Document Manager 中相应的文档。如果文档正在发布,我们调用一个函数来创建文档,或在 Domino Document Manager 中创建一个新的版本。
QPPageFuncs.cpp
我们讨论的下一个文件是 QPPageFuncs.cpp。该文件包含了两个函数,从 QPDD.cpp 中的 PageHook 函数调用它们。在该文件中,第一个函数是 cmdCheckOut。在编辑一个页面的时候调用这个函数。它所要做的是连接到 Domino Document Manager API,在 Domino Document Manager 中查找正在处理的 QuickPlace 文档所对应的文档,并且签出它。文档在 Domino Document Manager 中被签出,这反映了 QuickPlace 文档的状态。如果用户把 QuickPlace 页面保存为草稿,那么它不会做任何事情。Domino Document Manager 文档会保持已签出状态(这可以被修改;本文稍后会讨论到它)。
QPPageFuncs.cpp 中的下一个函数是 copyToDomDoc。在发布一个页面的时候调用这个函数。它先获取一些属性并连接到 Domino Document Manager API。然后,它检查 QuickPlace 文档寻找名为 h_ddCheckedOut 的域。该域在 cmdCheckOut 函数运行的时候创建。它告诉我们文档在 Domino Document Manager 中被签出。如果该域存在,我们得到 Domino Document Manager 中文档的工作副本的句柄。否则,我们在 Domino Document Manager 中创建一个新文档。
在创建一个新文档的情况下,我们连接到用于这个 QuickPlace 的文件柜。然后,我们会连接到与该 QuickPlace 文档正在发布到的文件夹相匹配的绑定器。如果绑定器不存在,就创建它。注意,绑定是作为 Categorized Binder 创建的。如果这个绑定器类型不允许用于文件柜,将会产生错误并且文档不会被保存在 Domino Document Manager 中。在拥有绑定器的句柄之后,我们在里面创建一个文档并设置一些配置信息。设置的信息有 QuickPlace 页面类型、名字和 QuickPlace 的位置,以及其他有关 QuickPlace 文档的信息。
在现有文档的情况下,我们只获得 Domino Document Manager 文档的句柄。
这时,代码合并并附着关联 QuickPlace 内容(如果它不是 Microsoft 文档页面)。如果它是链接页面或普通页面,那么稍后会设置该内容。在本例中,没有配置使用其他类型的页面(尽管可以容易地修改它来实现)。下一件事是保存并签入 Domino Document Manager 文档。在将文档签入 Domino Document Manager 之后,存储一些关于 QuickPlace 文档的信息。这样做是为了在 Domino Document Manager 中跟踪文档保存在哪里。这同样有助于识别保存在 Domino Document Manager 中的文档。
在设置完信息之后,我们使用 Notes C API 在 Document Manager 中获取文档的句柄。在普通 QuickPlace 页面或链接页面的情况下,我们需要这样做。这些页面类型的内容不能通过 Domino Document Manager API 来设置,因为它不处理多信息文本(rich text)格式的内容。对于链接页面,我们只是复制 QuickPlace 文档中存储链接的域,并把它转换为 Domino Document Manager 文档中的多信息文本。对于普通页面,我们复制所有的附件和所有的 PageBody 域。在这样做之前,我们需要删除也许已经以那个名字存在的任何域。该场景在签入随后的修订版到 Domino Document Manager 时发生。在该内容复制到 Domino Document Manager 之后,我们更新并关闭文档的句柄。函数在这时候结束;它只需要做一些 Domino Document Manager API 对象的清理工作。
rtaccess.c
对这个文件不需要过多的说明。它包含了三个实用函数。函数 cLogMessage 向日志文件写入一个消息。函数 convertTextToRT 用来把文本域转换为多信息文本。这个函数主要用来支持链接页面。函数 lnScanField 由 utilities.cpp 中的 dumpNoteToLog 函数使用。
utilities.cpp
这个文件包含大量的实用函数。该文件有很好的注释,所以我不会描述每一个函数。不过,我想要说一下 shouldProcessNote 函数。从 QPDD.cpp 中的 PageHook 函数调用它。它决定关联是否应该处理一个 QuickPlace 文档。它从检查 h_ddDocID 域开始。这个域存在的唯一情况是我们已经在前面处理过它,并且在 Domino Document Manager 中存在一个副本。如果这个域不存在,我们继续按一套标准对文档进行测试。这里是标准的流程表。
在这个演示中,集成是由一套 Notes.ini 变量来配置的。有配置该集成的更好方法,但原则是保持简单。关于如何实现的其他想法会在后面的部分进行讨论。
|
配置 QuickPlace 和 Domino Document Manager 服务器
为了进行集成,Domino Document Manager 服务器和 QuickPlace 服务器都需要配置。为允许集成和在两个产品间提供链接,这些变更是必需的。
Domino Document Manager 变更
Domino Document Manager 服务器需要创建一个新的文当类型,以及进行一些其他的次要变更。从示例压缩文件(QPDD.zip)提供的数据库中可以得到这个新的文档类型的子表单(subform),可以从本文结尾的“下载”一节中下载该压缩文件。在 Domino Designer 中打开数据库,复制子表单 QuickPlace Page 到您的文件柜模板(缺省为 filecab.ntf)。同样,当 File Cabinet 模板在 Domino Designer 中打开时,打开 DocContent 表单。需要添加一个 PageBody 域到 Body 域的下一行。PageBody 域在 QuickPlace 页面被存储在 Domino Document Manager 中时使用。创建这个域的最容易的方法是简单地复制并粘贴 Body 域,然后重命名为 PageBody。它应该是一个多信息文本,一个可编辑的域。
在完成 File Cabinet 模板的变更之后,在 Domino Document Manager 的服务器控制台完成一个负载设计(以便更新所有的文件柜数据库)。然后,根据 Domino Document Manager Administrator’s Guide 中的说明创建一个叫做 QuickPlace Page 的新文档类型。在该文档类型创建完成之后,务必在所有将要存储 QuickPlace 内容的文件柜中启用它。
QuickPlace 用户需要被授权访问存储 QuickPlace 内容的 Domino Document Manager 文件柜。如果他们未经授权而访问,就看不到先前的版本。QuickPlace 用户应该被授予读者访问权限,而不是编辑或管理员访问。如果他们被授予编辑或管理员访问,就可以从 Domino Document Manager 编辑或删除内容。这会导致页面内容与 QuickPlace 中的不一致。有关 Domino Document Manager 安全的更多信息,请参见 Domino Document Manager Administrator’s Guide。
QuickPlace 变更
QuickPlace 服务器同样需要做一些变更来支持集成。需要用一个新的主题来显示 Domino Document Manager 文档(如果有的话)的链接。对主题的变更是相当小的,因此可以把它们合并到一个现有的自定义主题(如果有的话)。有关自定义主题的更多细节,请参见IBM Redbook “Customizing QuickPlace”。
唯一需要定制的页面是页面布局文件。本文附带的压缩文件中有一个示例页面布局文件。关于该页面首先要注意的是它包含一些 JavaScript。这两个函数用来确定当前页面是否在 Domino Document Manager 保存了它的内容,并写一个到 Domino Document Manager 中的文档的链接。这里是该 JavaScript 代码的清单:
function isDomDoc(){ // returns 1 if this document has a doc in DomDoc // returns 0 otherwise if(fieldNames){ if(fieldNames.h_ddDocID){ // this document is also stored in DomDoc return 1; } else { // Document not stored in DomDoc return 0; } } else { // must be some kind of error, return 0 return 0; } return 0; } function writeDomDocLink(){ // Writes a link to the document in DomDoc if( isDomDoc() ){ document.write('<a href="'); document.write(fieldNames.h_ddURL); document.write('/'); document.write(fieldNames.h_ddDocDbRepID); document.write('/(DDMAutoLaunch)?OpenAgent&DocID='); document.write(fieldNames.h_ddDocURLID); document.write('&LaunchType=0">View document in Domino Document Manager</a>'); } } |
下一变更开始于第 279 行。它插入一个新列到一个表格并写一个到 Domino Document Manager 中的文档的链接。如果您不喜欢链接安放的地方,可以随意移动 HTML 代码到一个更加合适的位置。这里是插入的 HTML 代码:
<tr><!-- Write link for DomDoc document -->
<td><script>writeDomDocLink();</script></td>
</tr>
对主题的另一变更是隐藏某些动作。隐藏这些动作是因为它们不是被配置为进行 Domino Document Manager 集成的。让它们有效也许还会在用户之中引起混乱。如果您愿意使它们继续有效,请随意;只是要注意,在集成中没有处理这些动作的代码。
page.htm 文件的第 93 行和第 340 行有效地隐藏了下列动作:
除了 QuickPlace 中的新主题,必须在 QuickPlace 服务器上启用一些 Notes.ini 属性。下面是所有 Notes.ini 属性的一个列表和对它们做些什么的描述。任何包含 <QuickPlace Name> 的属性应该以 QuickPlace 的实际名称(如同在用于连接到它的 url 中所显示的那样)来取代。例如,如果您的 QuickPlace 以 qpdd 命名,一个 Notes.ini 属性会是 qpdd_ddURL。如果这些属性在 Domino 运行的时候添加,您需要重启 Domino 来使之生效。
|
测试集成
在集成配置完以后,测试应该相当容易。进入为集成配置的 QuickPlace。新建一个文档,使用任何支持的页面类型,在一个配置用来集成的文件夹中发布文档。在发布完文档以后,返回并查看。在文档的顶部,应该有一个链接“View document in Domino Document Manager”。单击该链接会带您到 Domino Document Manager 中的文档。如果选择 Document - View,您应该会看到 QuickPlace 文档的内容。
返回到 QuickPlace,找到刚才创建的文档。编辑,对内容做一些更改并发布。在 QuickPlace 中再次查看文档,单击“View document in Domino Document Manager”链接。您将再次被带到 Domino Document Manager 中的文档。选择 Document - Revision History,可以查看所有过去版本的列表。单击版本一,然后选择 Document - View,将显示该文档的第一个版本。查看文档的第二个版本将显示文档现在的内容。如果这些步骤生效,恭喜您!集成得到了适当的配置并运行良好。
调试集成
如果能够把 Domino、Domino Document Manager 和 QuickPlace 全部安装在您的机器上,就可以调试关联代码。调试代码的功能在定制的时候非常有用,因为能确切地看到在运行时会发生些什么。如果没有这种功能,可以给代码添加辅助的记录语句并依此进行调试。
这里是一个步骤列表,它描述如何配置 Visual C++ 工程来调试代码。
为实际载入调试器,确定编译过代码并且 Domino 程序目录中的 DLL 是最新的。启动 Domino,确定没有载入 HTTP 任务(如果载入,就关掉它)。在 Visual C++ 中,选择 Build - Start debug - Go。这将启动 HTTP 任务。在它载入之后,连接到 QuickPlace 并在一个用来进行集成的文件夹中创建一个页面。当页面发布的时候,调试器应当打开而且可以跟踪代码(假定至少设置了一个断点)。
|
增强的可能
可以做很多的事情来使我们的例子更加强大。下面是可以在本例中实现的想法列表。
可以修改示例来保存 QuickPlace 草稿为 Domino Document Manager 中的草稿。在 Domino Document Manager 中保存草稿会提供 QuickPlace 文档的完整历史。必须修改代码来寻找 h_SaveUnderConstruction 页面命令。这个命令发生的时候,应当生成对 shouldProcessNote 的调用。这将检验文档符合保存在 Domino Document Manager 中的那套标准。代码应当在 copyToDomDoc 函数之后改变。它应当检查文档是否已经保存在 Domino Document Manager 中。如果已经保存,应当检索文档并生成新的草稿。如果文档没有保存在 Domino Document Manager 中,应当新建一个文档并作为草稿签入。
可以修改支持 Domino Document Manager 集成的 Notes.ini 属性,使之更加友好。在起初的原型中,我在存储所有属性的 QuickPlace 中创建了一个自定义页面。这样,可以通过现行的 QuickPlace 修改属性,而不需要重启服务器。集成代码从该页面检索值而不是从 Notes.ini 属性检索。另一个方法是创建一个自定义数据库来为多个 QuickPlace 保存所有的属性。这种方法提供对存在于服务器上的所有 QuickPlace 的集成进行配置的单一位置。
可以修改代码来处理自定义 QuickPlace 页面。例如,如果有一个自定义 QuickPlace 页面,可以在 Domino Document Manager 中创建一个基于 QuickPlace 页面文档类型的新文档类型。这个新的文档类型可以包含存在于 QuickPlace 页面之上的自定义域。
可以在使用用户空间的 QuickPlace 中测试代码。需要适当地修改集成代码来使之在这样的场景中工作,但这不会花费太多的精力。
可以隐藏 Domino Document Manager 的链接,或从 QuickPlace 移除。链接移除之后,就没有可见的证据表明内容被保存在 Domino Document Manager 中。有时候,这也许是期望的,因为终端用户不会知道它们的更改正在被跟踪。
可以修改代码来使用当前在自定义主题中隐藏的动作。同样,可以修改它来使用文件夹清理动作。也许关联到那个动作并提供立即转移多个文档到 Domino Document Manager 的功能是可能的(可能针对在集成之前已经存在的 QuickPlace)。
|
总结
通过关联到 QuickPlace 事件,可以在 Domino Document Manager 中实时存储内容。一旦有内容存在,就可以使用 Domino Document Manager 的所有特性。可以查看内容的修订历史,允许归档设置,实现工作流的定制。集成这两个工具可以创建一个功能强大的工具。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者