MyFaces 1.1.0(tomahawk)をS2JSFで使う (newspaperTable編)

 たまには役に立つことでも書こうということで、MyFaces 1.1.0のtomahawkをS2JSFで使う方法を書いていきたいと思います。
 ここでいうtomahawkとは、北米インディアンの投げても使える戦斧のこと……ではなく、米軍の長距離巡航ミサイルのこと……でもなく、JSFの標準仕様にはない、MyFaces独自の便利な拡張UIコンポーネント群のことです。何はともあれ物騒な名前ですね。
 このtomahawkを利用することにより、簡単に、よりリッチなUIを作成することができます。利用しない手はありません。
 では、すでにS2JSFが使える環境にあるという前提でお話を進めます。ちなみに私は新規作成する場合はS2JSFBlankを愛用させていただいています。
 まずは、MyFaceshttp://myfaces.apache.org/からダウンロードしてきましょう。
 そして、WEB-INF/libMyFaces関連のライブラリを入れます。ここで注意。これを書いている時点での話ですが、myfaces-all.jarは罠です! なんとなく、myfaces-api.jarとmyfaces-impl.jarとtomahawk.jarの合計サイズとmyfaces-all.jarが同じっぽいという理由でmyfaces-all.jarを使うとハマります(っていうかハマった)。myfaces-api.jarとmyfaces-impl.jarとtomahawk.jarを使いましょう。そして、S2JSFに入っているmyfaces.jarは消してしまいましょう。……っと、MyFaces 1.1.0にしてこれまでのS2JSFアプリケーションが完全に動作するかどうかは私は知りませんので、このあたりは自己責任でお願いしますね。
 次に、タグライブラリをjsf.diconに登録します。

    <initMethod name="addTaglibUri">
        <arg>"s"</arg>
        <arg>"http://www.seasar.org/jsf"</arg>
    </initMethod>

↑これの下あたりに↓これを追加します。

        <initMethod name="addTaglibUri">
            <arg>"t"</arg>
            <arg>"http://myfaces.apache.org/tomahawk"</arg>
        </initMethod>
        <initMethod name="addTaglibUri">
            <arg>"wap"</arg>
            <arg>"http://myfaces.apache.org/wap"</arg>
        </initMethod>

以前は、MyFacesの拡張UIのプレフィックスには「x」が使われてましたが、tomahawkという名前がついたので「t」になったようですね。


 さてさて。それでは、今回は、newspaperTableコンポーネントを使ってみましょう。何故今回これを選んだかといいますと、こんな経験はないですか? リストを表示するんだけど、横に3つずつならべて表示したい。なんてこと。こういうとき困るんですよね〜。バッキングビーンで二次元配列に変換してforEachでまわそうか、そうするとビジネスロジックにビューの事情が入り込んで美しくない!ってなるし、ビューのほうでこねこねするのもあまりにバカらしい。そんなときに役にたつのがこのnewspaperTableコンポーネントなのです。
 とりあえず、リストの要素として以下のようなものがあったとします。

package newspaper;

public class NewspaperDto {
    private String name;
    private String value;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

初期化アクションは↓こんな感じです。東北6県の県庁所在地のリストです(^^;

package newspaper;

import java.util.ArrayList;
import java.util.List;

public class NewspaperAction {
    private List dtoList;
    
    public String initialize() {
        ArrayList al = new ArrayList();
        NewspaperDto nd;
        
        nd = new NewspaperDto();
        nd.setName("青森県");
        nd.setValue("青森市");
        al.add(nd);
        
        nd = new NewspaperDto();
        nd.setName("秋田県");
        nd.setValue("秋田市");
        al.add(nd);

        nd = new NewspaperDto();
        nd.setName("岩手県");
        nd.setValue("盛岡市");
        al.add(nd);

        nd = new NewspaperDto();
        nd.setName("宮城県");
        nd.setValue("仙台市");
        al.add(nd);

        nd = new NewspaperDto();
        nd.setName("山形県");
        nd.setValue("山形市");
        al.add(nd);

        nd = new NewspaperDto();
        nd.setName("福島県");
        nd.setValue("福島市");
        al.add(nd);

        dtoList = al;
        
        return null;
    }

    public List getDtoList() {
        return dtoList;
    }
}

初期化アクションをdiconに登録します。サンプルなので、app.diconに直接書いちゃいますね。

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
    "http://www.seasar.org/dtd/components21.dtd">
<components>
    <include path="jsf.dicon"/>
	
    <component name="newspaperAction" class="newspaper.NewspaperAction" />
</components>

それでは注目のHTMLテンプレートです。

<html xmlns:m="http://www.seasar.org/maya" m:action="#{newspaperAction.initialize}">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-31J">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>newspaper</title>
</head>
<body>
  <div m:inject="t:newspaperTable" m:newspaperColumns="3"
    m:value="#{dtoList}" m:var="e">
    この部分はtomahawkを使うためプレビューできません。
    <div m:inject="h:column">
      <span m:value="#{e.name}">県名</span>
    </div>
    <div m:inject="h:column">
      <span m:value="#{e.value}">県庁所在地</span>
    </div>
  </div>
</body>
</html>

私は、HTMLテンプレートをブラウザだけで見たときの挙動も大切にしたいので、「なんじゃこりゃ?」と思われないように「プレビューできません」と書いておいてます。もちろんこの注意書きは、S2JSFを通せば見えません。
 どうでしょうか? S2JSFのforEachコンポーネントに似ているかと思います。m:newspaperColumnsで列数を指定するのですが、うれしいのはh:columnの子タグをひとまとめにして「1つ」と扱っているところです。ちなみに実行結果は以下のようになります。



 それでは次回にもう少し詳しい使い方をやりたいと思います。