Apache Velocity
汎用テンプレートエンジン。近々、ソースコードジェネレータを作ることになりそうなので調べておこうかな、と思いました。割と前から気になってはいたんですが、なかなか手をつけられずにいたんですよ。
どの辺が汎用かっていうと、データを決める部分はjava.util.Mapに似た構造のクラスで、合成結果の出力先はjava.io.Writerで、テンプレートはスクリプト風の独自テンプレート言語(VTL)で記述するところです。最後のは汎用じゃないように見えますが、独自言語と言っても、既存のスクリプト系言語をベースにしたようなものなので、余程複雑なことをやるのでなければ一瞬で理解できるでしょう。
では練習をしてみます。テキストファイル"test.vm"に次のテンプレートを記述します。
#set($v = "123") name = $name $v #if ($number == 3) three! #else not three. #end #foreach ($i in $list) element = $i #end
実行するJavaのコードはこんな感じで。(このブロック全体は"throws Exception"が必要です。)
Velocity.init(); VelocityContext context = new VelocityContext(); context.put("name", "argius"); context.put("number", new Integer(3)); context.put("list", Arrays.asList(new Object[]{"@", "*"})); Template template = Velocity.getTemplate("test.vm"); PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); template.merge(context, out); out.flush();
"VelocityContext"は、インタフェースとしてはMapのような感じで使えば良いようです。コンストラクタにMapのインスタンスを渡せば、Mapからの変換もできます。"Writer"には、PrintWriterやFileWriterなどの標準クラスが使用できます。最後に、"Template"に、"context"と"Writer"を渡せば合成完了となります。
実行結果です。ここでは標準出力に結果を印字しています。ここでは、PrintWriter#flush()を実行しないと出力されませんので注意。
name = argius 123 three! element = @ element = *
はい、できました。物凄くとっつき易い仕様ですね。例えば、WriterにServletResponse#getWriter()を使えば、サーブレットでJSPの代わりに使えたりします。実際、Velocityを採用しているフレームワークも多いようですね。