目次


Groovy によるソーシャル・マッシュアップ

Groovy、Twitter、Google、そしてほんの少しの Ajax を組み合わせることで、ソーシャル・ネットワークに対応できます

Comments

最近、Web でのソーシャル・ネットワーキングが絶大な人気を集めています。Twitter、Facebook、LinkedIn などのアプリケーションの人気が急上昇しているということは、似たような考えを持つ人たちと繋がりを持ちたいという人間の本能を証明しています。一方、最近大流行しているものと言えば、オープン・アプリケーション・インターフェースも同じです。Google と Twitter はその顕著な例で、世界中の開発者たちに広く公開されて注目されており、これらを利用したさまざまなアイディアが開発者たちから出されています。この 2 つのプラットフォームはこれらのアプリケーションが持つデータを照会するための API、そして事実上思い付く限りのあらゆるアプリケーションに統合するための API を提供しています。

マッシュアップは Web 2.0 の真髄を表すアプリケーションです。マッシュアップは文字通り、一見関連性のない複数のアプリケーションを、裏でシームレスに切り替えて連動させる 1 つのエンティティーとして機能させます。マッシュアップ・コミュニティーに参加しようと張り合うエンティティーは大抵の場合、RESTful な原則 (「参考文献」を参照) に基づいたオープン API を提供しています。これが、思ったよりも簡単にマッシュアップを作成できる理由です。

最近人気を集めているマッシュアップの候補には、Google マップが挙げられます。Google マップは本質的には JavaScript ライブラリーであり、アプリケーションに場所の概念を追加します。Google マップに場所の情報を (住所または座標の形式で) 提供することで、該当する場所を視覚的に表すマップを作成することができます。Google のオンライン地図アプリケーション (例えば、運転のルートを調べるためなど) を今まで使ったことがあるならば、Google マップの動作はすでに目にしていることになります。

Twitter は、よく使われているソーシャル・ネットワーキング・アプリケーションです。Twitter ではユーザーが、あらゆる話題について簡単な近況 (「つぶやき」と呼ばれます) をフォロワーのネットワークに送信できます (Twitter では、「友達」とは自分がフォローする Twitter ユーザーのことで、「フォロワー」とは自分をフォローする Twitter ユーザーのことです)。こうした機能はよく、マイクロ・ブロギングと呼ばれています。Twitter の API に対しては、特定の基準と一致するつぶやき (例えば Java™ プログラミングに関するつぶやきなど) や、特定のユーザーの友達やフォロワーの名前など、Twitter のデータが持つさまざまな側面を照会することができます。それに加え、Twitter ユーザーにはユーザーの現在地を提供するオプションが用意されていることから、Twitter は現在地の情報も保存します。

Twitter は現在地情報を公開することから、Twitter を Google マップと組み合わせれば、ユーザーが特定の場所を中心にして Twitter を表示できるマッシュアップを作成することができます。これが、この記事で説明するマッシュアップです。この記事では、Twitter ユーザーが Twitter の友達のマップ、つまり世界に散らばる Twitter の友達のネットワークを Google マップ上に表示する単純なアプリケーションを作成します。作成手順は以下の 3 つのステップからなります。

  1. Java ベースのサード・パーティー・ライブラリーを使用して Twitter と連携します。
  2. Google マップを使用してマップを実装します。
  3. Groovlet と多少の Ajax を使用して、Groovy ですべてが連動するようにします。

この記事では、ご使用のシステムに Groovy がインストール済みであることを前提とします。その他に必要となるツールについては、説明の中でその都度、紹介します。

Twitter の準備

Twitter の広範な API は、実に多くの機能をサポートします (「参考文献」を参照)。この API を使って、現在地やキーワードを基準につぶやきを検索することも、Twitter ユーザーの友達やフォロワーのリストを取得することも、さらにはリスト内のそれぞれの友達やフォロワーのつぶやきを表示することもできます。Twitter の API は完全に RESTful なので、この API が公開する一連の URI (Uniform Resource Identifier) は機能にマッピングされています。

また Twitter の API は一般に公開されているため、多くの開発者によって Twitter の操作を容易にするライブラリーが作成されています。この記事ではそのなかから、Twitter API をラップする Java ベースのライブラリー、Twitter4J を使用します。記事の手順に従うには、twitter4j-1.1.4.zip をダウンロードして、twitter4j-1.1.4.jar をクラス・パスに追加してください。Twitter4J、そして Twitter そのものを利用するには、Twitter にアカウントを作成する必要があります。アカウントを作成したら、世界の Twitter 友達ネットワーク・マップを作成できるように自分がフォローしたい Twitter ユーザーを見つけてください。

Twitter4J の動作

Twitter4J ライブラリーの中心となるインターフェースは、Twitter オブジェクトです。Twitter ネットワークに接続するには、提供された Twitter アカウントのユーザー名とパスワードを使って新規 Twitter オブジェクトをインスタンス化します。リスト 1 (easyb を使用) では、ユーザー名 johndoe、パスワード 5555 を使用してオブジェクトをインスタンス化しています。

リスト 1. Twitter4J を使用した Twitter への接続
scenario "Exploring Twitter4J's login functionality'", {
 given "an instance of Twitter4J", {
  twitter = new Twitter("johndoe", "5555")
 }
 then "the test method should return true indicating things are working", {
  twitter.test().shouldBe true
 }
}

セッションが有効になったら、早速 Twitter インスタンスに対して興味のある情報を照会することができます (さらに、更新することも可能です)。例えば、アカウントの友達 (つまり、その Twitter アカウントがフォローする Twitter ユーザー) のリストを取得するには getFriends を呼び出します (リスト 2 を参照)。このメソッドが返すのは、User オブジェクトのリストです。リストに含まれるそれぞれのオブジェクトが、有効な Twitter アカウントを表します。

リスト 2. easyb を使用した Twitter4J による友達リストの取得
scenario "Twitter4J should support finding a user's network of friends", {
 given "an instance of Twitter4J", {
  twitter = new Twitter("johndoe", "5555")
 }
 then "the getFriends method should return a collection of users", {
  twitter.getFriends().size().shouldBeGreaterThan 0
 }
}

見てのとおり、Twitter4J の API は極めて単純で直観的です。

リストを取得した後は、getLocation メソッドによって特定のユーザーの現在地を突き止めることができます。この現在地情報は、例えば Denver, Colorado (コロラド州デンバー)、あるいは単に Virginia (バージニア州) といった単純な名前です。さらに現在地の他にも、興味のある情報を検索することができます。例えば、Twitter ユーザーのプロフィール画像 (getProfileImageURL 呼び出しを使用)、ユーザーの名前 (該当するユーザー名を設定した getName メソッドを使用)、ユーザー名、そして Twitter ユーザーがオプションで提供できる自己紹介 (getDescription メソッドを使用) などです。

実際、興味深いマッシュアップを作成するには、友達のリスト、現在地、プロフィール画像、そしてそのユーザーに関連付けられた自己紹介があれば十分です。これから、この情報を Google マップに組み合わせて、世界の Twitter 友達ネットワーク・マップを表示します。

Google マップのセットアップ

Google マップに取り掛かる方法は至って単純です。まずは、API キーを取得してください。このキーは無料ですが、特定の URL にバインドされるため、この記事のアプリケーション用に API を生成する場合には少々先見の明が必要です。説明すると、このアプリケーションは Web アプリケーションなのでサーブレット・コンテナー (Tomcat など) を利用します。このコンテナーには (開発中に) コンテキスト名 (geotweet など) を指定するため、Google マップの API キーに関連付けなければならない URL は localhost:8080/geotweet となります。このキーは、開発中にしか使用できません。完成したコードを (URL が acmecorp.biz/geotweet のような) 本番環境に移すことにした場合には、別のキーを生成する必要があります。

ユーザーがキーを生成すると、Google は親切にも作業の出発点となるソース・コードを提供してくれます。このコードを HTML ファイルにコピーすれば、準備完了です。一例として、この記事の出発点となる index.html をリスト 3 に記載します。

リスト 3. Google から提供された出発点となるコード
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Geotweet!</title>
    <script src="//maps.google.com/maps?file=api&v=2&key=YOURKEY"
      type="text/javascript"></script>
    <script type="text/javascript">

    //<![CDATA[

    function load() {
      if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById("map"));
        map.setCenter(new GLatLng(37.4419, -122.1419), 13);
      }
    }

    //]]>
    </script>
  </head>
  <body onload="load()" onunload="GUnload()">
    <div id="map" style="width:800px;height:500px"></div>
  </body>
</html>

前述のとおり、Google マップは JavaScript ライブラリーです。したがって、2 つのイベントを認識する必要があります。1 つはページのロード、そしてもう 1 つは、ページがロードされた後のマップの操作です。ページをロードするのは、実質的に Google マップを初期化し、その結果としてマップを表示する時点です。リスト 4 の HTML <body> 要素に onload 属性があるのはそのためで、ここで loadMap JavaScript 関数を呼び出すことによって、Google マップのインスタンスがロードされます。

リスト 4. ページをロードする時点でのマップのロード
<body onload="loadMap()" onunload="GUnload()">

loadMap 関数 (リスト 5 を参照) は、<body> 要素の上にある <script> セクションで定義します。

リスト 5. loadMap JavaScript 関数
 <script type="text/javascript">

        //<![CDATA[

        var map;

        function loadMap() {
            if (GBrowserIsCompatible()) {
                map = new GMap2(document.getElementById("containermap"));
                map.setCenter(new GLatLng(38.8920910, -77.0240550), 2);
                map.addControl(new GLargeMapControl());
            }
        }
 //]]>

</script>

マップをロードした後に、そのマップを操作する場合もあります。その一例は、マーカーの追加です。この場合、最初にマップのハンドルを取得してから、マップ上の座標を取得する API を呼び出す必要があります。そのため上記のリスト 5 では、関数の外部で map 変数を定義してあります。

ブラウザーがマップをロードした後には、当然それを表示しなければならないため、リスト 6 の <div> タグを定義します。

リスト 6. Google マップを保持する単純な <div> タグ
<div id="containermap"></div>

リスト 7 に、<div> タグのスタイルを設定する単純な CSS (Cascading Style Sheet) を記載します。この CSS によって、マップは少し右にシフトします。このようにする理由は、ユーザーが適切な Twitter 情報を入力できるように、マップの左側に単純な <form> を追加しようと思っているからです。

リスト 7. マップの位置を調整する単純な CSS
#containermap {
    position: absolute;
    margin: 5px 0px 0px 210px;
    height: 650px;
    width: 1000px;
}

この時点で、index.html ファイルは表示できるようになっています。このファイルをサーブレット・コンテナーにデプロイするなどの必要はなく、ファイルをブラウザーで開くだけで、図 1 のようなマップが表示されるはずです。

図 1. ブラウザーで開いた初期マップ
ブラウザーで開いた初期マップ
ブラウザーで開いた初期マップ

次に、マップの左側に単純で小さな <form> を追加します。このフォームが持つ 2 つのフィールドは、前に説明した Twitter4J ライブラリーを使用するための条件に直接関係します。つまり、何かしらの興味深い操作を行うためには、ユーザー名とパスワードを使って Twitter アカウントにログインしなければなりません。そこで、リスト 8 で追加する <form> には、ユーザー名とパスワードのフィールドが含まれているというわけです。

リスト 8. 情報を取得するための単純なフォーム
<div id="container">
 <div class="form">
  <form action="" name="twitter">
   <p><label>twitter id:</label><input class="name" type="text" size="12"
       id="name" name="name" value=""/></p>
   <p><label>password:</label><input class="pword" type="password" size="12"
     id="pword" name="pword" value=""/></p>

   <div class="buttnz">
    <a href="javascript: doSubmit();">Map my friends!</a>
   </div>
  </form>
 </div>
</div>

このフォームをコーディングすると、図 2 のようにページが多少整ってきます。

図 2. データ入力フォームを備えたマップ
データ入力フォームを備えたマップ
データ入力フォームを備えたマップ

ここからは、いよいよ肉付けしていく段階に入ります。まずは Twitter アカウントの友達をマップ上に配置するための機能から取り掛かります。この作業はそれほど厄介なものではありませんが、さらに 2 つの技術が必要になってきます。それは、サーバー・サイドの処理と多少の Ajax です。

Groovy で仕上げるサーバー・サイドの処理

Twitter4J ライブラリーは、結局は Java コードなので、Web ページの中で有効に実行させることはできません。ここで必要なのは、アプリケーションを仕上げるためのサーバー・サイドの処理です。そこで、これから Groovy の軽量フレームワーク、Groovlet を使います。Groovlet はサーブレットの構造を持たない単なるサーブレットです。これはつまり、単純な Groovy スクリプトを作成して、サーブレットのコンテキスト内でそのスクリプトを実行できるということです。作成するスクリプトは、サーブレットをコーディングするときに開発者が愛用するようになってきた通常のオブジェクトにアクセスします。このようなオブジェクトの例をいくつか挙げると、ServletRequestServletResponseServletContext などがあります。

Groovlet を使用するための準備は、これ以上簡単にできないほど簡単です。その手順は、web.xml ファイルにマッピングを追加し、Groovy インストール・ディレクトリーにある groovy-all-1.5.7.jar ファイルを Web アプリケーションの WEB-INF/lib ディレクトリーに追加するだけです。これで早速、使い始めることができます。

例えばリスト 9 に示す私の web.xml ファイルでは、2 つの要素が .groovy で終わるリクエストを Groovy の GroovyServlet にマッピングして、Groovlet のマジックを行います。

リスト 9. Groovlet の追加 (web.xml ファイルにいくつかフィールドを追加するだけです)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!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>
  <servlet>
      <servlet-name>GroovyServlet</servlet-name>
      <servlet-class>groovy.servlet.GroovyServlet</servlet-class>
  </servlet>
  <servlet-mapping>
        <servlet-name>GroovyServlet</servlet-name>
        <url-pattern>*.groovy</url-pattern>
   </servlet-mapping>
</web-app>

上記のコードによって、.groovy URI を宛先とするすべてのリクエストが GroovyServlet を呼び出し、このサーブレットが要求されたリソースを取得して、そのリソースを実行するようになりました。このように、Groovlet の最大の利点は単純なスクリプトであることです。

マッシュアップへの対応

Groovlet のコーディングに取り掛かる前に、2 つの重要な問題について検討しておかなければなりません。まず 1 つは、Twitter から必要なすべてのデータを取得する最善の方法です。もちろんデータの取得方法はわかりますが、この方法は何度か使用することになると思うので、Twitter 固有のロジックを 1 つのサービスとしてローカライズしておくと有効です。サービスと言っても、ここで言っているサービスは特定の振る舞いを抽象化する単純なクラスに過ぎないので、ご心配には及びません。例えばリスト 10 を見るとわかるように、私の TwitterService は至って単純です。

リスト 10. Twitter4J ライブラリーを使用するための単純なサービス
import twitter4j.Twitter

public class TwitterService {

 def getFriendsForTwitterer(username, password) {
  def twitter = getTwitter(password, username)
  return twitter.getFriends()
 }

 private def getTwitter(password, username) {
  return new Twitter(username, password)
 }

 def getLocationForUser(username, password) {
  def twitter = getTwitter(password, username)
  return twitter.getAuthenticatedUser().getLocation()
 }
}

2 つ目の問題は、もう少し考えさせられるものです。Google マップは座標、つまり地球上にあるあらゆるものを正確な位置で示す緯度と経度の数値を扱いますが、例えばワシントン D.C. についての知識を実際に持っているわけではありません。わかっているのは、緯度が 38.8920910 で経度が -77.0240550 であるということだけです。その一方で Google では、論理名と座標とのマッピングを行う独自のサービスを提供しています。ジオコーディングてして知られるこのサービスは、場所とその他のパラメーターを URL に指定すると、要求された場所に対応する座標を返す単純なサービスです。

例えば URL が http://maps.google.com/maps/geo?q=washington+DC&output=xml&key=YOUR_KEY だとすると、リスト 11 に記載するような XML 文書が返されます。

リスト 11. Google のジオコーディングによるレスポンス
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
 <Response>
  <name>washington DC</name>
  <Status>
   <code>200</code>
   <request>geocode</request>
  </Status>
 <Placemark id="p1">
  <address>Washington, DC, USA</address>
  <AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
   <Country>
     <CountryNameCode>US</CountryNameCode>
 <CountryName>USA</CountryName>
 <AdministrativeArea>
  <AdministrativeAreaName>DC</AdministrativeAreaName>
  <Locality>
   <LocalityName>Washington</LocalityName>
  </Locality>
 </AdministrativeArea>
    </Country>
   </AddressDetails>
   <ExtendedData>
    <LatLonBox north=
        "38.9951100" south="38.7915140" east="-76.9093960" west="-77.1199010"/>
   </ExtendedData>
   <Point>
     <coordinates>-77.0240550,38.8920910,0</coordinates>
   </Point>
  </Placemark>
 </Response>
</kml>

したがって、Twitter から提供される現在地情報のストリングを受け取り、座標を返すサービスをコーディングすればよいことになりますが、Twitter アカウントの現在地情報はオプションであることから、このサービスは多少複雑になります。つまり、ユーザーにとって現在地情報の入力は必須ではないため、Twitter では現在地情報の検証を行いません。そのためアカウントが実際に String 値を提供したとしても、その値が無効であったり、Google がその値に対して複数の座標を返したりする可能性が考えられます。さらにユーザーによっては、現在地情報をユーザーの現在地の座標で頻繁に更新する特殊なアプリケーション (携帯電話上の Twitter クライアントなど) を使っている場合もあります。そのため、GoogleMapsService では座標を返す前に、ちょっとしたクリーンアップを行います (リスト 12 を参照)。

リスト 12. Google ジオコーディング・サービスの使用
package org.disco.geotweet.service

public class GoogleMapsService {

 private static String KEY = "YOUR_KEY"

 def getLocationCoordinates(location) {
  if (location.contains("iPhone:")) {
   //iPhone: 39.035248,-77.138687
   def iloc = location.replace("iPhone: ", "")
   def scoords = iloc.split(",")
   return [latitude: scoords[0], longitude: scoords[1]]
  } else {
   def encdLoc = URLEncoder.encode(location)
   def response =
      "http://maps.google.com/maps/geo?" +
     "q=${encdLoc}&output=xml&key=${KEY}".toURL().getText()
   def root = new XmlSlurper().parseText(response)
   if (root.Response.Placemark.size() == 1) {
    def coords = root.Response.Placemark.Point.coordinates.text()
    def scoords = coords.split(",")
    if (scoords.size() > 1) {
     return [latitude: scoords[1], longitude: scoords[0]]
    } else {
     return [:]
    }
   } else {
    return [:]
   }
  }
 }
}

リスト 12 を見るとわかるように、ブランクの値に対する複数のチェックを行うコードを作成する必要がありますが、Groovy の XmlSlurper を使用することで、Google の XML レスポンスはいとも簡単に構文解析することができます。

2 つのサービスをコーディングしたところで、次は Groovlet を使ってすべてをリンクさせます。何よりもまず妥当な作業は、Twitter アカウント自体の現在地情報を基にしてマップをセンタリングすることです。リスト 13 で、力仕事の部分を任せるために上記でコーディングした 2 つのサービスを使用して、Twitter アカウントのユーザー名とパスワードを 2 つのパラメーターとして取り、そのアカウントの座標を JSON (JavaScript Object Notation) で表現して返す Groovlet を作成します。

リスト 13. Twitter アカウントでの Google マップのセンタリング
import net.sf.json.JSONObject
import org.disco.geotweet.service.GoogleMapsService
import org.disco.geotweet.service.TwitterService

def name = request.getParameter('username')
def pword = request.getParameter('password')

def coordinates = getJSONLatAndLng(name, pword)

println coordinates

def getJSONLatAndLng(name, password) {
 def googleMapsSevice = new GoogleMapsService()
 def twitterService = new TwitterService()
 def loc = twitterService.getLocationForUser(name, password)
 def coords = googleMapsSevice.getLocationCoordinates(loc)
 return this.getJSONForCoords(coords)
}

def getJSONForCoords(coords) {
  return new JSONObject().element("latitude", coords.latitude)
    .element("longitude", coords.longitude)
}

リスト 13 を見るとわかるように、この Groovlet はかなり単純なものです。Groovlet が request オブジェクトに暗黙的にアクセスすること、そしてレスポンスを返すには println を使用するだけで十分なことに注目してください。

最後に必要なのは、大幅に量が増えているだけで基本的には同じ情報を返すための手段です。つまり、Twitter ユーザーの友達の現在地情報を JSON フォーマットで返す必要があります。JSON レスポンスには、ユーザーの画像への URL、名前、そして自己紹介が含まれることになるので、この情報を Google マップのインスタンスに配置すれば、マーカーをもっと面白いものにすることができます。しかし、まずはマップを改良する前に、まずは友達用の Groovlet をコーディングする必要があります (リスト 14 を参照)。

リスト 14. 友達のリストを作成する Groovlet
import net.sf.json.JSONArray
import net.sf.json.JSONObject
import org.disco.geotweet.service.GoogleMapsService
import org.disco.geotweet.service.TwitterService

def name = request.getParameter('username')
def pword = request.getParameter('password')

def output = getJSONFriends(name, pword)

println output

def getJSONFriends(name, password) {
 def friends = getTwitterFriends(name, password)
 def output = new JSONObject().element("friends", new JSONArray())
 def gservice = new GoogleMapsService()
 friends.each {
  def location = it.getLocation()
  def pictureURL = it.getProfileImageURL().toString()
  def bio = it.getDescription()
  def tname = it.getName()
  if (location.size() > 0) {
   def profile = gservice.getLocationCoordinates(location)
   profile.pic = pictureURL
   profile.bio = bio
   profile.name = tname
   if (profile.size() > 0) {
    output.accumulate("friends", profile)
   }
 }
}

return output.toString() //JSON format
}


private def getTwitterFriends(name, password) {
 def service = new TwitterService()
 return service.getFriendsForTwitterer(name, password)
}

上記のリスト 14 では GoogleMapsService を (TwitterService と併せて) 利用して、Twitter アカウントの友達それぞれの座標が含まれるマップ (profile 変数) を取得します。このマップに (profile.pic = pictureURL によって) 追加される情報が、最終的には JSON フォーマットに設定されてブラウザーに返されます。

以上の 2 つの Groovlet、そして Twitter と Google マップのロジックの両方を処理する 2 つのサービスで、サーバー・サイドのマッシュアップは完成です。

スムーズな UI のための Ajax の利用

すべてを連動させるための最後のステップは、2 つの Groovlet を呼び出し、それによってページ上の Google マップを更新するためにほんの少し JavaScript を使用することです。

アプリケーションの index.html ページ左側にある 2 つのフィールドを持つフォームは、ユーザーが「Map my friends」リンクをクリックすると doSubmit メソッドを呼び出します。この関数は力仕事が行われる場所なので、これから Ajax を使用して、Web ページを非同期で更新できるようにします。こうすることで、ページのリロードが必要のないシームレスなユーザー・エクスペリエンスが実現します。

ここで利用する jQuery は、JavaScript で巧妙な UI を作成するための豊富な機能を揃えた JavaScript ライブラリーです。この重宝なフレームワークには、Ajax 用の優れた API があります。例えば、jQuery の getJSON を呼び出すだけで、Twitter アカウント自体の現在地情報で簡単にマップをセンタリングすることができます (リスト 15 を参照)。

リスト 15. jQuery の getJSON 関数の使用
function doSubmit() {
 var tid = document.twitter.name.value;
 var pwrd = document.twitter.pword.value;

 $.getJSON("locatetwitterer.groovy", {"username": tid, "password":pwrd}, function(json) {
  if(json.length > 0){
   map.setCenter(new GLatLng(json.latitude, json.longitude), 2);
  }
 });
}

リスト 15 の jQuery の getJSON 関数は少々奇異に見えるかもしれませんが、いったん内容を理解すれば、後は簡単に使用することができます。

  • 最初のパラメーターは、呼び出す対象の URL です。上記の例で呼び出しているのは locatetwitterer.groovy で、このファイルは Web アプリケーションのルート・ディレクトリーにあります。
  • 次にこの関数が取るのはパラメーターのマッピングです。したがって、tid 変数 (Twitter の名前を保持) は username パラメーターと関連付けられ、同じく pwrd 変数もマッピングされます。
  • 最後のパラメーターは、いわゆるコールバックです。つまり、locatetwitterer.groovy に対して行ったリクエストへのレスポンスを受け取ると、このコールバックに定義された関数が呼び出され、JSON レスポンスの長さがチェックされます。レスポンスにデータが含まれていれば、そこから latitude 属性と longitude 属性の値が取得されて Google マップの GLatLng オブジェクト (場所を表します) に渡され、これらの値に応じてマップがセンタリングされます。

友達を追加!

次に (そして最後に) 必要な作業は、センタリングされたマップにマーカーを追加して友達を表すことです。ここでも jQuery の getJSON 呼び出しを使いますが、今回は、コールバック関数の役割がもう少し大きくなります。リスト 16 で追加しているのは、HTML が含まれる Google マップのマーカーに対するリスナーです。ユーザーがマーカーをクリックすると、選択された友達のアイコン、名前、自己紹介が含まれる小さなウィンドウがポップアップ表示されます。

リスト 16. 非同期に行うマップのデータの設定
$.getJSON("locatefriends.groovy", {"username": tid, "password":pwrd}, function(json) {
 $.each(json.friends, function(i, item) {
  var marker = new GMarker(new GLatLng(item.latitude, item.longitude));
  map.addOverlay(marker)
  var picture = "<img src=\"" + item.pic + "\"/> " + item.name + "<br/>" + item.bio

  GEvent.addListener(marker, "click", function() {
   marker.openInfoWindowHtml(picture);
  });
 });
});

ご覧のように、リスト 16 で doSubmit 関数に追加された内容は多少複雑になっていますが、それでも理解するのは簡単です。まず、コールバック内では jQuery の each 関数が、受け取った JSON レスポンスに含まれる友達の集合を繰り返し処理します。この関数にもコールバックがあるため、繰り返し処理のたびに、収集されたデータにロジックが適用されます。前と同様、新しい GLatLng オブジェクトが作成され、GMarker がマップ・インスタンスの上に重ねられます (これによって、Google マップ上に赤いドットのようなアイコンが表示されます)。友達の場所を示すマーカーが追加されたマップは、図3 のようになります。

図 3. 友達の場所を表す Google マップ
友達の場所を表す Google マップ
友達の場所を表す Google マップ

図 4 に示しているのは、友達の画像、そして名前と自己紹介 (提供されている場合) を表すテキストを表示するポップアップ・ウィンドウです。

図 4. ドットをクリックすると表示される追加情報
ドットをクリックすると表示される追加情報
ドットをクリックすると表示される追加情報

マッシュアップは簡単です

ご覧のように、ある程度の先見の明と少しばかりの努力で、Twitter と Google マップを組み合わせたソーシャル・マッシュアップは簡単にアセンブルできます。さらに Groovy とわずかな Ajax を追加することで、作業は尚更簡単になります。ここから先にはもちろん、さまざまな可能性が考えられます。この記事では、エラーの処理をはじめ、使用できる機能をほんの少しかじっただけに過ぎませんが、重要な点は常に同じで、オープン API とわずかな想像力があれば、まったく新しいアプリケーションの世界が開け、その可能性が広がるということです。これをどう利用するかは、皆さん次第です。


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


関連トピック

  • Twitter API ウィキ: Twitter からのデータを利用する方法を説明している公式ガイドです。
  • Google Maps API Reference: Google マップのオブジェクトについて詳細を調べてください。
  • JSON と Ajax による非同期 Grails」(Scott Davis 著、developerWorks、2008年11月): Groovy ベースの Grails Web フレームワークを使用して、Google Maps API を利用したマッシュアップを構築してください。
  • jQuery を使って Ajax 開発を単純化する」(Jesse Skinner 著、developerWorks、2007年4月): jQuery の機能と関数について調べてください。
  • JSON を使用したデータ転送」(Brett McLaughlin 著、developerWorks、2007年3月): JSON の詳細、そして JSON によってアプリケーションでのデータとオブジェクトの移動が容易になる仕組みを学んでください。
  • developerWorks Java technology ゾーン: Java プログラミングのあらゆる側面を網羅した記事が豊富に用意されています。
  • Twitter4J: この Java ライブラリーを使ってアプリケーションに Twitter サービスを統合できます。
  • jQuery: jQuery JavaScript ライブラリーをダウンロードしてください。
  • JSON-lib: JSON をプログラムで作成および構文解析するには、JSON-lib をダウンロードしてください。

コメント

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology
ArticleID=377812
ArticleTitle=Groovy によるソーシャル・マッシュアップ
publish-date=02242009