Google Wave API開発ガイド(後編)

JavaとPythonでGoogle WaveのRobotを作るには


株式会社鳥人間
郷田まり子
2009/10/22


【Java編】App Engineでの開発準備

 JavaでのApp Engineアプリケーションの開発には、「Google App Engine SDK for Java」が必要です。また、スムーズな開発作業には、統合開発環境Eclipse専用のグーグル製プラグインが最適です。このプラグインは、Eclipse 3.3または3.4に対応しています。

 まずは、App Engineのアカウントでログインし、SDKをダウンロードしましょう。

 次に、Eclipseのソフトウェア更新機能を使って、Eclipseプラグインをインストールします。まず、Eclipseのメニューから[Help]→[Software Updates]→[Find and Install]を開きます。詳細は、Eclipseのバージョン3.3と3.4で微妙に違うので、別々に示します。

Eclipse 3.4でグーグル製プラグインをインストール

  • [Help]→[Software Updates and Add-ons]を選ぶ
  • [Available Software]タブを選択
  • [Add Site]をクリック
  • [Location]テキストボックスに「http://dl.google.com/eclipse/plugin/3.4」(※注意:インストールURLが3.3とは異なる)を入力して[OK]
  • インストールロケーションが追加されるので、[Google]→[Google Plugin for Eclipse 2.4]と[Google App Engine Java SDK]をチェック
  • [Install]をクリック

 詳細は、英語ですが「Google Plugin for Eclipse 3.4 (Ganymede) Installation Instructions」を参考にしてください。

Eclipse 3.3でグーグル製プラグインをインストール

  1. [Help]→[Search for new features to install]を開く
  2. [New Remote Site]をクリック
  3. [URL]欄に「http://dl.google.com/eclipse/plugin/3.3」(※注意:インストールURLが3.4とは異なる)を入力
  4. [Google Update Site for Eclipse 3.3]が加わっているので、これにチェックを入れた状態で[Finish]

 詳細は、英語ですが「Google Plugin for Eclipse 3.3 (Europa) Installation Instructions」を参考にしてください。

【Java編】Robot開発の準備

グーグル関係のメニュー

 まず、EclipseでRobotのプロジェクトを生成します。Eclipseプラグインをインストールすると、グーグル関係のメニューがEclipseに加わっているはずです。メニューバーにも、3つのアイコンが加わります。

  • :Google App Engine用Webアプリケーションの新規作成
  • :GWT(Google Web Toolkit)アプリケーションの新規作成
  • :Google App Engineにデプロイ

 Google App Engine用Webアプリケーションの新規作成アイコンをクリックして、App Engineプロジェクトを生成します。[Navigator]上で右クリックメニューを出し、[New Project]ダイアログを開いて[Google]→[Web Application Project]を選んでもOKです。すると、プロジェクト基本情報の入力ダイアログが表示されます。

プロジェクト基本情報の入力ダイアログ

 ここで、プロジェクト名・パッケージ名などを入力し、[Finish]ボタンでプロジェクトを作成します。最低限のファイルを含んだ、App Engine用のプロジェクトが生成されます。

作成されたプロジェクト

 「src」ディレクトリには自ら書いたコードを、「war/WEB-INF/」ディレクトリには設定ファイルやライブラリを、そのほか「war」ディレクトリ直下には、公開したい静的ファイルを置きます。静的ファイルは3000までと個数に上限があるのでご注意ください。「war/WEB-INF/lib/」には、あらかじめApp Engineに必要なライブラリ群が入っています。

App Engineに必要なライブラリ群

Robot開発用Javaライブラリ

 ここに、Robot用のJavaライブラリも追加する必要があります「wave-robot-java-client」から、以下の3つのjarファイルをダウンロードし、「war/WEB-INF/lib」ディレクトリに取り込んでください。 

  • wave-robot-api-*.jar
  • jsonrpc.jar
  • json.jar

 これらのjarをプロジェクトのビルドパスに加えておきます。プロジェクトを選んだ状態で、[Properties]→[Java Build Path]→[Libraries]の[Add JARs]から、先ほど追加したライブラリを選びます。

ライブラリの追加

【Java編】コード部分の実装

 では、Robot本体となるJavaのコードを書いていきます。プロジェクト生成時、「src/<プロジェクト作成時に入力したパッケージ名>/server/」内に、新たにjavaファイルを作成します。ここでは「HelloRobotService.java」とします。

package com.example.wave.server;
 
import com.google.wave.api.*;
 
public class HelloRobotService extends AbstractRobotServlet {
 
    @Override
    public void processEvents(RobotMessageBundle bundle) {
        Wavelet wavelet = bundle.getWavelet();
 
        if (bundle.wasSelfAdded()) {
            Blip blip = wavelet.appendBlip();
            TextView textView = blip.getDocument();
            textView.append("Hello, I'm a test robot!");
        }
        for (Event e: bundle.getEvents()) {
            if (e.getType() == EventType.WAVELET_PARTICIPANTS_CHANGED) {
                for (String participantName: e.getAddedParticipants()) {
                    if (participantName.endsWith("appspot.com")) continue;
                    Blip blip = wavelet.appendBlip();
                    TextView textView = blip.getDocument();
                    textView.append("Welcome, " + participantName + "!");
                }
            }else if (e.getType() == EventType.BLIP_SUBMITTED) {
                String submittedText = e.getBlip().getDocument().getText();
                Blip blip = e.getBlip().createChild();
                TextView textView = blip.getDocument();
                String creatorName = e.getBlip().getCreator();
                textView.append(creatorName + " said '" + submittedText + "'");
            }
        }
    }
}

 これが、シンプルなRobotのコードです。各要素を見ていきましょう。

import com.google.wave.api.*;

 Wave開発に必要なパッケージをインポートしています。

public class HelloRobotService extends AbstractRobotServlet {

 クラス宣言部分。Robot作成のための抽象クラス、AbstractRobotServiceを継承しています。 

    @Override
    public void processEvents(RobotMessageBundle bundle) {

 イベント発生時の動作を実装するには、「processEvents(RobotMessageBundle)」メソッドをオーバーライドします。

Wavelet・Blip・TextView


        Wavelet wavelet = bundle.getWavelet();

 「Wavelet」という、Waveの一部を取得します。これには、参加者情報や一連の発言などが含まれています。

 ここから先は、Wave特有のさまざまなクラス・インターフェイスがいろいろと登場します。それぞれが実際のWaveのどの部分に相当するかというのを下記リストにまとめました。

  • Wavelet
    Waveにおける会話の一部に相当。会話データや参加者データ、そのほかメタデータが含まれている
  • Blip
    会話の単位。Waveの画面上において枠で囲まれている単位がBlip。Blipには、さらに子要素としてBlipが付け加えられることもあり、木構造になっている
  • TextView
    Blipの中身。Blipの編集をするときには、TextViewオブジェクトを操作する
枠に囲まれた部分がBlip

Robot自身が参加

 ここからは、実際に発言を付け加えたりする動作です。まずは、Robot自身が参加するときにあいさつメッセージを投稿する処理です。

        if (bundle.wasSelfAdded()) {
            Blip blip = wavelet.appendBlip();
            TextView textView = blip.getDocument();
            textView.append("Hello, I'm a test robot!");
        }

 Robot自身が追加された直後にのみ、bundle.wasSelfAdded()はtrueを返します。Robot参加時に一度だけ行いたい処理を書くのに便利です。そして、新規Blipを生成します。WaveletのappendBlip()メソッドは、空のBlipを会話の最後に生成して返します。そして、生成したBlipの内容に文字列を付け加えています。

イベント操作


        for (Event e: bundle.getEvents()) {

 その次に、EventBundleに含まれるEventを列挙し、各に対して処理を行っています。

            if (e.getType() == EventType.WAVELET_PARTICIPANTS_CHANGED) {

 EventオブジェクトのgetType()メソッドで、そのイベントの種類を取得し、種類による分岐処理を行っています。このEventType.WAVELET_PARTICIPANTS_CHANGEDというのは、「参加者の変更」イベントです。例えば、「新たに誰かが参加してきたとか」「誰かが去っていった」といったイベントです。

 ほかにも、EventType列挙型の定数として、いろいろな種類のイベント種別が定義されています。

表1 Javaのイベントハンドラ
イベント種別の定数 イベントの概要
BLIP_CONTRIBUTORS_CHANGED Blipの編集者の変更
BLIP_DELETED Blipの削除
BLIP_SUBMITTED Blipの送信
BLIP_TIMESTAMP_CHANGED Blipの更新
BLIP_VERSION_CHANGED Blipの更新
DOCUMENT_CHANGED 文書内容の変更
FORM_BUTTON_CLICKED フォームのボタンがクリックされたとき
WAVELET_BLIP_CREATED Blipの新規作成
WAVELET_BLIP_REMOVED Blipの削除
WAVELET_PARTICIPANTS_CHANGED 参加者の変更(参加・退室)
WAVELET_SELF_ADDED Robot自身の参加
WAVELET_SELF_REMOVED Robot自身の退室
WAVELET_TIMESTAMP_CHANGED Waveletの更新
WAVELET_TITLE_CHANGED Waveletのタイトルの変更
WAVELET_VERSION_CHANGED Waveletのバージョンの変更

 この中のどの種類のイベントに反応するかは、後で登場する設定ファイルcapabilities.xmlにも記述します

 参加者に変更があった場合の処理の内容です。

            if (e.getType() == EventType.WAVELET_PARTICIPANTS_CHANGED) {
                for (String participantName: e.getAddedParticipants()) {
                    if (participantName.endsWith("appspot.com")) continue;
                    Blip blip = wavelet.appendBlip();
                    TextView textView = blip.getDocument();
                    textView.append("Welcome, " + participantName + "!");
                }
            }

 e.getAddedParticipants()で、新たに加わった参加者のユーザーID(String型)が格納されたListを取得し、ループで回し、「Welcome, <ユーザーID>」という内容のBlipを追加していきます。

子Blipの生成

 次は、新規Blipが生成されたときの処理です。

            }else if (e.getType() == EventType.BLIP_SUBMITTED) {
                String submittedText = e.getBlip().getDocument().getText();
                Blip blip = e.getBlip().createChild();
                TextView textView = blip.getDocument();
                String creatorName = e.getBlip().getCreator();
                textView.append(creatorName + " said '" + submittedText + "'");
            }

 e.getBlip()で、そのイベントで生成されたBlipを取得し、子要素として新しいBlipを生成しています。その中の文字列を「<発言者> said '<発言内容>'」にセットしています。

 ちなみに、Robot自身が生成したBlipに対しては「WAVELET_BLIP_CREATED」イベントは発生しません。「このタイプのイベントに反応してBlipを作る」→「そのイベントに反応してさらにBlipを生成」……という無限ループは防げるようになっています。

【Java編】設定ファイルを書く

 先ほど実装したコードを実際にRobotとして利用できるように設定するために、いくつかのXMLファイルを書きます。

web.xmlの編集

 まず、「war/WEB-NF/web.xml」を編集します。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>HelloRobot</servlet-name>
<servlet-class>com.example.wave.server.HelloRobotService</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloRobot</servlet-name>
<url-pattern>/_wave/robot/jsonrpc</url-pattern>
</servlet-mapping>
</web-app>

 <web-app>タグ内で、アプリケーションの定義をします。サーブレットの定義です。

    <servlet>
<servlet-name>HelloRobot</servlet-name>
<servlet-class>com.example.wave.server.HelloRobotService</servlet-class>
</servlet>

 先ほど作成したクラスをパッケージ名も含めて<servlet-class>で指定します。<servlet-name>には、何か分かりやすい名前を付けてください。

 次に、<servlet-mapping>で、先ほど定義したサーブレットをマッピングします。

    <servlet-mapping>
<servlet-name>HelloRobot</servlet-name>
<url-pattern>/_wave/robot/jsonrpc</url-pattern>
</servlet-mapping>

 <servlet-name>には、先ほど<servlet>タグ内で指定したサーブレット名を記述します。

 <url-pattern>は、「/_wave/robot/jsonrpc」とします。Waveは、Robotを利用するとき、URL「http://<アプリケーションID>.appspot.com/_wave/robot/jsonrpc」とJSON形式でやりとりをするのです。

Robotの詳細設定ファイル「capabilities.xml」の編集

 次は、Robotの詳細設定ファイルを書きます。「war/_wave/capabilities.xml」というファイルを作成します。「_wave」ディレクトリはプロジェクト生成時には存在していないので、自分で追加します。

 capabilities.xmlには、どの種類のイベントをハンドルするかといった設定を記述します。

<?xml version="1.0" encoding="utf-8"?>
<w:robot xmlns:w="http://wave.google.com/extensions/robots/1.0">
<w:capabilities>
<w:capability name="WAVELET_PARTICIPANTS_CHANGED" content="true" />
<w:capability name="BLIP_SUBMITTED" content="true" />
</w:capabilities>
<w:profile name="HelloRobot" imageurl="http://helloRobot777.appspot.com/icon.png" />
<w:version>1</w:version>
</w:robot>

 例えば、以下のように記述しておくと、メンバーに変更があったときにprocessEventsメソッドが呼ばれるようになります。

    <w:capability name="WAVELET_PARTICIPANTS_CHANGED" content="true" />

 イベントの種類については、「コード部分の実装」の節の、EventType列挙型のメンバー一覧を参照してください。

 Robotの名前やアイコン、そのほかプロフィールは<w:profile>タグで指定します。

  <w:profile name="HelloRobot" imageurl="http://helloRobot777.appspot.com/icon.png" />

 capabilities.xmlの設定は、バージョン番号を上げない限りキャッシュされます。capabilities.xmlの変更を反映させるときは、バージョン番号をインクリメントする必要があります。

  <w:version>1</w:version>

 ここの数値を増やします。Waveサーバは、Robotを参加させるときに、まずcapabilities.xmlを読み込み、どの種類のイベントが発生したときにRobotとの通信を行うかを把握します。そのとき、このバージョンが以前と同一だった場合は、以前の設定をそのまま使うようになっています。

【Java編】クラウドにデプロイ

 実装が完了したら、次はApp Engineのクラウドにデプロイし、実際にRobotを動かしてみます。プロジェクトを右クリックして[Google]→[Deploy to App Engine]を選ぶか、ツールバーのアイコンをクリックすると、App Engineへデプロイするためのダイアログが出ます。

デプロイするためのダイアログ

 ここに、App Engineへの登録に使用したメールアドレスとログインパスワードを入れます。また、アプリケーションIDを指定する必要があるので、[App Engine project]をクリックし、設定画面を開きます。

App Engine projectの設定

 ここに、アプリケーションID(App EngineのWeb画面で登録したもの)を入れます。ここで、App Engineで使用しているGoogle アカウントのメールアドレスとパスワードを入力し、[Deploy]ボタンをクリックすると、デプロイが行われます。

 デプロイが成功すると、コンソールに「Deployment completed successfully」と表示されます。これで、作成したアプリケーションが利用可能な状態になりました!

デプロイ成功!

1-2-3-4

 INDEX
Google Wave API開発ガイド(後編)
JavaとPythonでGoogle WaveのRobotを作るには
  Page1
Google WaveのRobotをGoogle App Engineに作る
Google App Engineの基本的な使い方
Page2
【Java編】App Engineでの開発準備
【Java編】Robot開発の準備
【Java編】コード部分の実装
【Java編】設定ファイルを書く
【Java編】クラウドにデプロイ
  Page3
【Python編】App Engineの利用準備
【Python編】設定ファイルを書く
【Python編】コード部分の実装
注意 「使用していなかったイベントに対するハンドラを登録したくなった場合」
【Python編】クラウドにデプロイ
  Page4
作成したRobotをWaveに参加させるには
App Engineでのデバッグ
終わりに



リッチクライアント&帳票 全記事一覧へ



HTML5 + UX フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日 月間