argius note

プログラミング関連

Apache Velocity (2)

新しい使い方を覚えた! のでメモ。

プロパティ

ひとつは基本中の基本、エンコーディングの指定です。"input.encoding"は、テンプレートを読み込む際の、"output.encoding"はWriterへ出力する際のエンコーディングを指定します。テンプレートに日本語などが書かれている場合は、明示的に"input.encoding"を指定する必要があります。
もうひとつは、テンプレートファイルを読み込む時などに、読み込む方法を指定します。通常はファイルシステムから読み込みますが、クラスパスから読み込みたい場合は、下記の例のように"resource.loader"と"*.resource.loader.class"を指定します。

Properties props = new Properties();
props.setProperty("resource.loader", "CLASSPATH");
props.setProperty("CLASSPATH.resource.loader.class",
                  "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
props.setProperty("input.encoding", "Shift_JIS");
//props.setProperty("output.encoding", "UTF-8");
Velocity.init(props);
// 続く

配列・メソッド呼び出し

続きまして、配列の扱いと変数のメソッド実行結果を反映させる方法です。これは重宝しました。
まず、"words"には、スペース区切り文字列をsplitして文字列の配列にしています。前回の例ではわざわざListに変換していますが、配列やCollectionなら自動的に解釈してくれます。この例で言うと、splitの結果の代わりにpropsを設定するとどうなるかを試してみると分かり易いかも知れません。

// 続き
VelocityContext context = new VelocityContext();
context.put("words", "Look and Feel".split(" "));
context.put("buffer", new StringBuffer("12345"));
Template template = Velocity.getTemplate("test/test2.template");
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
template.merge(context, out);
out.flush();

あと、前述の"resource.loader"については、クラスパスの相対位置("test/test2.template")から読み込んでいます。
test2.templateの内容はこんな感じです。

あいうえお

#foreach ($word in $words)
$word
  length : $word.length()
  upper  : $word.toUpperCase()
  lower  : $word.toLowerCase()
#end

$buffer.reverse()

変数の後ろにメソッドを記述すると、そのメソッドの実行結果が反映されます。存在しないメソッドを呼び出した場合は無視されます(変数表記のまま)。
結果は以下の通り。特に、"buffer"のreverseの結果をご覧ください。

あいうえお

Look
  length : 4
  upper  : LOOK
  lower  : look
and
  length : 3
  upper  : AND
  lower  : and
Feel
  length : 4
  upper  : FEEL
  lower  : feel

54321