目次


XForms を Google Web Toolkit と統合する、第 1 回

GWT の JSNI (JavaScript Native Interface) を紹介する

ロック・スター志望者のための Web アプリケーションを作成する

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: XForms を Google Web Toolkit と統合する、第 1 回

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:XForms を Google Web Toolkit と統合する、第 1 回

このシリーズの続きに乞うご期待。

はじめに

GWT (Google Web Tookit) は、Ajax アプリケーションを開発するための非常に一般的な方法になっています。Java 開発者は GWT を使うことによって、JavaScript の知識を何も必要とせずに、自分たちが持つ Java™ 技術の知識を活用して素早く Ajax アプリケーションを開発することができます。一方、XForms は HTML 標準の進化を表しており、単純な構成体を使って複雑で動的な動作を作成することができます。GWT と XForms はどちらも非常に強力であり、多くの問題に対して完全なソリューションを提供することができます。では、両方を同時に使ったらどうなのでしょう。このシリーズでは、まさにその問題を説明します。

このシリーズでは、ロック・スターとそのアルバムを管理する簡単な Web アプリケーションを開発します。GWT と XForms の両方を使い、そして最終的にはこの 2 つの技術を、お互いに交換可能な方法で共存させます。第 1 回では、簡単な例を使って 2 つの技術を説明します。特に GWT に関しては、KitchenSink の例を使います。この例を使う理由は、これが GWT の持つ、数々の UI ウィジェットを紹介することができるからです。

前提条件

この記事では、GWT のバージョン 1.4 と Mozilla の XForms プラグイン 0.8 を使います (ダウンロードのためのリンクは「参考文献」を参照してください)。Mozilla の XForms プラグインは、Mozilla ベースの Web ブラウザー (Firefox や Seamonkey など) であれば、どのブラウザーでも動作します。GWT には、Java 技術の知識と HTML や CSS などの Web 技術の知識が必要です。この記事では JavaScript も頻繁に使います。XForms は Model-View-Control のパラダイムを使うため、このパラダイムに慣れていると便利です。これまでに XForms と GWT を経験したことがあると役立ちますが、必須ではありません。

XForms

皆さんが Web アプリケーションを作成する場合には、おそらく Ajax 対応の Web アプリケーションを作成するでしょう。皆さんはおそらくこれまで、データを非同期に追加できるパターンや編集できるパターンなど、多くの Ajax パターンを経験してきているはずです。これらのパターンの多くが、Ajax という用語を誰も口にしたことのない頃から考えられていたものだと知ると、驚く人がいるかもしれません。Ajax を使ってできる一般的なことの多くは、XForms を使って行うこともできます。

XForms は、次世代の HTML 仕様の中心になると思われる、標準に基づく技術です。XForms の重要な点は、データと、そのデータの物理的なビューとを分離していることです。これはおなじみの概念のように聞こえませんか。データを分離することによって、そのデータは、考えられるどのような HTML の方法を使っても表示することができます。またフォーム要素にデータをバインドすることによって、データの入力と既存データの編集をシームレスに行うことができます。

Ajax も、こうした問題と同じ多くの問題を解決するために使われます。Ajax では、データと表示 (HTML) を分離しておく必要がありますが、データを表示するために、JavaScript オブジェクトを作成する羽目になることがよくあります。XForms は、これに対してもっと標準化された方法を提供しており、インスタンス・データを XML として保持します。では例を見てみましょう。

XML のインスタンス・データ

XForms は、おなじみの Model-View-Controller のパラダイムを使います。従って、XForms の背後にあるデータは XForms モデルの中に含まれています。その一例をリスト 1 に示します。

リスト 1. XForms モデルの例
        <xf:model id="my-model" xmlns="http://www.w3.org/1999/xhtml" 
		xmlns:xf="http://www.w3.org/2002/xforms">
            <xf:instance id="my-data" src="my-data.xml" xmlns=""/>
            <xf:bind calculate="sum(../Item/Amount)" nodeset="/Data/Total"/>
            <xf:submission action="my-data.xml" id="update-from-local-file" 
			instance="my-data" method="get" replace="instance"/>
            <xf:submission action="my-data.xml" id="view-xml-instance" 
                 method="get"/>
            <xf:submission action="my-data.xml" id="saveToServer" 
                 method="put"/>
        </xf:model>

ここではいくつかのことに注目する必要があります。第 1 は、XForms モデルに含まれる XForms インスタンスです。このインスタンスは、このモデルが表現する実際のデータであり、このインスタンスに対してソースを提供することができます。これは、JavaScript や CSS など他のリソースを参照することと非常に似ています。ソースの属性を提供すると、別の HTTP リクエストがブラウザーによって作成され、データがロードされます。あるいは、インスタンス・データをインライン化することもできます。また、モデルとインスタンスの両方が ID を持っていることにも注目してください。これは後でわかるように、モデルとインスタンスを他の技術に公開するための鍵となります。

最後に、XForms のさまざまな送信宣言に注目してください。ここにリストされているアクションは、基本的な HTML フォームに見られるアクションと似ています。これらのアクションは URL の形式をしており、この URL に送信されるフォーム・データを持つことになります。ここで method 属性に注目してください。これも HTML フォームに見られる method 属性とほとんど同じであり、その送信にどんな種類の HTTP リクエストを行うかを指定しています。これはすべて、モードの一部です。今度は XForms でのビューを見てみましょう。

XForms のビュー

モデルが宣言されると、モデルによってカプセル化されたデータから、容易にビューを作成することができます。XForms には、モデルのインスタンス・データを処理するための一般的なコントロールが無数に含まれています。各コントロールは、そのモデルのインスタンス・データのデータを参照することができます。インスタンス・データは XML フォーマットなので、XPath を使ってそのデータを容易かつ自由にナビゲートでき、参照することができます。XForms は XPath 2.0 仕様を完全にサポートしています。ではいくつかの例を見てみましょう。

モデルのデータを使ってできる最も簡単なことは、単純にそのデータをブラウザーにエコー・バックすることです。これは出力コントロールを使って行うことができます (リスト 2)。

リスト 2. XForms の出力
<xhtml:div id="sum">
  <xf:output class="item-amount" ref="/Data/Total" 
  xmlns="http://www.w3.org/1999/xhtml">
  </xf:output>
</xhtml:div>

ref 属性は単なる XPath 式です。この属性を、モデルのインスタンス・データに対して評価します。XHTML 式 (div や、出力コントロールの CSS クラス属性など) と XForms のコントロールとがどのように混在しているかに注目してください。これはいい加減に作ったものではなく、XForms が今後の HTML に不可欠な部分であることを示しています。

XForms は単にデータを表示するためだけのものではなく、対話動作のために設計されています。従って当然ながら、データを編集するためのコントロールがあります。リスト 3 を見てください。

リスト 3. XForms のフォーム・コントロール
<xf:input class="item-amount" ref="Amount" xmlns="http://www.w3.org/1999/xhtml">
    <xf:label>Amount</xf:label>
</xf:input>
<xf:submit submission="saveToServer" xmlns="http://www.w3.org/1999/xhtml">
    <xf:label>Save</xf:label>
</xf:submit>

リスト 3 は、ラベルと Submit ボタンを持つ入力フィールドを作成する簡単な例を示しています。ここにあるものはすべて、モデルにバインドされています。入力フィールドはインスタンス・データにバインドされています。HTML 要素で考えると、この入力フィールドには、データ・モデルにバインドされた値が事前に入力されています。

送信コントロールはもちろん、HTML の Submit ボタンになります。これも、モデルにバインドされています。そしてモデルの送信要素を参照します。この送信要素はフォームのアクションを指定します。従って、この送信コントロールは HTML の Submit ボタンを作成し、このボタンをクリックすると、モデルの送信仕様のアクションにある URL に対して HTTP POST が送信されます。ではこの URL には具体的に何がポストされるのでしょう。もちろん、XML データです。このデータは入力コントロールにバインドされています。そのため、ユーザーが新しい値を入力すると、その値はサーバーへの HTTP POST が送信される前に自動的にモデルに送られます。

さて、HTML フォームの送信は通常、その POST のアクション URL へのナビゲーションと関連付けられます。これは典型的な「Web 1.0」エクスペリエンスですが、幸いこれは XForms には無縁です。XForms アプリケーションでは、送信は単にデータをサーバーにポストするにすぎません。ナビゲーションとは無関係です。これは、モデル (データと、データに対する操作 (データをサーバーへ送信する、など) ) とビューとの明確な分離を示す一例です。

実際にはどうなのでしょう。これらはどれも、Ajax アプリケーションでは非常に典型的な話に聞こえないでしょうか。おそらく JavaScript で作成されている数えきれないほどの行で、データをフォームにバインドし、フォーム送信をキャッチし、非同期でデータをサーバーに送り返し、そしてそのデータを表示しているビューの部分を再描画しています。これはすべて、XForms の実装の中に組み込まれます。XForms 内部のみでも多くのことを実現できますが、これは決して XForms のみで使われるような技術ではなく、クライアント・サイド技術の基本、つまり HTML の DOM と JavaScript に直接結びつけられるのです。

XForms と JavaScript

XForms では、アプリケーションの背後にあるデータはモデルとして表現され、さまざまなビューにバインドされます。これは、サーバー・サイドのコードを開発する際に必ず目にする種類の方法であり、Ajax のおかげでクライアント・サイドでも次第に一般的になりつつあります。XForms はクライアント・サイドの技術です。そのため、ブラウザーのネイティブ言語である JavaScript を使って容易に利用できることは、驚くにはあたりません。

XForms の強力な世界に対して、同じページで実行する JavaScript から完全にアクセスすることができます。実際、すべての XForms 要素、そしてモデルとビューの双方ともに、作成される HTML の DOM の一部です。これらはすべて、次世代の HTML 仕様に従っています。そのため、おなじみの getElementById() のパラダイムを使うことで、HTML の div にアクセスする場合と同じように XForms 要素にアクセスすることができます。JavaScript を使って XForms モデルをアクセスする例として、リスト 4 を見てください。

リスト 4. JavaScript で公開された XForms モデル
var model = document.getElementById("my-model");
var instance = model.getInstanceDocument("my-data");
var dataElement = instance.getElementsByTagName("Data")[0];
var itemElements = dataElement.getElementsByTagName("Item");
var cnt = itemElements.length;
var descripElement = itemElements[0].getElementsByTagName("Description")[0];
descripElement.childNodes[0].nodeValue = "";
var amtElement = itemElements[0].getElementsByTagName("Amount")[0];
amtElement.childNodes[0].nodeValue = "0";
model.rebuild();
model.recalculate();
model.refresh();

リスト 4 を見るとわかるように、DOM の一部として XForms モデルにアクセスすることができます。取得されるものは、ファーストクラスの JavaScript オブジェクトです。このオブジェクトが、getInstanceDocument() のような特別なメソッドを持っていることに注目してください。このメソッドによって XML のインスタンス・データにアクセスすることができます。これは実際の XML DOM オブジェクトなので、他の任意の XML DOM オブジェクトの場合と同じように、このオブジェクトをナビゲートしたり変更したりすることができます。

GWT

GWT は 2006年の JavaOne で紹介されました。それ以来、GWT は Java 技術の開発者の間で非常に一般的なものとなっています。Java 技術の開発者は GWT を利用することで、彼らが持つ Java 技術のスキルと、それに加えて HTML と CSS に関する基本的な知識を少し使うだけで、Ajax 対応の Web アプリケーションを迅速に開発することができます。GWT は迅速なプロトタイピングを行うための明らかに有効なツールですが、実動のシナリオでもその機能が実証されています。例えば、Google 自身の Mashup Editor (Web アプリケーションと Web API とをスクリプトで統合するためのオンライン統合開発環境) は GWT を使って作成されたものです。

GWT の背後にある魔術の多くは、Java コードを JavaScript にコンパイルできる機能で実現されています。これによって Java 技術の開発者は、サーバー・サイドのモデルに直接結合された、おなじみのイベント駆動プログラミングを使うことができます。大部分の Java 開発者は、自分自身で JavaScript を作成しなくてよいことだけで十分に満足しています。彼らは強い型付けの言語の利点を活用でき、また標準的なデバッグ・ツール (Eclipse など) を使って Ajax 対応の Web アプリケーションをデバッグすることができます。

もし JavaScript を扱うことをいとわなければ、GWT によってさらに可能性が広がります。最も重要なことは、JavaScript が GWT の世界に出入りするための鍵であることです。GWT で作成されていないものと GWT で作成されたものとを対話動作させたい場合、あるいはその逆の場合には、JavaScript こそがその手段です。

幸い GWT は、他の技術と適切に連携動作するように作成されています。GWT は、その背後に隠された JavaScript の世界を開き、GWT クラスの中から直接 JavaScript でコーディングできるようにします。そのとおり。GWT の JSNI (JavaScript Native Interface) を使うことによって、Java クラスと並列に JavaScript を作成できるのです。

JSNI

GWT のドキュメンテーション (「参考文献」を参照) を読むと、JSNI の使い方がいくつか示されています。JSNI を使うことで、クライアント・サイドのメソッドを完全に実装することができます。また既存の JavaScript をラップすることもできるため、既存のアプリケーションを GWT にマイグレーションする際に非常に便利です。JSNI を使ってクライアント・サイドの Java コード (いずれにせよ JavaScript にコンパイルされます) にアクセスでき、その逆も可能です。ここで重要な点は、JavaScript で可能なことはすべて GWT の JSNI を使って行うことができ、Java 表現は必要ないという点です。では JSNI の例をいくつか見てみましょう。

JSNI の例

JSNI を使って何ができるかを調べるために、GWT に同梱されている例の 1 つから始めましょう。ここでは KitchenSink の例を使います。この例は、GWT に含まれているさまざまな UI 要素を示すショーケースです。この例はすべてがクライアント・サイドであり、サーバーへの通信がないので、JSNI の実験にも便利です。

ここでは、JavaScript で実装される Java メソッドを定義します。まず、JavaScript で可能な最も簡単なこと、つまり古典的な「Hello world」を表示することから始めます。この、JSNI 版の Hello world をリスト 5 に示します。

リスト 5. JSNI 版の Hello world
private native void blastName() /*-{
	alert("Hello world");
}-*/;

この JSNI メソッドを使うために、このメソッドを KitchenSink クラスに追加します。そして次に、Java メソッド showInfo() からこのクラスを呼び出すことで、起動時に JSNI のメソッドをこのクラスに実行させます (リスト 6)。

リスト 6. Java から JSNI を呼び出す
private void showInfo() {
  show(list.find("Intro"), false);
  blastName(); // added JSNI method
}

GWT では、Java プラットフォームで作成されたものとまったく同じようにネイティブ・メソッドを扱えることに注目してください。これは非常に簡潔で単純です。ホスト・モードでコンパイルして実行すると、図 1 のようなインターフェースが表示されるはずです。

図 1. KitchenSink
KitchenSink
KitchenSink

これは非常に単純です。今度は、もっと複雑にし、Java と JavaScript の間でデータを共有してみましょう。

JSNI から Java 変数にアクセスする

JSNI を便利なものにするためには、Java で作成されたコードと JavaScript のネイティブ・コードとの間でデータを共有できる必要があります。こうすることによって、GWT をの利点を生かしながら同時に JavaScript の強力さを活用することができます。リスト 7 を見ると、JSNI 版の「Hello world」が改善された様子がわかります。

リスト 7. JSNI の変数と Java の変数
public class KitchenSink implements EntryPoint, HistoryListener {

  private static final Sink.Images images = (Sink.Images) GWT.create(Sink.Images.class);

  protected SinkList list = new SinkList(images);
  private SinkInfo curInfo;
  private Sink curSink;
  private HTML description = new HTML();
  private VerticalPanel panel = new VerticalPanel();
  // new variable to be accessed in JSNI
  private String myVar = "Hello variables";

myVar 変数は Java で定義されていますが、この変数に JSNI メソッドの中からアクセスすることができます (リスト 8)。

リスト 8. myVar 変数に JSNI メソッドの中からアクセスする
private native void blastName() /*-{
  var str = 
   this.@com.google.gwt.sample.kitchensink.client.KitchenSink::myVar;
  alert(str);
}-*/;

今度は新しい KitchenSink をコンパイルし、先ほどと同じようにボタンをクリックすると、図 2 のようなインターフェースが表示されるはずです。

図 2. Hello 変数
Hello 変数
Hello 変数

これで、Java コードと JavaScript のネイティブ・コードとの間で容易にデータを渡し合えるようになりました。JavaScript によって公開される他の任意の技術 (例えば XForms など) と GWT とを結合するために必要な、すべてのビルディング・ブロックが得られたのです。

まとめ

XForms と GWT はどちらも、最近の Ajax アプリケーションのための強力な抽象化とツールを提供しています。またどちらも「下位レベル」の JavaScript に結合することができます。そのため、XForms と GWT それぞれの技術が既に提供している豊富な機能を増強するために JavaScript を利用できるだけではなく、他の技術 (例えば Xforms、GWT お互いの技術) と組み合わせるための共通の基盤も提供します。今回の記事で、XForms と GWT とを統合するための青写真ができました。第 2 回では、この青写真に従って XForms と GWT とを共存させます。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML, Java technology
ArticleID=262023
ArticleTitle=XForms を Google Web Toolkit と統合する、第 1 回: GWT の JSNI (JavaScript Native Interface) を紹介する
publish-date=09182007