`
chanshui
  • 浏览: 82827 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

IBM 操作lotus notes

阅读更多
http://www.ibm.com/developerworks/cn/lotus/domino-wps/

2009 年 9 月 04 日

Lotus Notes/Domino 和 WebSphere Portal 是 IBM Lotus 家族中的两大产品。本文将向读者介绍一个 WebSphere Portal 与 Lotus Notes/Domino 集成的实例 - 如何创建一个迷你型的日历 Portlet。该 Portlet 能够从 Lotus Domino 中获取用户的会议数据并将其显示出来,其大小可以改变。用户还可以通过显示出来的会议记录访问其在 iNotes 上的具体内容。
实例场景

本文将向读者展示一个 WebSphere Portal 与 Lotus Notes/Domino 集成的实例 -- 创建迷你型日历 Portlet,主要有以下功能:

可变化大小。
能够从 Lotus Domino Server 获取用户的日历数据。
点击日历上某一日期,显示当日的会议邀请记录列表。用户点击列表上的任一条目可以在 iNotes 上打开该条目的详细情况。
读者至少需要拥有 Lotus Domino Server V7 以上 , WebSphere Portal V6 以上,并完成 Portlet 与 Domino Server 之间单点登陆的配置。

关于 Portlet 与 Domino Server 之间的单点登陆,在文章 IBM / Lotus Domino 与 WebSphere Portal: 单点登录 中作了具体的讲解。

如果实际客户环境使用 LDAP 服务器作为 Domino Directory,读者需要配置 Domino Server 和 IBM WebSphere Portal,使得 LDAP 上的用户能够登陆 IBM WebSphere Portal。

由于 WebSphere Portal 和 Lotus Domino 之间的单点登录是通过一种称为轻量级第三方认证 (LTPA) 的机制来实现的。因此,还需要配置 WebSphere Portal 和 Domino 之间的 LTPA 关系。这些在 WebSphere Portal Info center上都有详细的文档,读者可以参考这些材料完成配置。

下面将介绍该实例的原理图,如图 1 所示。部署在 WebSphere Portal 上的 Portlet,显示一个日历,并通过 DIIOP 去访问 Domino Server 得到选定的日期的会议邀请等数据,并在 Portlet 上显示出来。


图 1. 实例原理图






回页首




创建日历

可能大家都知道,用 JavaScript 创建一个日历,简单而快捷。由于在互联网上相关的实例和讲解众多,这里我只是简单的介绍一下日历实现的主要思想。

首先创建一个 7 × 7  的表格,第一行填充 [ 星期一,…,星期天 ],如图 2 所示。然后按照下面的规则填充表格单元。

得到该月 1 日是星期几(假如是第 X 列),然后从第 2 行第 X 列开始填充 [1,2,…,Y] (假如该月有 Y 天)。
填充第 2 行第 1 列到第 X-1 列。
填充剩下的表格单元。

图 2. 日历示意图


各个表格单元的属性可以通过样式文件来显示,例如周末用红色背景,今天用白色背景并加粗等等。






回页首




Portlet 与 Domino Server 之间的通讯

此实例一个重要的功能是能够获取 Domino Server 上的会议记录。在我们的实例当中,我们通过 DIIOP 访问 Domino。因此,我们必须确保所使用的 Domino Server 启动了 DIIOP 服务。具体方法是:打开 Domino 安装目录下的 notes.ini,将 DIIOP 到 ServerTasks 中,保存文件并重启 Domino Server。

下面介绍如何获取 Domino Server 上用户的会议邀请等。前文已经提到,我们的应用中,一个重要功能是对 SSO 的支持。用户登陆了 WebSphere Portal 之后,我们需要根据 WebSphere Portal 上的登陆信息找到用户在 Domino Server 上的信息(Mail Server 和 DIIOP 端口是用户单独配置的,具体见创建 Portlet 小节),最后获取 Domino Server 上该用户的会议邀请纪录,这里主要包含几个重要的步骤:

获取 LTPA cookie 信息。清单 1 中变量 sessionToken 存储的值是 LTPA cookie 信息,将作为方法 getItemByDateUsingLTPA ( 见清单 3) 的第二个参数来获取会议邀请纪录。
获取用户的 Notes 账号。清单 3 中开始部分根据 LTPA cookie 信息获取 Session notesSession,然后根据语句 notesSession.getUserName() 来获取用户的 Notes ID。
获取用户的邮件在服务器上存放位置。一旦获得用户 Notes ID (Domino Server 由用户自行配置),我们就可以通过清单 2 获取用户的邮件存放位置,返回的结果类似于 “mail/test.nsf”。
获取用户的会议邀请纪录。清单 3 演示了如何通过 LTPA 信息来获取用户会议邀请条目。其中, CalendarItem 存放的数据结构如清单 4 所示。

清单 1. 获取 LTPA cookie 信息
Cookie[] cookies = null;
String sessionToken = null;
cookies = renderRequest.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++){
if (cookies[i].getName().equals("LtpaToken")){
sessionToken = cookies[i].getValue();
break;
}
}
}



清单 2. 获取用户邮件存放位置
public static String getMailFile(Session notesSession,
String nameServer, String username) throws NotesException {
String mailFile = null;
Database nameDB = notesSession.getDatabase(nameServer, "names.nsf");
if(nameDB != null) {
String searchCondition = "Owner = \""+
username+"\" & Type= \"Person\"";
DocumentCollection dc = nameDB.search(searchCondition);
if(dc != null) {
Document doc = dc.getFirstDocument();
if(doc != null) {
Vector<Object> mailfiles = doc.getItemValue("MailFile");
if(mailfiles!=null && mailfiles.size()>0)
mailFile = (String)mailfiles.get(0);
}
nameDB.recycle();
if(mailFile != null) {
if(!mailFile.contains(".nsf"))
mailFile += ".nsf";
mailFile = mailFile.replaceAll("\\\\", "/");
}
}
}
return mailFile;
}



清单 3. 获取用户会议邀请条目
/**
* Retrieve the specific calendar items list
* @param mailServer: mail server and DIIOP port,
*    e.g. dominodemo.company.com:63148
* @param ltpaToken: LTPA token
* @param startDate: start date, e.g. "03/23/2009"
* @param endDate: end date, e.g. "03/23/2009"
* @return calendar items list.
*
*/   
public static List<CalendarItem> getItemByDateUsingLTPA(String mailServer,
String ltpaToken, String startDate, String endDate) {
    ArrayList<CalendarItem> list = new ArrayList<CalendarItem>();
    Database mailDB = null;
    Session notesSession = null;
    try {
        notesSession = NotesFactory.createSession(mailServer, ltpaToken);
        String []tmpArray = mailServer.split(":");
        String directory = getMailFile(notesSession,tmpArray[0],
notesSession.getUserName());

        mailDB = notesSession.getDatabase(tmpArray[0], directory);
        String searchCondition = "@IsAvailable(" +
NotesCalendarFields.calendarDateTime +
") & @IsMember(\"" + startDate
+ "\";@Explode(StartDateTime; \",\"))";
        DocumentCollection dc = mailDB.search(searchCondition);
        Document doc = dc.getFirstDocument();
        long startDateTime = format.parse(startDate).getTime();
        long endDateTime = format.parse(endDate).getTime();
        while(doc != null) {
            Vector<Object> vec =
doc.getItemValue(NotesCalendarFields.calendarDateTime);
            for( int i = 0; vec != null && i < vec.size(); i ++) {
                Date date = ((DateTime)vec.get(i)).toJavaDate();
                long elem = date.getTime();
                if(elem >= endDateTime)
                    break;
                else if(elem >=  startDateTime) {
                    CalendarItem calItem = new CalendarItem();
                    if((vec = doc.getItemValue(NotesCalendarFields.subject))
.size() > 0)
                            calItem.setSubject(vec.get(0).toString());
                    calItem.setStartDate(date);
                    vec = doc.getItemValue(NotesCalendarFields.endDateTime);
                    calItem.setEndDate(((DateTime)vec.get(i)).toJavaDate());
                       
                    if((vec = doc.getItemValue(NotesCalendarFields.description))
.size() > 0)
                            calItem.setDescription((String)vec.get(0));
                    if((vec = doc.getItemValue(NotesCalendarFields.calType))
.size() > 0)
                            calItem.setCalType(Integer.parseInt(vec.get(0)
        .toString()));
                    URL url = new URL(doc.getHttpURL());
//For SSO reason, we need to replace it's host
                    String strURL = url.toString().replaceAll(url.getHost(),
tmpArray[0]);
                    calItem.setHttpURL(strURL);
                    list.add(calItem);
                }
            }
            Document temp = dc.getNextDocument();
            doc.recycle();  // recycle the one we're done with
            doc = temp;
        }           
    }
    catch(Exception e) {
        e.printStackTrace();
    }
    finally {
        try {
            if(mailDB != null)
                mailDB.recycle();
            if(notesSession != null)
                notesSession.recycle();
        }
        catch (NotesException e) {
            e.printStackTrace();
        }
    }
   
    return list;
}



清单 4. CalendarItem 数据结构
public class  CalendarItem {
    private Date startDate;
    private Date endDate;
    private String subject;
    private String description;
    private String httpURL;
    /**
    0 - Appointment
    1 - Anniversary
    2 - All Day Event
    3 - Meeting
    4 - Reminder
     */
    private int calType;
    public CalendarItem() {
        subject = "";
        description = "";
        calType = 0;
    }
   
    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public Date getEndDate() {
        return endDate;
    }
    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public int getCalType() {
        return calType;
    }
    public void setCalType(int calType) {
        this.calType = calType;
    }

    public String getHttpURL() {
        return httpURL;
    }

    public void setHttpURL(String httpURL) {
        this.httpURL = httpURL;
    }
}







回页首




创建 Portlet

完成上述几个步骤之后,接下来我们需要创建一个 Portlet 来显示日历,当用户点击某一日期时,Portlet 能够调用清单 2 和 3 中的代码来获取用户的日历邀请条目并显示出来。能够创建 Portlet 的工具很多,IBM 也不缺乏这样的工具,例如 Rational Application Developer(简称 RAD)。用 RAD V7 创建 Portlet 十分简单,如图 3 和图 4 所示,创建一个名为 PortletExmple 的 Portlet,选择查看和编辑两个视图。

在文件 PortletExamplePortletEdit.jsp 中添加 2 个编辑框,让用户输入:Domino Server,DIIOP 端口(默认为 63148)。另添加一个 button 按钮,能够让用户保存数据。如清单 4 所示。

在 PortletExamplePortlet.java 中定义变量如下:

public static final String mailServer = "dominoCalendarmailServer";
public static final String portnumber = "dominoCalendarportnumber";
public static final String saveAction = "saveaction";



在方法 processAction 中实现处理 Portlet 编辑视图中的按钮事件。代码如清单 5 所示。

接下来我们来介绍如何实现 Portlet 查看视图。在文件 PortletExamplePortletView.jsp 中,其主要功能是生成一个带有日历以及选定日期的页面。我们用 preferences.getValue(String, “”) 获取 Domino Server 以及其端口值,然后调用清单 2 方法 getItemByDateUsingLTPA 可以获取会议邀请信息列表,每条记录包含开始时间、结束时间、描述、主题以及 iNotes 上该条目的 HTTP 链接,效果图如图 5 所示。


图 3. 创建 Portlet 示意图 1


图 4. 创建 Portlet 示意图 2


清单 5. Portlet 编辑视图代码
<%@ page session="false" contentType="text/html; charset=gb2312"
import="java.util.*,javax.portlet.*, com.company.*"%>
<%@taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<portlet:defineObjects/>

<%
PortletPreferences prefs = renderRequest.getPreferences();
if (prefs != null) {
    String mailServerValue =
    prefs.getValue(PortletExamplePortlet. mailServer, "");
    String portValue = prefs.getValue(PortletExamplePortlet.portnumber, "");
%>

<FORM ACTION="<portlet:actionURL/>"METHOD="POST">
Mail Server:<INPUT NAME="<%=PortletExamplePortlet. mailServer %>"
VALUE="<%= mailServerValue %>" TYPE="text"><BR>
Port:<INPUT NAME="<%=PortletExamplePortlet. portnumber %>"
    VALUE="<%= portValue %>"TYPE="text"><BR>
<input type="submit" value="Save"
name="<%= PortletExamplePortlet.saveAction %>" /> 
<%
}
%>
<input type="submit" value="Cancel"
onclick="javascript:location.href='<portlet:renderURL portletMode="view"/>';"
/>
</FORM>
<%
    } else {
%>
Error: PortletPreferences is null.
<%
    }
%>



清单 6. Portlet 编辑视图事件处理函数
public void processAction(ActionRequest request, ActionResponse response)
    throws PortletException, java.io.IOException {
    PortletPreferences prefs = request.getPreferences();
    try {
        if(request.getPortletMode() ==  PortletMode.EDIT ) {
            if(request.getParameter(saveAction)!=null)  {
                prefs.setValue(mailServer,request.getParameter(mailServer));
                prefs.setValue(portnumber,request.getParameter(portnumber));
                prefs.store();
            }
            response.setPortletMode(PortletMode.VIEW);
            response.setWindowState(WindowState.NORMAL);
         }
    }
    catch( ReadOnlyException roe ) {
    }
    catch( ValidatorException ve ) {
    }
}



图 5. Portlet 运行效果图






回页首




结论

通过对上述实例的介绍,读者应该对如何实现 Lotus Notes/Domino 与 WebSphere Portal 的集成有一个大概地了解。读者可以结合 Lotus Notes/Domino 和 WebSphere Portal 的优点,开发出一些集成程序,更好的发挥它们的作用和价值,这也是本文的主要目的。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics