How to use maru-dog Beanプロパティデータバインドライブラリ (4)
前回はmaru-dogで標準で提供しているコンバータについて説明しました。maru-dogで提供しているコンバータはすべて拡張コンバータと呼ばれる方式で提供されています。
今回はアルファベット文字列を大文字(もしくは小文字)に変換し、指定されたメッセージを連結して結果を返す独自拡張コンバータの作成方法について説明します。
拡張コンバータを作成するにはまず、コンバートを行いたい項目に対して付与するアノテーションを作成します。
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.maru.dog.converter.ConverterIdentifier; @Documented @ConverterIdentifier(ChangeCaseConverter.class) @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ChangeCase { CasePattern casePattern() default CasePattern.UPPER; String addedMessage() default ""; }
コンバータアノテーションには必ず@ConverterIdentifierアノテーションを付与し、実際に変換を行うコンバータクラスを定義してください(上記例ではChangeCaseConverter.class)。アノテーション本体ではcasePattern()で大文字小文字の変換を制御するための列挙型と、addedMessage()で連結する文字列を定義しています。
CasePattern列挙型のコードは以下の通りです。
public enum CasePattern { UPPER, LOWER }
次に実際にコンバート処理を行うChangeCaseConverter.classを定義します。
import org.maru.common.annotation.Identifier; import org.maru.common.annotation.Value; import org.maru.dog.converter.ConverterIdentifier; public class ChangeCaseConverter { @ConverterIdentifier(ChangeCase.class) public String changeCase( @Value String value, @Identifier("casePattern") CasePattern casePattern, @Identifier("addedMessage") String addedMessage) { value += addedMessage; if (casePattern.equals(CasePattern.UPPER)) { return value.toUpperCase(); } else { return value.toLowerCase(); } } }
上記コンバータクラスにはchangeCaseという唯一のメソッドが定義されていますが、このメソッドが@ChangeCaseアノテーションが付与されたプロパティのデータを受け取り変換を行います。当該メソッドにも@ConverterIdentifierアノテーションが付与されています。このアノテーションには先に定義したChangeCaseアノテーションのクラス型が定義されています。
Director内部ではまず入力側のクラスのバインド対象プロパティに@ChangeCaseアノテーションが付与されていると、このアノテーションよりコンバートを行うクラスを@ConverterIdentifier(ChangeCaseConverter.class)より読み取ります。
次にChangeCaseConverterクラスから@ChangeCaseで実行すべきコンバータメソッドを決定します。実行すべきメソッドを識別するための情報が@ConverterIdentifier(ChangeCase.class)です。拡張コンバータではコンバータアノテーションが付与された場合に、そのコンバート処理を行うメソッドに@ConverterIdentifierを付与し、その項目に対象のアノテーションクラスを設定しなければなりません。
コンバータメソッドのパラメータについてですが、変換対象の値を受け取る引数には必ず@Valueを指定する必要があります。コンバータアノテーションより変換処理を行うための深情報を受け取る引数には@Identifierを付与し、受け取るべきアノテーションの項目名をString型で設定しなければなりません。項目名をせってしていない場合はエラーとなります。
上記例では@Valueが付与された引数valueに変換対象データが、@Identifier("casePattern")、@Identifier("addedMessage")が付与された引数casePattern、addedMessageに@ChangeCaseのcasePattern()、addedMessage()の値がそれぞれ渡されてコンバータメソッドが実行され結果が返されます。
返された結果はバインド先の任意の項目にバインドされます。
最後に実行プログラムと実行結果を示します。
import org.maru.dog.Director; import org.maru.dog.Marudog; import org.maru.dog.annotation.Bind; import org.maru.dog.annotation.Bound; public class Main { public static void main(String[] args) { TargetBean tbean = new TargetBean(); InputBean ibean = getInputBean(); Director director = Marudog.getDirector(); director.bind(tbean, ibean); System.out.println(tbean.message); } private static InputBean getInputBean() { InputBean ibean = new InputBean(); ibean.message = "test"; return ibean; } static class TargetBean { @Bound String message; } static class InputBean { @Bind @ChangeCase(addedMessage = "123") String message; } }
上記プログラムの実行結果は"TEST123"です。
InputBeanの小文字の"test"が@ChangeCaseコンバータアノテーションによりcasePatternに従った変換とaddedMessageの"123"という文字列連結が実行され結果がTargetBeanのプロパティにバインドされていることが分かります。
コンバータというと変換処理をイメージしますが、このように、あるデータを任意に加工することも可能です。このような理由から「拡張コンバータ」と名付けました。
最後に拡張コンバータ自体はまだ試行中ですので、定義方法等も含め変更となる可能性があります。(下位互換性がないような変更もあり得るかと・・・)
今回ここまでです。
サイトページ:http://maru.sourceforge.jp/
ドキュメントページ:http://maru.sourceforge.jp/document_dog.html