深入講解 Lotus Notes 外掛程式設計

genusBIT發表於2009-09-02

 

作者:李 偉, 軟體工程師, IBM

原文連結:http://www.ibm.com/developerworks/cn/lotus/notes-plugindev/index.html?ca=drs-cn-0831#main

簡介

眾所周知,Lotus Notes V8 以後的各個版本都是基於強大的託管客戶機軟體平臺 Lotus Expeditor 開發而成的,而 Lotus Expeditor 擴充套件了 Eclipse,是基於外掛的架構,這也使得 Lotus Notes 具有良好的可擴充套件性。Lotus Notes 發展到今天已經成為一個非常強大的整合了 Web 2.0 功能特性的協作辦公軟體。

本文通過幾個 Lotus Notes 外掛的開發介紹,深入淺出的講解如何基於 Lotus Notes 平臺,開發最常用的 Notes 外掛。從而增強 Lotus Notes 的協作能力,滿足使用者在工作中的實際需要。



Sender Analystics 外掛開發

專案簡介

該外掛通過 Email 地址來分析發信人的資訊。當使用者收到一個陌生人的來信,準備進一步瞭解該發信人的資訊時,這個外掛特別有用。

擴充套件實現

如清單 1 所示,Sender Analystics 外掛擴充套件了 Eclipse 平臺的 org.eclipse.ui.popupMenus 擴充套件點。請注意 objectClass 的值是 com.ibm.rcp.realtime.livenames.LiveNameSelection,當您在 Lotus Notes 中選擇一封 Email 或者一個物件中包含了 Sametime 的 Live Name 資訊,其檢視彈出選單中將顯示該擴充套件的選單項。


清單 1. Plugin.xml
				 
 
 
 
     
         
         
         
     
     
 

當 ObjectClass 是 LiveNameSelection 物件的時候,在 Action 的 run 方法裡面,我們能夠拿到 com.ibm.rcp.realtime.livenames.LiveName 物件資訊。在 Sametime Javadoc 文件中,我們知道 LiveName 有以下一些方法,可以獲取發信人的相關資訊。如表 1 所示,詳情請下載 Lotus Sametime SDK 並參考有關文件。

java.lang.String getCommunityId()
Returns the ID of the community that this person belongs to.
java.lang.String getContactId()
Returns the person's contact ID.
java.lang.String getDisplayName()
Returns the person's display name.
java.lang.String getId()
Returns the person's unique ID.
java.lang.String getName()
Returns the persons username.
int getStatus()
Returns the person's status, one of the STATUS_xxx codes defined in this interface.
org.eclipse.swt.graphics.Image getStatusImage()
Returns the image displayed for the person's status.
java.lang.String getStatusMessage()
Returns the person's status message.

在 Sender Analystic 外掛開發中,我們通過 LiveName 物件拿到了發信人的 Email 地址資訊。如清單 2 所示:


清單 2. Action 的 run 方法
				 
public void run(IAction action) {
    ObjectPluginAction bjAction = (ObjectPluginAction) action;
    if (objAction == null)return;
    if (objAction.getSelection() instanceof IStructuredSelection) {
        if (((IStructuredSelection) objAction.getSelection()) 
            .getFirstElement() instanceof LiveNameSelection) {
            LiveNameSelection sel = (LiveNameSelection) ((IStructuredSelection) objAction
                .getSelection()).getFirstElement();
            LiveName name = sel.getLiveName();
            String contactId = name.getContactId(); 
            String url = SenderAnalyzerHelper.createURL(contactId);
            SenderAnalyzerHelper.launchURLasEmbed(url);
        }
    }
}

接下來,程式呼叫 SenderAnalyzerHelper 輔助類的 launchURLasEmbed 方法,並根據生成的 URL(本外掛應用發信人的 Email 資訊構造一個 myfreeemailsearch 網站的 URL 請求)啟動 Lotus Notes 嵌入的瀏覽器開啟 Email 查詢頁面。如清單 3 所示,關於該方法的實現邏輯,請參考 Lotus Expeditor 有關文件。


清單 3. launchURLasEmbed 方法
				 
public static boolean launchURLasEmbed(String url){ 	
    final String secondaryId = BROWSER_VIEW_ID + Integer.toString(++counter); 
    Map configMap = new HashMap(); 
    configMap.put(BrowserPreference.ID, secondaryId); 
    configMap.put(BrowserPreference.ENABLE_APPLET, "true"); 
    BrowserLauncher bLauncher = BrowserLauncher.getLauncher(); 	
    return bLauncher.launchURLasEmbedded(url,null, configMap); 
} 

因為 Sender Analystics 需要啟動 Lotus 內部的瀏覽器,所以我們需要在 plugin.xml 加入如下的依賴外掛。如圖 1 所示:


圖 1. 在 plugin.xml 中加入依賴外掛
圖 1. 在 plugin.xml 中加入依賴外掛

圖 2 顯示了 Sender Analystics 外掛的執行效果。


圖 2. Sender Analystics 外掛的執行效果
圖 2. Sender Analystics 外掛的執行效果

通過本外掛的相關介紹,讀者可以開發基於 Sametime 的 Notes 外掛。

Driving Direction 外掛開發

專案簡介

本外掛的主要目地是管理使用者的旅行路線,啟用 Google Maps 來顯示旅行路線資訊。

擴充套件實現

如圖 3 所示,Driving Direction 外掛擴充套件瞭如下的擴充套件點。讀者可能對 org.eclipse.ui.views 並不陌生,外掛擴充套件了 Lotus Expeditor 所提供的 com.ibm.rcp.ui.shelfViews 擴充套件點。該擴充套件點使得 view 能夠和 Lotus Notes 的 Sametime 外掛,Activity 外掛一樣顯示在 shelfViews 區域,如圖 4 所示。


圖 3. Extension
圖 3. Extension

圖 4. shelfView
圖 4. shelfView

對該擴充套件點的描述如下:(更多的資訊,請參考 Lotus® Expeditor 資訊中心的文件)。

id id 屬性唯一標識該 shelf 檢視,也就是說,如果該 id 被使用了多次,只會有一個檢視被成功地註冊。
view View 屬性的值和所貢獻檢視的 id 是一致的(本外掛中是 traffic view 的 id)
region region 屬性是一種可選的方式用以描述檢視顯示在 sidebar 中的那個區域。其有三種可能的值 “TOP” ,“MIDDLE” 和“BOTTOM”。如果許多檢視的該選項值相同的話,檢視顯示的順序和其被載入的順序是一致的。預設值是“BOTTOM”
page page 屬性描述該檢視屬於那個 sidebar, 對於 Lotus® Expeditor 而言,該值是"RIGHT"
showTitle showTitle 屬性是 bool 型別,其值決定是否顯示標題欄

在圖 4 所示的 Driving Direction 外掛中,點選 Open 按鈕會開啟 Lotus Notes 的 preference 頁面(如圖 5 所示),這個功能會被經常用到,請見清單 4。preference 頁面主要是用來管理外掛的一些配置選項資訊。在本例中,用其管理旅行路線資訊。


清單 4. 開啟 Notes 的 preference 頁面
				 
openBt.addSelectionListener(new SelectionAdapter() { 	        
    public void widgetSelected(SelectionEvent e) { 
        PreferenceDialog dlg = PreferencesUtil 
            .createPreferenceDialogOn( 
                TrafficView.this.getSite().getWorkbenchWindow().getShell(), 
                    "com.ibm.lotus.openntf.traffic.ui.trafficanalyzer", //$NON-NLS-1$ 
                    null, null); 
                int success = dlg.open(); 
                if(success == 0) refreshRoutes(); 
            } 
    }); 

清單 4 中,com.ibm.lotus.openntf.traffic.ui.trafficanalyzer 是您定義的 preference page 的 id 屬性值。


圖 5. Traffic Routes Preferences
圖 5. Traffic Routes Preferences

通過本外掛的介紹,讀者就可以輕鬆的開發一個可以放在 shelfView 裡面顯示的 Eclipse 檢視外掛。


Date Recognizer 外掛開發

專案簡介

Date Recognizer 外掛用來識別 Notes 文件裡面的日期,並根據識別出來的日期觸發動作顯示當前的 Calendar 資訊。

擴充套件實現

和本文第一個外掛類似,Date Recognizer 擴充套件了 org.eclipse.ui.popupMenus 擴充套件點,不同的是,ObjectClass 的屬性值是 org.eclipse.jface.text.ITextSelection (當我們在 Notes 文件中,選中一段文字才能啟用外掛的 action)如清單 5 所示。


清單 5. Plugin.xml
				 

     
        
         
     
 

Date Recognizer 外掛中如何識別日期是一個非常重要的演算法問題。通常我們都用正規表示式。但時間格式的複雜性,使得難以有一個完整的正規表示式處理所有可能的情況。在清單 6 中給出了本外掛的演算法,它結合正規表示式能夠識別出 Notes 中常用的諸如:MM/DD/YYYY,March/Mar. Day, Year, 和 Year ? Month? Day 等日期格式。(其中‘?’是某一給定特殊的分隔符,比如 . / _- 等)如果字串中沒有合法的日期,本例中,將建立一個 Date 物件作為預設值。


清單 6. 解析演算法
				 
private boolean parse() { 
    // if destStr is empty, return false; 
    if (checkNull(destStr)) return false; 
    // append a space to destStr, it deals with situation like MM/DD/YYYY format, 
    // which lies at the end of destStr 
    StringBuffer sb = new StringBuffer(); 
    sb.append(destStr+" "); 	
    destStr = sb.toString(); 
    Pattern p = Pattern.compile(YEAR); 
    Matcher m = p.matcher(destStr); 
    // We just care about the first legal date and neglect other dates. 
    while (m.find()) { 
        // probably, year of Calendar exists 
        String lYear = m.group(); // for example 2008- 
        // two directions to analyze the string 
        int index = m.start(); 
        // Algorithm-forward: Obtain Month & Day information before the located year. 
        String previousP1 = destStr.substring(0, index + 4); // neglect yy format 
        // Match such format as January 01, 2009 
        Pattern pp1 = Pattern.compile(MonthDayYear); 
        previousP1 = previousP1.replaceAll("\\s", ""); // remove spaces 
        Matcher mp1 = pp1.matcher(previousP1); 
        if (mp1.find()) { 
            String destP1 = mp1.group(); 
            getDayAndMonth(destP1); 
            if (month != null && day != null) { 
                // remove the duplicated character 
                year = lYear.substring(0,lYear.length()-1); 
                createPrev1Date(); 
                return true; 
            } 
        } 
        //Match such format as MM/DD/YYYY 
        Pattern pp2 = Pattern.compile(MMDDYEAR); 
        Matcher mp2 = pp2.matcher(previousP1); 
        if (mp2.find()) { 
            createPrev2Date(mp2.group()); 
            return true; 
        } 
        // Algorithm: Obtain Month & Day information after the located year 
        // if Month & Day information is not in the same line as Year info, ignore it. 
        String afterText = destStr.substring(index + 4); 
        String[] dateText = afterText.split("\n|\t"); 
        String wantedText = afterText; 
        for (int i = 0; i < dateText.length; i++) { 
            if (!dateText[i].equals("")) { 
                wantedText = dateText[i]; 
                break; 
            } 
        } 
        afterText = wantedText.replaceAll("\\s", ""); // replace space 
        Pattern ap = Pattern.compile(MONTH); 
        Matcher map = ap.matcher(afterText); 
        int count = 0; 
        String tmpMonth = null; 
        String tmpDay = null; 
        if(checkNull(afterText)){ break; } 
        // separator of calendar must be consistent. 
        // can't support format like this 2008-09/02 
        char specialChar = afterText.charAt(0); // _ . / * - 
        while (map.find()) { 
            try { 
                if (count == 2) break; 
                if (count == 0) { 
                    tmpMonth = map.group(0); 
                } else if (count == 1) { 
                    String tmpday = map.group(0); 
                    int indexD = map.start(); 
                    if (afterText.charAt(indexD - 1) == specialChar) { 
                        tmpDay = tmpday; 
                    } 
                } 
                count++; 
            } catch (Exception e) {} 
        } 
        if (tmpMonth != null && tmpDay != null) { 
            year = lYear.substring(0,lYear.length()-1); 
            month = tmpMonth; 
            day = tmpDay; 
            createPrev1Date(); 
            return true; 
        } 
    } 
    return false; 
} 

圖 6 顯示瞭如何啟用 Date Recognizer 外掛。 圖 7 給出了 Calendar 資訊。日期被識別出來並賦值給了 Calendar 元件。


圖 6. 啟動外掛
圖 6. 啟動外掛

圖 7. Date Recognizer
圖 7. Date Recognizer

通過 Date Recognizer 外掛的學習,開發者可以輕鬆的向 Notes 文件的右鍵選單中貢獻外掛。

不僅如此,Eclipse 的諸多擴充套件點都可以在 Lotus Notes 中擴充套件應用。Lotus Expeditor 提供的 Launcher,Search Bar 等擴充套件點,請參考 Lotus Notes 8 的擴充套件與程式設計 一文。





如何安裝 Lotus Notes 外掛

有兩種常見的方式用以安裝 Notes 外掛,一種就是我們常見的 update site 方式。在 Lotus Notes 中,預設條件下 , 這個功能是不被支援的。

我們需要在 C:\Lotus\notes\framework\rcp (C:\Lotus\notes 是我的 Notes 的安裝目錄,開發者請注意,如果在安裝目錄中有空格,比如 notes 的預設安裝目錄 C:\Program files\ 在 debug 環境下會導致類載入異常)目錄下面的 plugin_customization.ini 檔案內加入 com.ibm.notes.branding/enable.update.ui=true 一行語句,那麼當您重新啟動 Notes 的時候,Notes 就啟動 update site 的功能了。如圖 9 所示:


圖 8. 啟動 update site 功能
圖 8. 啟動 update site 功能

Notes 外掛安裝的另一種方式是 Lotus Notes 8.5.1 所提供的 widget 方式。最終外掛會被包裝成 widget 來安裝。和第一種方式相比較,這種方式的好處之一就是不用去修改配置檔案。然而這種安裝方式最大的好處就是靈活,非常容易共享。開發者開發一個 Notes 外掛並開發一個遠端的更新站點(也可以自己下載一個 Apache http server, 把本地的更新站點簡單的放到 C:\Program Files\Apache Software Foundation\Apache2.2\htdocs 目錄下面就成功了)然後通過 Notes widget 的嚮導逐步安裝你的外掛。如圖 10 所示:


圖 9. Start Configuring Widgets
圖 9. Start Configuring Widgets

圖 10. 從遠端站點載入外掛
圖 10. 從遠端站點載入外掛

最終在 Notes 的 My Widget 裡面生成類似於普通 widget 的外掛。如圖 11 所示:


圖 11. Widget 外掛
圖 11. Widget 外掛

開發者可以用 Email 方式分享此外掛,收信人只要在 Notes 裡進行簡單的拖拽就能成功的安裝此外掛。開發者也可以點選 Remove 按鈕解除安裝該外掛。不過不管安裝或解除安裝外掛,都需要重新啟動一次 Notes。





總結

本文通過對三個 Lotus Notes 外掛專案的介紹,以及對其所涉及的擴充套件點,實現過程中的重要演算法等的講解會幫助開發者快速上手,開發 Lotus Notes 中最常見的外掛。並介紹了兩種常見的釋出方式,如果使用者安裝了 Lotus Notes 8.5.1 ,Widget 方式的外掛釋出極具誘惑。

希望讀者能夠從本文中獲益,快速的構建、釋出您自己的基於 Lotus Notes 的外掛專案。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14751907/viewspace-613811/,如需轉載,請註明出處,否則將追究法律責任。

相關文章