S2Valiを作りながら提供側に必要な技術を学ぶ(3)

なかなか時間が取れないものですね。実装は最低限使える部分までは終わったのですがブログの更新が滞ってました。

ResourceBundle

前回はValidatorResourcesをコンポーネント保有させるところまで行きました。
今日はResourceBundleです。
commons-validatorでは、

        <validator name="required"
                   classname="jp.honestyworks.s2vali.validator.DefaultValidator"
                   method="validateRequired"
                   methodParams="java.lang.Object, org.apache.commons.validator.Field"
                   msg="s2vali.required" />

のように validator毎に msg属性でエラーメッセージを指定できますが、このmsg属性にResourceBundleのkeyを入れておけばResourceBundleから取得したメッセージが使われるようにしたいのです。
またメッセージのArgs(「{0}を入力してください」の{0})も

           <field property="card_id" depends="required,length">
                <arg key="prompt.card_id" />
                <arg key="${var:minlength}" name="length" resource="false" />
                <arg key="${var:maxlength}" name="length" resource="false" />
             ....
           </field>

このように arg要素の key属性でResourceBundleのkeyを指定できます。

ResourceBundleのファイルを定義するdicon

作戦としてはValidatorResourcesと同じように ValidatorResourcesContainerのinitメソッドでResourceBundleを構築して保有しておくというやり方にしました。
まずは、使い手にResourceファイル名を指定してもらう仕組みです。
これは diconファイルにコンポーネントのプロパティとして設定してもらうことにします。

* s2valiConfig.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
    "http://www.seasar.org/dtd/components24.dtd">
<components namespace="s2vali">

    <component name="validatorConfig"
        class="jp.honestyworks.s2vali.ValidatorConfig">
        
        <property name="resourceBundleProperties">
            "testmessage"
        </property>
        
        <property name="validationRules">
            "s2vali-rules.xml"
        </property>
        
    </component>

</components>

ついでに validationRulesファイルも設定可能にしました。

ValidatorResourcesとResourceBundleの連携

validatorResourcesContainerに validatorConfigをinjectして initメソッドで ResourceBundleを取得します。そして、ValidatorResourcesに ResourceBundleを組み込もうと思っていろいろ調べてみたのですが、どうやらなさそうです。
僕のイメージでは ValidatorResourcesのコンストラクタとかに ResourceBundleを渡せばFieldやArgがResourceBundleを保持した形で構築され、
Field.getMsg() とかでResourceBundleから取得されたメッセージがとれるものかと想像していましたが、どうもそのようにはなっていないようです。
SAStrutsStrutsの実装もさらっと見てみたのですが、SAStrutsではCreator(だったか)でResourceBundleを自力でsetしているような。。
仕方がないのでValidationの実行時にResourceBundleを自分で引くような形で実装しました。
これでもまったく問題なさそうです。

実装のことを文章で書くのはなかなか難しいものです。

今日はこのあたりまで。

SVN: http://my.honestyworks.jp/svn/open/s2vali/
Maven2: http://my.honestyworks.jp/maven2/