JSR 188 CC/PP Processing

2003-10-30にJSR 188のFinal Releaseが出た。またSunによるRefernce Implementationも出ているようだ。
http://www.jcp.org/en/jsr/detail?id=188
http://java.sun.com/j2ee/ccpp/

JSR 188はJavaでCC/PPを扱うためのAPIセットを定義している。

CC/PPとはComposite Capability/Preference Profilesの頭文字で、各種端末のハードウェア・ソフトウェア的な能力や、ユーザによる設定情報を記述するXML/RDFの仕様だ。各種端末のハードウェア・ソフトウェア的な能力の違いをサーバサイドあるいはその中間にある何かプロクシなどで吸収することを目的としている。携帯電話などではハードウェア・ソフトウェア的な能力の制約があるので、それに応じたコンテンツを返してあげるために使おうという目的で考えられた。ヨーロッパの携帯電話のWAP仕様から出てきたものだ(と思う)。
http://www.w3.org/Mobile/CCPP/
http://www.ccpp.org/

例えば、携帯電話なら画面の解像度、文字が縦横どのくらい表示できるか(これはユーザ設定によって文字の大きさが大中小などにカスタマイズできることもあるだろう)、表示できる画像の形式はgif/jpeg/pngなどのうち何と何に対応しているか、などという情報になる。これをCC/PPで表現すると例えば以下のようになる。

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:ccpp="http://www.w3.org/2002/11/08-ccpp#"
     xmlns:uaprof="http://www.wapforum.org/profiles/UAPROF/ccppschema-20010430#">
    <Description about="MyDevice">
        <uaprof:component>
            <Description id="HardwarePlatform">
                <uaprof:ScreenSize>240x260</uaprof:ScreenSize>
                <uaprof:ScreenSizeChar>20x10</uaprof:ScreenSizeChar>
            </Description>
        </uaprof:component>
        <uaprof:component>
            <Description id="SoftwarePlatform">
                <uaprof:CcppAccept>
                    <Bag>
                    <li>image/gif</li>
                    <li>image/jpeg</li>
                    <li>text/html</li>
                    <li>*/*</li>
                    </Bag>
                </uaprof:CcppAccept>
            </Description>
        </uaprof:component>
    </Description>
</RDF>

ScreenSizeなど端末の個々の属性にどのような名前を付けるか、その命名した名前のセットをボキャブラリと呼ぶ。名前空間の定義にあるようにCC/PPのボキャブラリとしてはW3Cに存在するものと、wapforumが提案しているものの二つが主要なものになる(と思う)。


JSR 188に話を戻すと、JSR 188はCC/PPを参照するためのAPIで生成するためのものではない。CC/PPを生成するのはJSR 188のAPIを実装する側の処理になる。

JSR 188でCC/PPを参照するには典型的には以下のような手順になるだろう。

  1. JavaのHttpServletでHttpServletRequestを受け取る。
  2. HttpServletRequestを使ってCC/PPを生成する。(JSR 188実装の中ではUser-Agentヘッダなどから判別した端末の情報からCC/PPを生成することになる)
  3. CC/PPを参照する。
  4. 参照した情報に応じた処理を行う。

コードとしてはこんな感じになる。

import javax.ccpp.ProfileFactory;
import javax.ccpp.Profile;
import javax.ccpp.Attribute;
import javax.ccpp.uaprof.Dimension;

public class MyServlet extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response) {
        ProfileFactory factory = ProfileFactory.getInstance();
        Profile profile = factory.newProfile(request);
        
        // ScreenSizeを取得する。
        Attribute screenSize = profile.getAttribute("ScreenSize");
        Dimension dim = (Dimension)screenSize.getValue();
        int height = dim.getHeight();
        int width = dim.getWidth();
        
        // 全ての属性を取得する
        java.util.Set attributes = profile.getAttributes();
        java.util.Iterator it = attributes.iterator();
        while (it.hasNext()) {
            Attribute attribute = (Attribute)it.next();
            Object o = attribute.getValue();
            // 属性ごとに型が異なる
        }
    }
}

CC/PPおよびJSR 188を利用する利点としては以下のようなものが挙げられる。

  • 端末判別処理の抽象化
    • 今までUser-Agentヘッダを見て、"Docomo"と書いてあったらi-mode、などと泥臭い文字列判定を行っていた部分を抽象的に扱うことができる。
    • i-modeauなど各社の携帯電話で送信されるHTTPヘッダに違いがあるが、この部分を吸収することができる。統一的なCC/PPデータを使えば、携帯キャリアの違いを意識することがなくなる(少なくなる)。
  • 既に端末判別処理を持っている場合、それをこの仕様に準じて仕立て直すことで、部品化して再利用することができる。あるいはJSR 188の実装を他社製品、オープンソース プロダクトなどを利用することで開発の効率化を図ることができる。と言ってもまだJSR 188の実装が出てきていないので、これは将来的な話になる。(最初にSunの実装が出たと書いたが、中をちょっと見た限りではヨーロッパのWAP端末への対応がしてあるだけで、日本の携帯電話はサポートされていないようだった。)

もちろんこれに対しては、User-AgentヘッダをString#contains()や正規表現などで判定したほうが簡単でいいじゃないかという意見もあるだろう。しかし、その場合、if文の嵐になる可能性があるし、新しく発売になる新機種への対応にも問題が出てくるかもしれない。
また今後は異なる端末でも共通の処理能力を持つものが多くなってくるかもしれない(i-modeauのどちらもXHTML Basicを扱えるとか)。そうした場合に、端末の処理能力を抽象的に表現したCC/PPが有効になってくる。

関連するオープンソース プロダクトとしてはApache Cocoonがある。CocoonはUser-Agentに応じて、コンテンツ変換を行うXSLTスタイルシートを切り替えるといった機能があり、またHPのMark Butler氏が開発したDELIというCC/PPを扱う部品と連携することもできるようだ。

http://cocoon.apache.org/2.1/developing/deli.html
http://www-uk.hpl.hp.com/people/marbut/