用自定義 Java 程式碼擴充套件 IBM Workplace Designer 的功能

genusBIT發表於2008-09-11

IBM Workplace Designer 是具有內嵌指令碼的功能齊全的、基於標準的視覺化開發工具,可以使應用程式開發人員、設計人員和其他使用者很容易地為 IBM Workplace Collaboration Services 或 IBM Workplace Services Express 建立和部署元件。

Workplace Designer 為 Workplace Collaboration Services 和 Workplace Services Express 提供了同樣簡單易用、功能強大的基於表單的開發,Domino 開發人員已經用 Lotus Domino Designer 享受這種好處很多年了。Domino ISV 很久以來就能夠使用 Lotus Domino Designer 容易地為 Domino 伺服器建立和部署元件。現在,Workplace Designer 已經發布了,因此這些開發人員可以容易地在 Workplace Collaboration Services 和 Workplace Services Express 應用程式中建立和部署元件,以滿足特定的行業和業務需求。

Workplace Designer 通過其內嵌 JavaScript. 引擎提供了強大的伺服器端指令碼功能。JavaScript. 程式碼可以與每個控制元件、表單或元件的事件相關聯。Workplace Designer 還提供了對實用程式 JavaScript. 類的內嵌本地庫(比如 DocAPI 和目錄服務,以及函式集合)的訪問。Workplace Collaboration Services API 還可通過自定義 JavaScript. 程式碼被直接訪問,從而開發人員可以構建與 Workplace Collaboration Services 伺服器整合的應用程式。

本文面向具有 Domino 開發、JavaScript. 或其他視覺化指令碼語言和 Java 背景的 Workplace Designer 元件開發人員、應用程式開發人員和 ISV。本文描述瞭如何擴充套件 Workplace Designer 的少量可程式設計性以包括外部(非 Workplace)Java 程式碼,其中包括 Lotus Domino 的 Java API。現有 Java 程式碼可以容易地合併到用 Workplace Designer 構建的應用程式中。本文提供瞭如何實現該操作的幾個樣例,以及在 Workplace 環境中進行開發、測試和部署的指南。

本文假設您具有 Web 應用程式開發,尤其是 JavaScript. 的一些經驗。略微熟悉 Workplace Collaboration Services 或 Workplace Services Express 伺服器也有幫助。

高階開發人員和 ISV 程式設計人員通常使用各種 Domino 工具包將其程式碼與 Lotus Notes 和 Domino 整合起來。一些人可能在 Java 技術上投資很大,而且可能已經構建了產品,而現在他們希望將這些產品與 Workplace Collaboration Services 和 Workplace Services Express 應用程式整合起來。Workplace Software Development Kit(原來叫做 Workplace Collaboration Services API Toolkit)允許 ISV 構建協作應用程式以與 Workplace Collaboration Services 伺服器一起使用。

不太出名的是 Workplace Designer 的可擴充套件性及其從 Workplace Designer 元件中呼叫 “外來” Jar 檔案中非 IBM Java 類 API 的能力;但這也是可能的,使得 ISV 能夠在使用 Workplace Designer 開發的新 Workplace 應用程式中重用以前開發的 Java 功能。在本文中,我們將討論 Workplace Designer 中一些可用的可程式設計性特性,並解釋可以如何保留和有效利用已經在 Java 類中所做的投資。

Workplace Designer 可程式設計性特性和功能

對開發工具的衡量是看它的事件處理能力。在 Workplace Designer 中,每個設計元素可以將 JavaScript. 程式碼與當元素在 Workplace 伺服器上執行時可能發生在該元素上的事件相關聯。

Workplace Designer 支援許多級別的事件:

  • UI 控制元件事件。每個 UI 控制元件都可以有一組客戶端事件。例如,按鈕元素可以響應 onClick 事件;編輯控制元件可以響應 onBlur 事件。關聯的 JavaScript. 程式碼可以指定為在伺服器端或客戶端執行。
  • 元件事件。這些是標準的 Workplace 伺服器事件;例如,當元件例項化時或為 Workplace 應用程式新增或移除元件時。這些事件是使用一組事件全域性屬性在元件級別定義和處理的。
  • 表單/文件事件。表單具有一組伺服器端事件,例如,可以響應 onPageLoad 事件。文件事件與表單事件一樣。

事件和 JavaScript

HTML 程式設計人員應該熟悉可與許多 Workplace Designer 控制元件一起使用的事件。一般來說,HTML 規範中描述的事件是與控制元件型別一起使用的。Workplace Designer 還提供了一組與表單設計元素一起使用的事件。對於其中每種事件型別,開發人員可以在密封的 SimpleAction(可以接受引數)的表單中或 JavaScript. 中關聯一些程式碼。除了提供與 JavaScript. 標準的高度相容性之外,JavaScript. 引擎還允許您使用 Java 程式碼並呼叫 Java 標準庫,這些標準庫可用於執行在伺服器上的 Java Virtual Machine (JVM) 中。

如前所述,Workplace Designer 內嵌了一個綜合的 JavaScript. 引擎,支援開發功能強大的應用程式。JavaScript. 程式碼可以設計成執行在伺服器或客戶機上。JavaScript. 引擎附帶的 JavaScript. Editor(參見圖 1)支援語法上色和內容幫助。

在編輯器 UI 的 Outline 和 Reference 皮膚中,可以訪問本地物件,從而訪問實用程式程式碼庫。還可以建立自己的可重用指令碼程式碼庫。JavaScript. 引擎具有允許直接呼叫任何 Java 程式碼(包括 JVM 中的 Java API)的 Java 橋。

使用 Workplace Designer 中包括的 JavaScript. 包裝器物件,可以實現與 Workplace 業務元件更高階的整合。這些物件提供了到達完全 Workplace Collaboration Services API Java 類的 “前門”,允許構建從 Workplace Designer 的 JavaScript. 編輯器皮膚直接與 API 進行互動的元件。因此,可以讓您的 Workplace Designer 元件生成電子郵件、建立日曆條目並與 Workplace Collaboration Services 的各種業務元件進行互動。

在 JavaScript. Editor 中,不僅可以輸入普通的 JavaScript. 程式碼,還可以使用一組特殊的全域性物件 JavaScript. 類(可由 Workplace Designer 使用)。

這些類(如圖 1 中的 Reference 皮膚所示)用 Java 程式碼實現,可以通過內嵌的 Java 橋進行訪問。圖 1 所示的程式碼片段使用了 Workplace Designer 的文件類和 XSPUrl 類,XSPUrl 類實現 Workplace Designer URL 的功能。


圖 1. JavaScript. Editor
.. Editor

該 Java 橋允許您無需知道它們的任何實現而使用這些類。這正是我們將探討的 Java 橋,可以呼叫我們自己的 “外來” API。在這裡,外來的含義是非 Workplace 和非 JVM。

圖 1 所示的程式碼片段使用 Workplace Designer 的文件和一個 XSPUrl 類,該類實現 Workplace Designer URL 的功能。程式碼展示了新建一個文件,然後在瀏覽器中開啟。

在 JavaScript. 中嵌入 Java 程式碼

有時候,可能希望使用一組外部類檔案的可用功能。Workplace Designer 中的 JavaScript. 引擎允許無縫地呼叫 Java 程式碼,不管是在標準程式碼還是私有程式碼中。例如,使用 java.util 包中的 Date 類:

var startDate = new java.util.Date(2005, 10, 24, 15, 0); 
// create a Java Date object for 3 PM, October 24 2005
var endDate = new java.util.Date(2005, 10, 24, 16, 0);   
// create a Java Date object for 4 PM, October 24 2005

long elapsed_time = endDate.getTime() - startDate.getTime(); 
// compute elapsed time in milliseconds
println("One hour is " + elapsed_time + " milliseconds");

這是可行的,因為執行時 JVM 提供了這些標準 Java 類。

如果要使用的類不在標準 JVM 集合中怎麼辦?通過將類(最好是打包成 JAR 檔案)放在 Workplace 伺服器上並配置伺服器來識別類,就可以使用這些外來類了。舉一個簡單的例子。

假設您有一個用 Java 編寫的自定義 Converter 類,希望將其用於一個用 Workplace Designer 構建的元件中,但不希望將 Converter 程式碼中的所有例程放到 JavaScript. 中。該 Converter 類暴露許多方法,這些方法提供不同計量單位之間的轉換功能。我們專門看兩個方法 —— 攝氏和華氏之間的轉換,如下列程式碼樣例所示:

package com.ibm.workplace.converter;

public class Converter
{
   private final double K_far = 1.8;           
   // ((212-32) / 100) = 9 / 5 = 1.80   ;
   private final double K_cel = 0.55555555556; 
   // (100 / (212-32)) = 5 / 9 = 0.555..;

   public Converter()
   {
      super();
   }

   public String getClassVersion()
   {
      return this.getClass().getName() + " Version 1 (01/21/2006 10:00 AM)";
   }
 
   /*
    * temperature conversion - Celsius to Fahrenheit
    */
   public double toFahrenheit(double c)
   {
      return (c * K_far) + 32;
   }
    
   /*
    * temperature conversion - Fahrenheit to Celsius
    */
   public double toCelsius(double f)
   {
      return (f - 32) * K_cel;
   }
}

要在 Workplace Designer 元件中使用該類的方法,則為所選設計元素的相關事件編寫 JavaScript. 程式碼。為了簡便,我們將該程式碼放在按鈕的 onClick 事件上,並只將結果輸出到伺服器日誌檔案中。在可下載的樣例中,顯示在螢幕上的輸出如圖 2 所示。


圖 2. 轉換器樣例演示
轉換器樣例演示

下例呼叫一個簡單的 Java 類來執行溫度轉換(攝氏/華氏)。

var myPackage = com.ibm.workplace.converter; 
// access the Java package

var conv = new myPackage.Converter(); 
// instantiate a Java Converter object

var f1 = 50;
var c1 = conv.toCelsius(f1); 
// get Celsius value for 50 Fahrenheit
println(f1 + " degrees F is " + c1 + " degrees C.");

var c2 = 10;
var f2 = conv.toFahrenheit(c2); 
// get Fahrenheit value for 10 Celsius
println(c2 + " degrees C is " + f2 + " degrees F.");

執行時,下列輸出顯示在 Workplace SystemOut.log 檔案中:

[01/21/06 12:38:03:447 EDT] 4e718de7 SystemOut O 50 degrees F is 10 degrees C.
[01/21/06 12:38:03:447 EDT] 4e718de7 SystemOut O 10 degrees C is 50 degrees F.

該程式碼還被構建成一個簡單的 Workplace Designer 元件,可以從本文下載得到。

當將元件部署到 Workplace 伺服器上並插入到頁面中時,可以看到圖 2。當在 Workplace Designer 中開啟時,專案顯示要部署到 Workplace 伺服器上的表單元素(參見圖 3)。


圖 3. Workplace Designer 中的 formConverter
Workplace Designer 中的 formConverter

元件接受一個表示溫度的輸入值(/rootConverter/temperature),並根據單擊的操作按鈕,將該值轉換為相應的攝氏或華氏等同溫度。例如,當單擊 “Convert from Fahrenheit to Celsius” 按鈕時,則在該按鈕的 onClick 事件中執行下列程式碼:

var myPackage = com.ibm.workplace.converter; 
// access the Java package
var conv = new myPackage.Converter(); 
// instantiate a Java Converter object

// retrieve the user input field from the form.
var tIn:float = document.getDoubleValue("/rootConverter/temperature");
print( "tIn = "+tIn );

// call out to the Java method on the Converter object
var tOut = conv.toCelsius(tIn);

print( "tOut = "+tOut );

var result = ""+tIn+" F = "+tOut+" C";
print( result );

// display result in form.
document.setStringValue("/rootConverter/result", result);

它將結果顯示在表單 (/rootConverter/result) 的結果欄位中。這些欄位在表單的模式中描述(參見圖 4)。


圖 4. Workplace Designer 中的 schemaConverter
Workplace Designer 中的 schemaConverter

注意: /rootConverter/temperature 和 /rootConverter/temperature 是用於訪問表單上這些欄位的 XPath 表示式。該程式碼(JavaScript. 和 Java)在 Workplace 伺服器上執行以響應按鈕單擊。

Workplace Designer JavaScript. 引擎已經實現了允許變數型別轉換的擴充套件,例如 var tIn:float。

可以用相同的方式呼叫 Workplace API。Workplace API JAR 檔案是安裝 Workplace 伺服器時附帶的。我們只需要在 Workplace Designer 元件中編寫 JavaScript. 程式碼,以與 Workplace 業務元件互動。Workplace API 的主要服務直接暴露在 Workplace Designer JavaScript. 環境中,其方式與前面提到的其他全域性物件完全一樣。例如,圖 5 展示了一些樣例 JavaScript. 程式碼,演示了 Workplace Calendar API 的使用。


圖. scriptLibraryMailCalendar
.LibraryMailCalendar

對在應用程式中使用 Workplace API 類的介紹超出了本文範圍。可以從 developerWorks Workplace Sample 頁面 下載展示其用法的例子。此外,參見紅皮書 “IBM Workplace 2.5 Development with Workplace Designer” 以獲得有關如何使用 Workplace API 類的其他資訊。

開發過程、技術和指南

使自己的外來程式碼可用於基於 Workplace Designer 的應用程式是一個十分簡單的過程。那麼如何來實現呢?首先,將您的 Java 程式碼放入 JAR 檔案中。有許多方法可以做到這一點;可以使用批構建過程來構建所有類檔案並將其組合到一個 JAR 檔案中,命令如下:

jar -cfv com

其中 是目標 JAR 檔案的完全限定檔名(例如 sample.jar),com 是包含類檔案的軟體包樹根(例如 \mycode\built\classes\com...)。

側欄檔案 “如何使用 Eclipse 為 Converter 程式碼生成一個 JAR 檔案” 展示瞭如何從 Eclipse 專案生成 JAR 檔案。

假設現在 JAR 檔案中具有希望用於 Workplace Designer 元件中的程式碼。將該 JAR 檔案安裝在 Workplace 伺服器上,然後配置伺服器以啟用 JAR 檔案。

啟用 Workplace 伺服器上的外來 JAR 檔案以用於 Workplace Designer 元件中

安裝自定義 JAR 檔案需要伺服器管理特權和對伺服器磁碟驅動器的訪問權,所以伺服器管理員可能必須執行下列管理任務。

編寫 Java 類檔案並將其組合到 JAR 檔案中之後,通過下列方式將自定義 JAR 檔案安裝在伺服器上:

  1. 將 JAR 檔案複製到 Workplace 伺服器的 \WorkplaceServer\lwp_lib 目錄上,其中 是包含 Workplace 伺服器已安裝檔案(例如 C:\WebSphere)的 IBM WebSphere Application Server 程式目錄。如果無法訪問 WebSphere Application Server 檔案系統,請讓伺服器管理員幫您複製 JAR 檔案。

    注意: IBM i5/OS 使用者應將 JAR 檔案複製到 /qibm/userdata/WebAS5/Base//WorkplaceServer/lwp_lib。

  2. 瀏覽至伺服器上的 IBM WebSphere Administrative Console,http://machineName.subDomain.domain:port/admin(例如 http://mymachine.ibm.com:9091/admin)。在登入螢幕上,以具有管理員特權的使用者身份登入。
  3. 在左皮膚中選擇 Environment Shared Libraries。
  4. 在共享庫列表中選擇 LotusWorkplaceLib。
  5. 在 Configuration 螢幕上,CLASSPATH 欄位列出位於自定義 JAR 檔案複製到的相同目錄中的所有共享庫。新增步驟 1 中複製的自定義 JAR 檔案。( 在步驟 1 中定義)。進行該操作最簡單的方法是複製和貼上其他一個條目,然後編輯 JAR 檔名稱,例如 \WorkplaceServer/lwp_lib/mycustom_file.jar。
  6. 確保所有條目都正確,完成後單擊 OK。
  7. 單擊 Shared Libraries 螢幕頂部的 Save。
  8. 單擊 Save to Master Configuration 螢幕上的 Save。
  9. 將自定義 JAR 檔案安裝在伺服器上後,重啟伺服器,以便 JVM 載入該 JAR 檔案。

現在可以建立並部署使用外部自定義 Java 程式碼的 Workplace Designer 元件了。

除錯和測試

如果每件事並不是您第一次嘗試,那麼可以除錯您的作品以確定問題在哪裡。這可能是枯燥無味的,因為一旦將 JAR 檔案安裝在 Workplace 伺服器上並由 JVM 載入,如果要更改或更新該檔案,則必須停止伺服器,替換 JAR 檔案,然後重啟伺服器。這可能要花一些時間,所以您不希望經常這樣做。

可以採用一些除錯技術來讓每次迭代更有效。側欄檔案 “如何使用日誌記錄來幫助您除錯程式碼” 展示瞭如何在 Java 程式碼中啟用日誌記錄。日誌記錄的輸出被髮送到位於 \Websphere\PortalServer\logs\trace.log 的系統跟蹤日誌檔案中。

為此,在 WebSphere Application Server Administrative 控制檯中啟用此軟體包的日誌記錄。側欄檔案 “如何在 WebSphere Application Server 中啟用日誌記錄” 展示瞭如何來實現。

此實用工具允許在開發程式碼時開啟日誌記錄,然後在準備部署時關閉,從而靈活地控制日誌記錄的級別,而且不需要更改任何程式碼。

還可以獨立於 Workplace Designer 或 Workplace 伺服器來測試您的 Java 類。可以只編寫普通的 Java 主例程來呼叫類的方法。從 Eclipse 除錯會更加容易。這種主例程的一個示例在側欄檔案 “獨立於 Workplace Designer 元件來測試您的類” 中展示。

如果您喜歡的話,可以使用 JUnit 測試。請參見側欄檔案 “用 JUnit 來測試您的類”。

呼叫 Domino Java 類以訪問 Domino 程式碼的示例

如果外來 API 正是 Domino Java API,則可以使用相同的策略。首先,將 Domino 伺服器中的 Domino JAR 檔案 (NCSO.jar) 複製到 Workplace 伺服器上的 Workplace 伺服器庫目錄中:

\WorkplaceServer\lwp_lib

NCSO.jar 檔案包括 Domino Java API 以及 ORB,允許您從 Workplace 伺服器與 Domino 伺服器進行遠端通訊。NCSO.jar 通常位於 Domino 伺服器的位置:

\Domino\data\domino\java\NCSO.jar

要使之工作,Domino 伺服器需要執行 DIIOP 伺服器任務(如果執行 Lotus Domino 5,還要執行 HTTP 任務)。

可以選擇將如何從 Workplace Designer 元件中使用 Domino 類。可以使用與上述相同的技術,在 Workplace Designer JavaScript. 程式碼中直接編寫自己的 Domino 訪問程式碼。例如:

var notesPackage = lotus.domino; 
// access the Java package
var session = null;

// retrieve the user input fields from the form.
var host = document.getStringValue("/rootConverter/host");
var userName = document.getStringValue("/rootConverter/userName");
var password = document.getStringValue("/rootConverter/password");

 // retrieve the Domino factory object
var notesFactory = notesPackage.NotesFactory;
var result = "";

try
{
   // use the Domino factory object to get a Domino session
   session = notesFactory.createSession(host, userName, password);
   if (session != null)
      result = "-- Got Session for "
                    + context.getUser().getCommonName() +".";
   else
      result = "-- Session is null.";
}
catch (ne)
{
   result = result + "-- " + ne.getMessage();
   result = result + "-- Failed to get session for "
                     + context.getUser().getCommonName() +".";
}

print("createSession result is : " + result);
var platform. = null;
if (session != null)
{
   // use the Domino session object to get the Domino server platform. name
   platform. = session.getPlatform();
   if (platform. != null)
   {
      result = "-- Got platform. (" + platform. + "} for " + context.getUser().getCommonName() +".";
      print("Platform. = " + platform);
   }
   else
      result = "-- platform. is null.";
}

print("Access Notes result is : " + result); // log result to SystemOut.log

// display result in form.
document.setStringValue("/rootConverter/diiopResult", result);

此外,如果已經具有與 Lotus Domino 通話的自定義 Java 庫,那麼惟一要做的就是將 JAR 檔案(和 NCSO.jar)安裝在 Workplace 伺服器上,並從 Workplace Designer 元件的 JavaScript. 程式碼中呼叫該檔案。這可能是比較乾淨的選項,因為這樣會將所有的 Domino 程式碼(可能十分龐大)保留在元件外部。JavaScript. 程式碼無需知道 Domino 類的任何內容,您根本不需要將任何 Domino 物件在元件和 Java 程式碼之間來回傳遞。您只需要在 Java 庫中維護 JavaScript. 程式碼和後端系統(用於儲存、文件管理或 Domino 暴露的其他任何設施)之間的隔離層。在該場景中可以替換 Lotus Domino,而 JavaScript. 元件無需更改。

var notesPackage = com.ibm.workplace.designernotes; 
// access the package

// retrieve the user input field from the form.
var host = document.getStringValue("/rootConverter/host");
var userName = document.getStringValue("/rootConverter/userName");
var password = document.getStringValue("/rootConverter/password");

 // instantiate an external Java object to access Domino classes
var myNotes = new notesPackage.NotesAccessor();

var result = "";

try
{
   // use the accessor object to initialize a session with Domino
   var success = myNotes.initNotes(host, userName, password);

   // retrieve the platform. information from the Domino server
   var platform. = myNotes.getNotesPlatform()
   if (platform. != null)
   {
      result = "-- Got platform. (" + platform. + "} for " + context.getUser().getCommonName() +".";
      print("Platform. = " + platform);
   }
   else
      result = "-- platform. is null.";
}
catch (ne)
{
   result = result + "-- " + ne.getMessage();
   result = result + "-- Failed to get platform. for "
         + context.getUser().getCommonName() +".";
}

print("Access Notes result is : " + result); // log result to SystemOut.log

// display result in form.
document.setStringValue("/rootConverter/diiopResult", result);

// tell the Domino session we are finished using it
myNotes.termNotes();

這兩個場景都在可下載樣例中有演示。

Domino 訪問程式碼封裝在 NotesAccessor 類中,在 Workplace Designer 元件 JavaScript. 程式碼和處理後端資料管理的程式碼之間提供了隔離層。在樣例中使用了 getPlatform. 方法,因為一旦已經與 Lotus Domino 成功建立了聯絡,並具有一個會話物件,就可以訪問 Domino Java API 中的全部類。

public class NotesAccessor
{
   private Session _dominoSession = null;

   public NotesAccessor()
   {
   }

   /*
    * Initialize the connection to the Domino server
    */
   public boolean initNotes(String host, String username, String password)
   {
      boolean k = false;
      try
      {
          _dominoSession
                = NotesFactory.createSession(host, username, password);
         k = true;
      }
      catch (NotesException e)
      {
         e.printStackTrace();
      }
      return ok;
   }

   /**
    * clean up any Domino objects
    */
   public void termNotes()
   {
      try
      {
          _dominoSession.recycle();
          _dominoSession = null;
      }
      catch (NotesException e)
      {
         e.printStackTrace();
      }
      return;
   }

   /**
    * @return the Notes session.
    */
   public Session getSession()
   {
      return _dominoSession;
   }

   /**
    * @return The name of the platform. the session is running on
    */
   public String getNotesPlatform()
   {
      String retVal = null;
      try
      {
          if (_dominoSession != null)
              retVal = _dominoSession.getPlatform();
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
      return retVal;
   }

在圖 6 中,我們展示了從 Domino 伺服器中檢索 OS 平臺字串的兩個方法,並將之顯示在 Workplace Designer 元件表單上。您可以用同樣的方式與其他任何產品的 Java API 進行互動。


圖 6. Domino 樣例演示
Domino 樣例演示 

結束語

Workplace Designer 工具針對任何有興趣開發 IBM Workplace 平臺應用程式的人。它為比較簡單的任務提供了 SimpleActions 和 JavaScript,併為需要更多馬力的任務提供了與基於 Java 的工具相整合的可擴充套件性。

要了解有關 IBM Workplace Designer 的更多資訊和下載樣例,請訪問以下參考資料。

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

相關文章