IBM Lotus Connections における Google ガジェットのデプロイとインプリメント

この記事では、IBM® が開発し、IBM Lotus® Connections 2.0 などさまざまな IBM 製品で使用されている iWidget 仕様について紹介します。実用的な例を取り上げ、この仕様の種々の側面を解説するとともに、Google ガジェットのラッパーとして機能する iWidget のインプリメント方法も示します。

Vincent Burckhardt, Software Engineer, IBM

Vincent Burckhardt is a Software Engineer at the IBM Dublin Software Laboratory. Vincent has been working as part of the IBM Lotus Connections development team since 2007. You can reach him at vincent.burckhardt@ie.ibm.com.



2008年 9月 09日

Lotus Connections 2.0 にはカスタマイズ性と拡張性の非常に高い新しいメイン・ページが含まれていて、分散されたさまざまなソースからの情報を集約したビューをユーザーに提供します。ウィジェットに基づくホーム・ページ機能を使用すると、Lotus Connections ソーシャル・ソフトウェア・プラットフォームを容易に拡張できます。

ホーム・ページには、独自のウィジェットをインプリメントおよび追加できます。iWidget は、IBM によって定義されたウィジェット用の新しい定義です。iWidget 仕様によって、このようなウィジェットの構造が定義されています。iWidget 標準は Lotus Connections 固有のものではなく、IBM Mashup Center の Lotus Mashups コンポーネントなどの他の製品でも使用されるため、一度ウィジェットを記述すると他の製品でも実行できます。

この記事では、基本的な iWidget を作成し、それをデプロイしてホーム・ページで実行する手順の概要を説明します。例として、iWidget 内に Google ガジェットをラップする方法を示します。この記事を読むと、他のコンテンツをユーザーに表示する基本的なウィジェットを作成できるようになるでしょう。

この記事の最初の 2 つのセクションでは、iWidget 仕様と Google ガジェットの両方に関し、必要となる理論的な知識を解説します。3 番目のセクションでは、基本的な Google ガジェット・ラッパーとして機能する iWidget のインプリメント手順をステップバイステップで示します。最後に、Google ガジェット・ラッパーを機能強化する方法を説明し、より詳しい内容に触れます。

基本的なウィジェットを作成およびデプロイするプロセスは比較的簡単です。この記事は、JavaScript™、Java™ Platform、Enterprise Edition、および XML など、最も一般的な Web 開発技術に習熟していることを前提に書かれています。JavaScript Dojo Toolkit の使い方など、あまり一般的でない領域の情報については必要に応じて説明しますので、中級程度の知識で十分です。

ホーム・ページ・ウィジェットと iWidget 仕様の概要

このセクションでは、IBM の iWidget 仕様の概要について簡単に説明し、記事の後半で書かれている実用的なパートを理解するために必要な最小限の理論的な知識を説明します。この記事では、仕様に記載されている一部の機能についてはあまり詳しく触れていません。

ホーム・ページ・ウィジェットの構造

技術的に詳しく説明する前に、ホーム・ページ・ウィジェットの構造を見てみましょう。ホーム・ページ・ウィジェットは、次の 2 つの部分に分けることができます。

  • ヘッダー : ウィジェットのタイトル、およびアイコンで表されたアクション (ウィジェットの移動、編集、更新、ヘルプ、閉じる) が含まれています。
  • ボディー : 図 1 の赤い長方形の枠で示した部分です。ボディーは、任意の iWidget をユーザーに表示できる場所です。
図 1. ホーム・ページ・ウィジェットの構造
ホーム・ページ・ウィジェットの構造

ウィジェットの開発者は、ホーム・ページ・ウィジェットのボディーに表示されるコンテンツをほぼ完全に制御できます。ウィジェットは、標準の Web ページにある任意のものを表示できます。唯一の制限は、iWidget 仕様で定義されたコンポーネント・モデルに従う点です。

ホーム・ページ・ランタイムは、自動的にヘッダー・バーを生成します。ヘッダー・バーのカスタマイズは、制限付きのレベルでのみ可能です。iWidget によってサポートされるアクションを定義できます。ホーム・ページは、埋め込まれた iWidget によってサポートされていないアクションのアイコンを自動的に非表示にします。管理者は、デプロイメント時にウィジェットのタイトルを定義します。

iWidget 記述子

記述子は iWidget のコアとなる部分です。ウィジェットがサポートするさまざまな機能を記述子で宣言します。iWidget 記述子は、マイクロフォーマットまたは XML 構文の 2 つの異なるスタイルを使用して記述できます。Lotus Connections のホーム・ページは XML 定義スタイルのみサポートするため、この記事ではマイクロフォーマット構文については触れません。「Hello World」の iWidget XML 記述子の例をリスト 1 に示します。

リスト 1. 「Hello World」の iWidget XML 記述子
<iw:iwidget name="helloWorld" xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget" 
iScope="HelloWorldWidgetClass">
   <iw:resource uri="helloworld.js" />			
   <iw:content mode="view">
      <![CDATA[
         <div id="root">
            Hello World! <br/>
               <button id="click" 
               onclick="iContext.iScope().onClickButton()">Click me!</button>
         </div>
      ]]> 
   </iw:content>     
</iw:iwidget>

このウィジェットは、ストリング「Hello World」と 1 つのボタンを表示します (図 2 参照)。

図 2. 「Hello World」ウィジェット
「Hello World」ウィジェット

例として取り上げた XML 記述子の重要な部分について説明します。

  • iScope 属性 : この属性は、iWidget のロジックを含むクラスの名前を指定します。通常は、XML 記述子で宣言されたいずれかのリソース (このリストの次の項目を参照) で定義された JavaScript クラスです。iWidget フレームワークでは、iWidget のインスタンスごとに、iScope オブジェクトのインスタンスが生成されます。
  • iw:resource タグ : これらのタグは、iWidget が必要とするさまざまなリソースを示します。ホーム・ページは、JavaScript リソースとカスケード・スタイル・シート (CSS) リソースをサポートします。XML 記述子で宣言された各リソースは、取り出されて評価されます。「uri」(Uniform Resource Identifier) という名前の属性は、XML 記述子の場所に関連しています。この例では、1 つのリソース、つまり helloworld.js という名前の JavaScript ファイルだけが宣言されています。このファイルは、XML 記述子ファイルと同じディレクトリーに置かれています。iw:content タグは、指定されたモードのマークアップを定義します。マークアップ・フラグメントは、iWidget が指定されたモードで表示されるときに、ホーム・ページによって iWidget 用にレンダリングされる HTML コードです。この例では、ウィジェットには「view」という 1 つのモードだけがあり、これがデフォルト・モードとなります。

iScope クラスの HelloWorldWidgetClass を定義する helloworld.js ファイルのコードをリスト 2 に示します。このクラスは onClickButton メソッドだけを定義します。これは、リスト 1 で示したボタンの onclick イベントに対応するハンドラーです。ユーザーがこのボタンをクリックすると、「Button clicked」というストリングがウィンドウに表示されます。

Dojo の構文

JavaScript はプロトタイプ・ベースの言語です。オブジェクト指向プログラミングに慣れている開発者のために、Dojo Toolkit にはオブジェクト指向のクラス・ヘルパーがいくつか用意されています。この例では、dojo.declare メソッドを使用し、親クラスを拡張せず (null)、1 つのメソッド (onClickButton) を持つ HelloWorldWidgetClass を宣言しています。

リスト 2. helloworld.js の内容
dojo.provide("HelloWorldWidgetClass");

dojo.declare(
   /* class name */                                            
   "HelloWorldWidgetClass",  
   /* parent class */ 
    null,
   /* methods and variables */ 
   {	
      onClickButton: function(){
         alert("Button clicked");
      }
   }
}

iWidget フレームワークによって提供されるサービスの使用

iContext オブジェクトは、iWidget フレームワークによって提供されるサービスとの対話に使用される中心的なオブジェクトです。iWidget フレームワークは、iContext という名前のオブジェクトをウィジェットの iScope クラスにメンバー (this.iContext) として自動的に追加します。この iContext オブジェクトを通じて、iWidget フレームワークの機能を活用できます。

また、iContext オブジェクトをウィジェットの HTML マークアップで使用し、iScope クラスの対応するインスタンスのメソッドをカプセル化された方法で呼び出すことができます。リスト 1 の例は、この手法を使用して onClickButton メソッドを呼び出しています。

カプセル化と iContext

カプセル化は iWidget 仕様の重要な部分です。各 iWidget は、同じページ上で同時に開かれた複数のウィジェットによって宣言されたリソース間でクラッシュが発生するのを防ぐためにカプセル化を必要とします。iWidget フレームワークはウィジェットのカプセル化を支援しますが、開発者はいくつかの作業を行うことも必要です。特に、iWidget 開発者は次のことを実行しなければなりません。

  • この記事の「iWidget 記述子」セクションで説明したように、iWidget クラスのスコープ(iScope)を正しく宣言します。iWidget で使用するどのメソッドまたは変数も、iScope 内で宣言する必要があります。
  • iWidget のリソースでは、グローバルの JavaScript 関数および変数の使用を避けてください。同じページ上の他のウィジェットで、同じ名前のオブジェクトが宣言されていないとは保証できないからです。同じ名前のオブジェクトが宣言されると、クラッシュや競合が発生します。
  • iContext オブジェクトを通じて iWidget フレームワークと対話し、適切なスコープ・オブジェクトを取得します。「Hello World」の例では、iContext.iScope() ステートメントを使用してこれを行います。

ItemSet

ItemSet は、iWidget フレームワークによって管理される名前と値のペアによるセットです。通常、ItemSet は iWidget のプロパティーを格納するために使用されます。ItemSet は、getItemValue および getAllNamesare などのメソッドを通じて、iScope クラスのコード内で操作されます (詳細については、iWidget 仕様を参照してください)。ItemSet は XML 記述子で宣言できます (リスト 3 参照)。

リスト 3. ItemSet の宣言
<iw:itemSet id="itemSetId">
   <iw:item id="item1" value="value1" />
   <iw:item id="item2" value="value2" />
</iw:itemSet>

この記事の最後のセクション「ガジェット・ラッパーのさらなる機能強化」には、この記事でインプリメントする Google ガジェット・ラッパーのプリファレンスを格納する ItemSet の使用例が具体的に示されています。

iWidget フレームワークによって提供される他のサービス

このセクションでは、仕様で定義されているその他のサービスについて説明します。Google ガジェット・ラッパーでは、これらのすべてのサービスが使用されるわけではありません。仕様によって提供される機能には、次のものがあります。

  • イベント・システム : このシステムにより、iWidget はイベントの発行とキャッチが可能になります。ホーム・ページでは、ヘッダー・バーに配置されているアクション (編集や更新など) の 1 つをユーザーが選択したときに、このメカニズムを使用してイベントが iWidget に発行されます。
  • IO モジュール : JavaScript によって同じ系統のセキュリティー・ポリシーが実施されているため (詳細については、http://www.mozilla.org/projects/security/components/same-origin.html を参照)、デフォルトでは、ホーム・ページ・ドメイン以外のドメインに Ajax 要求を発行できません。他のドメインへの要求を送信する機能を与えるために、ホーム・ページには Ajax プロキシーが用意されています。指定された IO モジュールを使用して任意の URL を書き換え、ホーム・ページの組み込み AJAX プロキシーを通じて、Ajax 要求を転送することができます。また、IO モジュールを使用して、XML 記述子の場所に対応するリソースを特定できます。
  • ワイヤリング・システム : ユーザーは複数のウィジェットを構成し、このリストの最初の項目で説明したイベント・システムを使用してデータを交換できます。この機能は Lotus Connections のホーム・ページでは有効ではありませんが、Lotus Mashups では有効です。

Google ガジェットの概要

Google ガジェットは、XML、HTML、および JavaScript で作成された小さくて軽量のアプリケーションです。Google ガジェットは、iGoogle (Google のカスタマイズ可能なホーム・ページ)、Orkut、Google Maps、または Google Desktop などのガジェット・コンテナーに追加できます。ガジェットの開発はすべての人に開放されています。Google は、ユーザーがガジェットを公開できる公開ディレクトリーを提供しています。

iWidgets と同様に、Google ガジェットのコアとなる部分は、その XML 定義ファイルに含まれています。ガジェットの XML 記述子の構造の詳細については、「official developer's guide」の「Writing Your Own Gadgets」の章に記載されています。簡単に言うと、ガジェットの XML 定義では、2 つの主要アスペクトであるガジェットのマークアップ (HTML コード) とプリファレンスのセットを指定します。

現在、2 つの異なる Google ガジェット API があります。この記事では、シンジケートされたガジェット用に Google がサポートするレガシー API を取り上げます。

任意の Web サイトへの Google ガジェットの追加

Google は、ガジェットを任意の Web ページで実行する、シンジケーションと呼ばれる機能を提供しています。この機能を活用し、Google ガジェットを Lotus Connections のホーム・ページに表示するラッパーを作成できます。

  • ユーザーがガジェット・コンテナーの外部でガジェットを実行できるようにするために、Google は JavaScript と HTML で構成されたフォーマット済みの出力を返す Web サービスを提供しています。この出力は、ガジェットの依存関係を開始し、ガジェットをレンダリングする役割を持ちます。このサービスは、いくつかの要求属性、特に Google ガジェットの XML 定義ファイルへの URL を受け取ります。
  • ガジェットの XML 記述子で定義されているユーザー・プリファレンスには、サービスへの要求パラメーターとして「_up」という接頭辞を付加したプリファレンス名を渡すことにより、値を割り当てることができます。渡されたユーザー・プリファレンスの値は、Google ガジェットの XML 定義で指定されたデフォルト値をオーバーライドします。
  • タイトル、幅 (w)、高さ (h)、および境界線のスタイルなどのプリファレンスを表示します。

Google サービスの基本 URL は、「http://www.gmodule.com/ig/ifr」というストリングです。完全な URL の例を以下に示します。この URL には、Google ガジェット「Date Time」の JavaScript コードを返す Google サービスへの要求属性が含まれています。

http://www.gmodules.com/ig/ifr?url=http://www.google.com/ig/modules/
datetime.xml&up_color=blue&up_firstDay=0&
w=320&h=136&output=js

この例では、次のパラメーターに注目してください。

  • 「Date Time」ガジェットの XML 記述子への URL は、「http://www.google.com/ig/modules/datetime.xml」というストリングで提供されます。
  • 色と最初の曜日のユーザー・プリファレンス (このガジェット固有) は、「blue」と「0」(日曜日) に設定されています。
  • 幅 (w) と高さ (h) の表示パラメーターは、320 px と 136 px に設定されています。

Web サービスへの URL を手動で作成することもできますが、必要なすべての要求パラメーターを含めるには、ベスト・プラクティスとして、Google が提供している「Page Creator」ツールを使用するとよいでしょう。このツールを使用すると、グラフィカルな方法で簡単に URL を構成できます。また、このツールでは、ガジェットのプリファレンスの値を指定し、ガジェットの XML 定義で定義された各プリファレンス用の正しい要求パラメーターを含むサービスへの URL を生成できます。「Page Creator」ツールを使用するには、次の手順に従います。

  1. Google ガジェット・ライブラリー」にアクセスします。
  2. ガジェットを選び、「自分の Web ページに追加」オプションを選択します。ガジェット設定とユーザー・プリファレンス値をカスタマイズします。新しい値を設定したガジェットのプレビューがページに表示されます。
  3. 設定が終了したら、「コードを取得」オプションを選択します。
  4. 追加するコードがページに表示されます。Web サービスへの URL は、script タグの src 属性のストリングです。

メモ : すでに気付かれていると思いますが、「Page Creator」から返される URL はいくつかの特殊文字がエスケープされています。たとえば、アンパーサンド (&) 文字は & とエスケープされています。URL は HTML または XML 文書に含めるために構築されるので、文書の正当性を保つために特殊文字のエスケープが必要となります。


iWidget 記述子での Google ガジェットのラッピング

これで、「Date Time」Google ガジェットのラッパーを記述する準備が整いました。このガジェットをホーム・ページにデプロイした結果を図 3 に示します。

図 3. ホーム・ページにデプロイされた Google「Date Time」ガジェット
ホーム・ページにデプロイされた Google「Date Time」ガジェット

このセクションで明らかにする方法は、他の Google ガジェットでも同じです。ただし、適切なガジェットを示すようにコードの 1 行だけを変更します。

最初のアプローチでは、ガジェットをホーム・ページにレンダリングするという唯一の目的に沿って、ラッパーを基本的な状態にとどめます。この記事の最後のセクションで、このラッパーへの機能の追加に焦点を当て、たとえば、ユーザーがガジェット・プリファレンスの値を変更できる編集ビューなどを追加します。

ガジェットのレンダリング方法と XML 記述子

Google ガジェットをホーム・ページにレンダリングするには、適切な要求パラメーターを指定して、「任意の Web サイトへの Google ガジェットの追加」で説明した Google Web サービスを呼び出します。HTML と JavaScript が混ざった応答が、script 要素内に挿入されます。script 要素は、iWidget の IFRAME パートにロードされた HTML 文書内にあります。

IFRAME

IFRAME は他の文書を含むインライン・フレームです。これは標準 HTML 要素で、iWidget 仕様との特別な関連はありません。IFRAME の src 属性は、ロードする文書の URL を示します。

iWidget の XML 記述子のコード・スケルトンをリスト 4 に示します。Google サービスを示す script 要素が含まれる JSP 文書 (gadgetWrapper.jsp) の一部をリスト 5 に示します。

リスト 4. Google ガジェット用の iWidget ラッパー定義
<iw:iwidget name="googleDateTime" 
xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget">
   <iw:content mode=”view”>
   <![CDATA[
      <iframe scrolling="auto" width="100%" height="300px" frameborder="0" 
      src="/gadgetWrapper/gadgetWrapper.jsp?url=<google gadget xml url>">
      </iframe>
   ]]> 
   </iw:content>     
</iw:iwidget>
リスト 5. gadgetWrapper.jsp
<%
   StringBuffer url = new StringBuffer();
   url.append("http://www.gmodules.com/ig/ifr?");
   url.append(request.getQueryString());	
 %>

<script src="<%= url.toString() %>"></script>

コードからわかるように、iWidget は gadgetWrapper JSP ページを示す IFRAME HTML 要素をレンダリングします。この JSP ページは、次のタスクを実行する役割を持っています。

  • URL のクエリー・ストリングの部分を取得します。これは、URL の ? 文字以降のサブストリングです。この場合、「/gadgetWrapper/gadgetWrapper.jsp?url=<google gadget xml url>」のクエリー・ストリングの部分は「url=<google gadget xml url>」となります。
  • gmodule.com でのサービスのコンテキスト・ルートにクエリー・ストリングを追加して、Google サービスへの URL を構築します。
  • クエリー・ストリングからの適切なガジェット・パラメーターを用いて、Google サービスを示すよう script 要素の src 属性を設定します。

Java を使用しない場合は、選択したサービス側の言語 (たとえば、PHP または .NET) で、JSP ページ用に記述された動作を改変できます。重要なことは、Google サービスへの URL を持つ script 要素を単に設定することです。

この時、次の 3 つの点に注意してください。

  • script 要素を直接 iWidget コードの XML 定義に挿入することもできました。しかし、Google サービスから返された JavaScript コードと iWidget フレームワーク間の競合の可能性により、SCRIPT タグを IFRAME 要素内に隔離するという方法を選択しました。
  • • Google サービスは、出力要求パラメーターに (js の代わりに) html の値を受け入れます。その結果、リスト 4 に示した IFRAME に直接挿入できる HTML コードが生成されるので、JSP ページを使用する必要がありません。しかし、このソリューションでは、Google ガジェットの下に「gadget powered by Google」および「+Google」のボタンが含まれず、「Google gadget terms of service」に違反します。
  • この iWidget にはバッキング・ロジックがありません。このため、XML 定義には、iScope または JavaScript リソースへの参照がまったく含まれません。この記事の最後のセクションで、iWidget に何らかのロジックを追加します。

Google「Date Time」ガジェット

図 3 に示した「Date Time」Google ガジェットをラップする iWidget 用の XML 記述子のコードをリスト 6 に示します。IFRAME 要素の src 属性は、「http://www.google.com/ig/modules/datetime.xml」にあるこのガジェットの XML 記述子の URL を示します。また、この属性は、背景色 (orange) や最初の曜日 (0 は日曜日) など、このガジェット固有のユーザー・パラメーターを設定します。前述のように、ガジェットの XML 定義を調べてそのガジェットで利用できるユーザー・パラメーターを特定するか、Google の「Page Creator」ツールを使用できます。

リスト 6. Google「Date Time」ガジェット用の iWidget ラッパー定義
<iw:iwidget name="googleDateTime" 
xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget">
   <iw:content mode="view">
   <![CDATA[
      <iframe scrolling="auto" width="100%" frameborder="0"
	   src="/gadgetWrapper/gadgetWrapper.jsp?url=
http://www.google.com/ig/modules/datetime.xml&amp;up_color=
orange&amp;up_firstDay=0&amp;title=&amp;border=
&amp;output=js"></iframe>
        ]]> 
     </iw:content>
</iw:iwidget>

選択した Google ガジェットの URL を取得し、IFRAME の src (ソース) 属性に挿入するには、「任意の Web サイトへの Google ガジェットの追加」セクションを参照してください。この時点では、ユーザー・プリファレンスを URL 要求ストリングの一部としてハードコーディングします。この記事の最後のセクションで、ユーザーがプリファレンスを変更できるように、このコードを変更します。

メモ: リスト 6 で、2 つの表示パラメーター (title と border) に空の値を設定していることに注目してください。この設定により、Google ガジェットはタイトルと境界線のスタイルを持たずに表示されます。


ホーム・ページへの Google ガジェットのデプロイ

iWidget をホーム・ページにデプロイするには、次の 2 つの主な手順があります。

  1. XML 記述子と iWidget のすべてのリソースを Web サーバーにデプロイする。
  2. デプロイした iWidget XML 記述子の URL を指定して、ウィジェットをホーム・ページ・カタログに登録する。

iWidget のデプロイ

Web サーバーへの iWidget のデプロイは、特定のサーバー・テクノロジーに左右されず、柔軟です。たとえば、iWidget が PHP プロジェクトであることも可能で、その場合は PHP サーバーにデプロイします。また、ウィジェットを Java Platform, Enterprise Edition プロジェクトとしてインプリメントし、WebSphere® Application Server または Tomcat など、サーブレット/Java Platform, Enterprise Edition コンテナーにデプロイすることもできます。この選択はユーザーが行います。Java Platform, Enterprise Edition コンテナーを使用しない場合は、「ガジェットと XML 記述子をレンダリングする方法」セクションで説明した JSP ページを改変する必要があります。

Eclipse で iWidget プロジェクトを Web プロジェクトとして作成し、それを EAR ファイルとしてエクスポートするプロセスを以下の手順で詳しく説明します。 この EAR ファイルは、Java Platform, Enterprise Edition コンテナーにデプロイできます。

メモ: Eclipse で Web プロジェクトを作成するには、Web ツール・プラグインをインストールする必要があります。Web ツール・プラグインは http://download.eclipse.org/webtools/downloads/ からダウンロードできます。Eclipse の Java Platform, Enterprise Edition バージョンには、このプラグインが含まれています。

では、プロジェクトと EAR ファイルを作成し、デプロイの準備をしましょう。まず、Eclipse でプロジェクトを作成します。

  1. 「ファイル」->「新規」->「プロジェクト」を選択します。
  2. ウィンドウで「Web」->「動的 Web プロジェクト」を選択し、「次へ」をクリックします。
  3. 好きなプロジェクト名 (例: gadgetWrapper) を入力します。Eclipse から直接プロジェクトをデプロイする場合はターゲットのランタイムを選択できますが、それ以外の場合は「なし」を選択します。
  4. 「EAR にプロジェクトを追加」オプションを選択し、この Web プロジェクト用に EAR プロジェクトを作成して関連付けるよう Eclipse に指示します。
  5. 「次へ」を選択して最後のウィンドウを表示します。どのデフォルト設定も変更しないでください。「終了」をクリックして Web プロジェクトを作成します。

この時点で、プロジェクトで作業できるようになりました。

次に、iWidget XML 記述子をプロジェクトに追加します。

  1. 「WebContent」で、このディレクトリー名を右クリックし、「新規」->「ファイル」を選択して新しい XML ファイルを作成します。ファイル名として「gadgetWrapper.xml」を入力します。
  2. Eclipse でこのファイルをダブルクリックして開き、リスト 6 に示したコードを貼り付けます。ファイルを編集できないときは、「source」タブが選択されていることを確認します。図 4 を参照してください。
  3. ファイルを保存します。
図 4. Eclipse で編集中の gadgetWrapper.xml
Eclipse で編集中の gadgetWrapper.xml

XML 記述子の追加にも同じ手順を繰り返し、リスト 5 で定義されている JSP をプロジェクトに追加します。このファイルの完成版は、この記事の「ダウンロード」セクションで入手できる gadgetWrapper.ear 内にあります。

次に、WebSphere Application Server など、Java Platform, Enterprise Edition コンテナーにデプロイする EAR ファイルを生成します。

  1. 前の手順で作成した Web プロジェクトに対応する EAR プロジェクトを選択します。
  2. 右クリックし、「エクスポート」->「EAR ファイル」を選択します。
  3. ディスク上のエクスポート先を選択します。

これで、iWidget リソースと XML ファイルを含む EAR ファイルが得られ、任意の Java Platform, Enterprise Edition コンテナーにデプロイする準備が整いました。

この時点で、他の EAR ファイルをデプロイするときと同様に、EAR ファイルを Java Platform, Enterprise Edition コンテナーにデプロイできます。

メモ: リスト 6 で示した IFRAME には、コンテキスト・ルートを /gadgetWrapper に設定した JSP ページ (リスト 5 参照) への参照が含まれています。EAR ファイルをデプロイした実際のコンテキスト・ルートに応じて、その設定を変更することが必要な場合もあります。この記事の最後のセクションで、iWidget の IO モジュールを使用してこの制限を免れる方法を説明します。

ホーム・ページ・カタログでのウィジェットの登録

ホーム・ページには、新しいウィジェットをカタログ・データベースに追加する管理ユーザー・インターフェースがあります。管理者権限を持つユーザーだけが新しいウィジェットをホーム・ページ・カタログに追加できることに注意してください。

以下の手順に従い、ホーム・ページの Web 管理ユーザー・インターフェースを使用して iWidget を追加します。

  1. 管理者アカウントでホーム・ページにログインします。
  2. ホーム・ページで「管理」タブを選択します (図 5 参照)。
    図 5. 「管理」タブ
    「管理」タブ
  3. ページの右下にある「別ウィジェットを追加」オプションを選択します。
  4. 図 6 に示すフォームが表示されます。タイトル名と iWidget の XML 記述子の場所を入力します。
    図 6. 管理者のホーム・ページ
    管理者のホーム・ページ
  5. ウィジェットのタイトルを入力します。入力したタイトルは、ウィジェットのタイトル・バーに表示されます。たとえば、「Google Date Time」というタイトルにすることができます。
  6. XML 記述子の場所を入力します。このフィールドは、前の「iWidget のデプロイ」セクションでウィジェットをデプロイした場所に依存します。
  7. 他のテキスト・フィールドは省略可能で、空のままにすることができます。たとえば、アイコンを指定することができます。アイコンは、ウィジェットが閉じられているときに、サイドバーに表示されます。
  8. すべてのボックスのチェックマークを消去します。これらのボックスは、他の Lotus Connections 機能を扱うウィジェットにのみ必要で、Google ガジェットをラッピングする iWidget には関係ありません。
  9. 「保存」をクリックします。

ウィジェットを管理するための管理オプションの詳細については、「Lotus Connections v2 Information Center」を参照してください。


ガジェット・ラッパーへのさらなる機能強化

このセクションでは、基本的な iWidget により多くの機能を追加する方法を説明します。特に、Google ガジェット定義で宣言されたプリファレンスの一部を変更する機能をユーザーのために追加できます。ユーザー・プリファレンスは Google ガジェット自身で処理されるため、これらのプリファレンスは Google ガジェットの XML 定義で <UserPrefs> 要素として宣言されています。ここでの目標は、ユーザーがこれらのプリファレンスの値を選択できるようにして、その値を Google サービスに送信することです。

ラップされた Google ガジェットをユーザーがカスタマイズできるようにするには、次の手順に従います。

  1. iWidget 用の編集ビューをインプリメントします。ユーザーはこの編集ビューで、Google ガジェット定義で宣言されたプリファレンスの値をカスタマイズします。
  2. 入力された値を、前の「任意の Web サイトへの Google ガジェットの追加」セクションで導入した Google サービスに渡します。これを行うには、新しいプリファレンスの値を URL の一部として Google サービスに渡します。

これらの手順を通じ、この記事で紹介した ItemSet、iWidget フレームワークによって提供されるカプセル化のメカニズム、およびイベント・システムなどの概念を使用した実用的な例も見ることができます。

「Date Time」ガジェットのプリファレンス

このセクションでは、既存の iWidget を変更し、ユーザーが Google「Date Time」ガジェットのプリファレンスを設定できるようにします。使用する手順は他のどの Google ガジェットでも同じです。このため、ここで説明した概念を応用してホーム・ページ内のガジェットをカスタマイズすることは難しくありません。

一般に、Google ガジェットのユーザー・プリファレンスのリストを取得するには 2 とおりの方法があります。

  • ガジェットの XML 記述子を調べ、<UserPrefs> 要素を検索します
  • 「Page Creator」ツールを使用します。プリファレンスのリストは、ガジェット設定セクションの下にあります。

「Date Time」ガジェットの XML 定義を調べると、次の 2 つのユーザー・プリファレンスがあることがわかります。

  • 背景色
  • カレンダーの最初の曜日

これらの 2 つのパラメーターは、許可されている値のリストが列挙として定義されています。ガジェット XML 定義に含まれる色のユーザー・プリファレンスに関する列挙コードのスニペットをリスト 7 に示します。最初の曜日のプリファレンスも同じ種類の列挙を使用します。このセクションの残りの部分で、2 つのプリファレンスについて、列挙にリストされている値からユーザーが 1 つの値を選択できるようにします。

リスト 7. 色のユーザー・プリファレンスの列挙を示す、「Date Time」ガジェットの XML 定義からの抜粋
<UserPref name="color" datatype="enum" default_value="blue" 
display_name="__MSG_color__">
   <EnumValue value="blue" display_value="__MSG_blue__"/>
   <EnumValue value="green" display_value="__MSG_green__"/>
   <EnumValue value="orange" display_value="__MSG_orange__"/>
   <EnumValue value="pink" display_value="__MSG_pink__"/>
   <EnumValue value="purple" display_value="__MSG_purple__"/>
   <EnumValue value="red" display_value="__MSG_red__"/>
   <EnumValue value="yellow" display_value="__MSG_yellow__"/>
</UserPref>

iWidget へのロジックの追加

これまでに提供した iWidget は基本的なウィジェットで、いくらかのマークアップを含むものの、JavaScript ロジックは持っていません。この場合、Google サービスへの URL は、iWidget のマークアップ (iw:content) セクションで直接ハードコーディングしました。ここでは、ユーザーによって入力された値に基づいて URL を動的に構築することにします。これを行うには、URL ストリングの生成ロジックをインプリメントするバッキング・コードを記述する必要があります。ここでの最初の目標は、Google サービス URL の場所を iWidget の HTML マークアップから、以下の手順で示すバッキング・コードに移動することです。

  1. iWidget XML 定義の IFRAME から src 属性を削除することで、マークアップから URL を削除します。コンテンツの部分は、リスト 8 に示すコードのようになります。
    リスト 8. iWidget ラッパーのビューのマークアップ
    <iw:content mode="view">
       <![CDATA[
          <iframe id="frame" scrolling="auto" width="100%" 
          frameborder="0"></iframe>
       ]]> 
    </iw:content>
  2. バッキング・ロジックを含む JavaScript ファイルを作成します。前述したように、ロジックは iScope という JavaScript クラスとしてインプリメントされます。Eclipse で JavaScript ファイルを作成および追加する手順は、「iWidget のデプロイ」セクションで説明した XML 定義ファイルをプロジェクトに追加する手順と同じです。JavaScript ファイルに「googleGadgetWrapper.js」という名前を付けます。このファイルに追加するコードをリスト 9 に示します。
    リスト 9. googleGadgetWrapper.js の最初のバージョン
    dojo.provide("GoogleGadgetWrapper");
    
    dojo.declare("GoogleGadgetWrapper", null, {	
    
       onLoad: function(){
       },
    	
       onview: function(){
       // get the frame DOM object declared in the widget markup
       var frame = this.iContext.getElementById("frame");	
    
       // get the URL to the JSP page location without having to hard-code
       // the context root in the code. For instance, if the context root  
       // after deployment is /gadgetWrapper/, jspLocation is set to
       // /gadgetWrapper/gadgetWrapper.jsp
       var jspLocation = this.iContext.io.rewriteURI("gadgetWrapper.jsp");
    	
       // set the src attribute of the iframe		
       frame.src = jspLocation + "?url=http://www.google.com/ig/modules/datetime.xml&
       title=&border=&output=js&w=400";
       }
    }

リスト 9 のコードを見ていきましょう。

  1. iWidget フレームワークは Load というiEvent をウィジェットに送信します。イベント処理メカニズムについては詳しく触れませんが、この iEvent の送信により、iWidget の iScope で「on + <イベント名>」という名前のメソッドが呼び出されることを知っておく必要があります。この場合は、このメカニズムによって onLoad メソッドが呼び出されます。
  2. iWidget フレームワークは、ウィジェットのデフォルト・モード (view) をロードします。このモードは、次の 2 つの手順でロードされます。
    • モードに対応するマークアップ (XML 記述子の content 要素) がユーザーに表示されます。ウィジェットのマークアップは、リスト 8 のこのモード (mode="view" 属性) で宣言することに注意してください。
    • モードの名前を持つ iEvent がウィジェットに送信されます。この場合は、onview メソッドが呼び出されます。

結果として、ウィジェットがページ上に配置されたときに、onLoad メソッドと onview メソッドがフレームワークによって自動的に呼び出されます。

また、iWidget フレームワークによって (iContext オブジェクトを通じて) 提供された IO モジュールからの rewriteURI メソッドを使用する点にも注意してください。この手法により、プロジェクトのコンテキスト・ルートをコードに含めずに、JSP ファイルの実際の場所を取得できます。開発の時点では、iWidget がデプロイされるコンテキスト・ルートを確実に知ることはできません。この値は、デプロイ時に管理者によって変更される可能性があるからです。

バックエンド・ロジックは、iWidget の XML 定義に接続する必要があります。この接続は、次の 2 つの手順で行われます。

  1. プロジェクトに追加した JavaScript ファイルを示す resource 要素タグを追加します。
    <iw:resource uri="googleGadgetWrapper.js" />
  2. iWidget XML 記述子の iw:widget タグ要素で、googleGadgetWrapper.js で定義された JavaScript クラスを示すように iScope 属性を設定します。この JavaScript クラスの名前は GoogleGadgetWrapper なので、iw:widget タグは次のようになります。
    <iw:iwidget name="googleDateTime"
    xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget" iScope="GoogleGadgetWrapper">

これで IFRAME の src 属性が、ウィジェットの初期化時に動的に設定されるようになりました。この時点では、ユーザーに対するウィジェットの動作に違いはありません。次に、Google サービスへの URL のクエリー部分を生成します。

パラメーターの格納と Google サービスへの URL の生成

IFRAME への URL を設定する前に、Google サービスへの URL を生成および変更する簡単な方法を見てきました。このセクションでは、URL を変更してユーザー・プリファレンスの値を追加します。以下の 3 つの手順で行います。

  1. Google ガジェットのユーザー・プリファレンスの値を iWidget の ItemSet に格納します。プリファレンスの格納に ItemSet を使用するのは、以下の理由によります。
    • ItemSet は便利なデータ・ストアであり、ユーザーが選択した値を取得および設定するためにコードの他の部分で使用できます。
    • ItemSet を使用すると、ホーム・ページ・サーバーでユーザー・セッション間にわたりプリファレンスを保持できます。この点については、この記事の「ユーザー・プリファレンスの保持」セクションで後述します。

    これを行うために、iWidget の XML 定義を変更し、ItemSet を宣言します。ItemSet には「userPrefs」という名前を付けます。後で編集ビューに表示する 2 つのユーザー・プリファレンスのコード・スニペットをリスト 10 に示します。

    リスト 10. 「Date Time」ガジェットのユーザー・プリファレンスを格納する ItemSet
    <iw:itemSet id="userPrefs">
       <iw:item id="color" value="green" />
       <iw:item id="firstDay" value="0" />
    </iw:itemSet>

    また、各ユーザー・プリファレンスのデフォルト値 (「green」および日曜日を示す「0」) も指定しました。

  2. ItemSet に格納された値から、Google サービスへの URL を動的に生成するメカニズムをインプリメントする必要があります。これには、getQueryString という名前のメソッドを iWidget の iScope クラスに追加します。このメソッドのコードをリスト 11 に示します。
    リスト 11. プリファレンス ItemSet からクエリー・ストリングを返すメソッド
    getQueryString: function(){
       // get the ItemSet object
       var userPrefs = this.iContext.getItemSet("userPrefs");
    		
       // get the names ("id") of the items as an array		
       var prefNames = userPrefs.getAllNames();
    		
       // initialize an empty JavaScript object used as a map		
       var params = {};
    		
       // populate the params map with the user parameters
       dojo.forEach(prefNames, function(name) { 
          // we need to prefix the name with "up_" to pass it to the Google Service 
          as discussed in “Google gadget overview” part
          var upName = "up_" + name;
    	params[upName] = userPrefs.getItemValue(name);		
       });
    		
      // generate the string from the params map
      return dojo.objectToQuery(params);		
    }

    このメソッドは、ユーザー・プリファレンスの値をエンコードするストリングを返します。たとえば、「Date Time」ガジェットの場合は、ストリング「up_color=green&up_firstDay=0」を返します。このストリングは、Google サービスへの URL を構築するために直接使用できます。この URL により、Google ガジェットの対応するマークアップが返されます。

  3. リスト 9 で示した onview メソッドを変更し、getQueryString を呼び出して Google サービスへの URL を構築することにより、iFrame の src 属性にこの URL を設定できるようにします。onview の新しいバージョンをリスト 12 に示します。
    リスト 12. ユーザー・プリファレンス値を含む URL ストリングを動的に生成する onview の新しいバージョン
    onview: function(){   
       var frame = this.iContext.getElementById("frame");	
    	
       var query = this.getQueryString();
    
       var jspLocation = this.iContext.io.rewriteURI("gadgetWrapper.jsp");
    			
       frame.src = jspLocation + "?url=http://www.google.com/ig/modules/datetime.xml&
       title=&border=&output=js&w=400&" + query;
    }

編集ビューのインプリメント

これまでに、ユーザー・プリファレンスを格納し、プリファレンス値を含む Google サービスへの URL を生成するメカニズムをインプリメントしました。このサブセクションでは、ユーザーによって入力された値から ItemSet を生成します。このタスクは、以下の 3 つの手順で行います。

  1. ユーザーがプリファレンスの値を選択できるグラフィカルなインターフェースをインプリメントします。これには、編集ビューのマークアップをインプリメントする必要があります。このインプリメンテーションは、編集ビューが有効なときにユーザーが対話するビューです。「Date Time」Google ガジェットの場合は、ユーザーが背景色と最初の曜日をカスタマイズできるようにします。このため、編集ビューを 2 つのドロップダウン・リストを持つフォームとしてインプリメントします。この 2 つのドロップダウン・リストには、2 つのユーザー・プリファレンス用に許可された値をセットします。

    「Date Time」ガジェットをラップする iWidget の編集ビューを図 7 に示します。

    図 7. iWidget ラッパーの編集ビュー
    Edit view of the iWidget wrapper

    iWidget の XML 記述子の一部であるマークアップ・コードのスニペットをリスト 13 に示します。

    リスト 13. ウィジェットの編集ビューのコード <iw:content mode="edit">
       <![CDATA[
       <table>
       <tr>
          <td>Color: </td>
    	<td>
          <select id="color">
    	   <option value="blue">Blue</option>
    	   <option value="green">Green</option>
    	   <!—other options here 
    	</select>
    	</td>
       </tr>
       <tr>
      —-- same principle as for the color drop-down list here -->
       </tr>
       </table>
       <br/>
       <input id="saveButton" type="button" value="Save" 
       onclick="iContext.iScope().onSave()" />
       <input id="cancelButton" type="button" value="Cancel" 
       onclick="iContext.iScope().onCancel()" />
       ]]> 
    </iw:content>

    このリストでは、次の点に注目してください。

    • マークアップは、mode 属性が edit に設定された状態で、iw:content 要素に置かれます。
    • iContext.iScope() メソッドを使用して、正しいカプセル化が行われるようにします。
    • マークアップは、2 つのドロップダウン・リストと 2 つのボタン (「Save」と「Cancel」) を持つ単純な HTML 表です。
  2. ユーザー入力から ItemSet を生成するために、メソッドを iWidget のバッキング・ロジックに追加します。これには、ボタン (onSave() メソッドと onCancel() メソッド) のバッキング・ロジックをインプリメントする必要があります。ユーザーが「Save」ボタンをクリックしたときに呼び出される onSave() メソッドのコードをリスト 14 に示します。
    リスト 14. onSave() メソッドのコード
    onSave: function(){
       // get ItemSet object
       var userPrefs = this.iContext.getItemSet("userPrefs"); 
    
       // set the item values from the drop-down list selections
       userPrefs.setItemValue("color", 
       this.iContext.getElementById("color").value);
       userPrefs.setItemValue("firstDay", 
       this.iContext.getElementById("firstDay").value);
    		
       // switch back to the view mode (widget normal view with the gadget)		
       this.iContext.iEvents.fireEvent("onModeChanged", 
       null, "{newMode: 'view'}");		
    }

    onSave() メソッドは、ユーザー入力に基づいて、ItemSet の 2 つのプリファレンスの新しい値を設定します。save メソッドの最後の行で、ウィジェットの編集モードを返します。これを行うために、ウィジェットに対して onModeChanged イベントを発行します。このイベントは、フレームワークによって、ウィジェットの現行モードを edit から view に変更する要求として解釈されます。この手順の後に、「iWidget へのロジックの追加」セクションで説明したモード処理に関するメカニズムが呼び出されます。

    「Cancel」ボタンの目的は、ItemSet のプリファレンスを保存せずに view モードに戻すことです。このため、onCancel() は onSave() の最後の行となっていて、onModeChanged イベントを発行します。

  3. iWidget の XML 記述子に編集モードを登録します。これには、次に示すように、XML 記述子の iw:iwidget 要素に supportedMode 属性を追加します。
    <iw:iwidget name="googleDateTime"
    xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget"
    iScope="GoogleGadgetWrapper" supportedModes="edit view">

    この変更を行い、ウィジェットを再デプロイすると、ホーム・ページ・ウィジェットのヘッダー・バーに編集アイコンが表示されます (図 8 参照)。

図 8. iWidget のヘッダー・バーの「編集」ボタン
Edit button in the header bar of the iWidget

ユーザーが「編集」ボタンをクリックすると、ホーム・ページ・ランタイムは埋め込まれた iWidget に対し onModeChanged イベントをトリガーします。このイベントにより、フレームワークは編集ビューをレンダリングし、iWidget の iScope で onedit というメソッドを呼び出します。最後に、onedit メソッドでのロジックの追加方法をリスト 15 に示します。このロジックでは、ItemSet に格納された値を使用して、編集ビューの 2 つのドロップダウン・リストを設定します。

リスト 15. 格納された値を使用して編集ビューのドロップダウン・リストを設定する onedit メソッド
onedit: function(){
   var userPrefs = this.iContext.getItemSet("userPrefs"); 
   this.iContext.getElementById("color").value = userPrefs.getItemValue("color");
   this.iContext.getElementById("firstDay").value = userPrefs.getItemValue("firstDay");
}

ユーザー・プリファレンスの保持

iWidget ラッパーへの最後の機能強化は、ItemSet に格納されたユーザー・プリファレンスを保持することです。このタスクを行うと、ユーザーによってカスタマイズされた内容が失われません。ホーム・ページ・ランタイムによって、ItemSet をサーバー・サイドで保持する 2 つのメソッド (_save および _load) が提供されています。

メモ: このインプリメンテーションは、iWidget フレームワークのホーム・ページ固有の拡張であり、Lotus Mashups など、他の iWidget コンテナーでは機能しません。

_save メソッドと _load メソッドは URI をパラメーターとして受け取ります。この URI は ItemSet を保持する場所です。ItemSet のエンコードおよびデコードのために、これらのメソッドが使用するシリアライゼーションについては、この記事の範囲を超えています。ただし、ホーム・ページは handleUP?Act=XXX&FId=XXX に書かれているストリングを受け取ったり、返したりするサービス (Servlet) を提供します。なお、Act は SaveCustomization と LoadCustomization を値として受け取り、FId は iWidget ID です。

メモ: ホーム・ページでは、iContext から ウィジェット ID (iContext.widgetId) を取得できます。 この変数はホーム・ページ固有のものであり、iWidget 仕様の一部ではありません。

維持レイヤーからの値を使用して userPrefs ItemSet を生成する役割を持つ onLoad メソッド (ウィジェットがページに配置された直後に呼び出されます) のコードをリスト 16 に示します。値が保持されていない場合は (ユーザーが、このウィジェットのプリファレンスを変更および保存しなかったことを意味します)、iWidget の XML 記述子 (リスト 9) で定義されている値がデフォルト値として使用されます。

リスト 16. ホーム・ページの維持レイヤーからのユーザー・プリファレンスのロード
onLoad: function(){
   var userPrefs = this.iContext.getItemSet("userPrefs");
   userPrefs._load("handleUP?Act=LoadCustomization&FId=" + this.iContext.widgetId);
}

最後に、ItemSet 値を保存する必要があります。この手順は、ユーザーが編集ビューで「Save」ボタンをクリックしたときに実行しなければなりません。このため、onModeChanged イベントをトリガーする直前に、onSave メソッドで userPrefs オブジェクトに _save メソッドを呼び出す必要があります。EAR ファイルのソース・コードは、この記事の「ダウンロード」セクションで入手できます。


まとめ

この記事では、Google ガジェットをラップする基本的な iWidget を Lotus Connections のホーム・ページにインプリメントおよびデプロイするさまざまな手順を説明しました。また、ラッパー自身のインプリメンテーションに加え、iWidget フレームワークによって提供されるいくつかの機能を具体的な例を通じて紹介しました。この記事を読むことにより、XML 記述子、ItemSet、モード、イベントなどの概念を十分に理解し、ホーム・ページ用の基本的なウィジェットを記述できるようになります。また、たとえば iWidget の編集ビューでユーザーがガジェットの記述子の場所を指定できるようにするなど、Google ラッパーへの機能強化のインプリメントを継続することができます。


謝辞

著者は、developerWorks を書くためにすべてのプロセスをガイドしていただいた Luis Benitez 氏に感謝します。また、このトピックに関する記事を書くことを提案していただいた Adrian Spender 氏に感謝します。

さらに、記事をレビューし、改良点を指摘していただいた Luis、Adrian、および Li Xu の各氏にも感謝します。


ダウンロード

内容ファイル名サイズ
gadgetWrapper.ear4KB

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Lotus
ArticleID=367669
ArticleTitle=IBM Lotus Connections における Google ガジェットのデプロイとインプリメント
publish-date=09092008