目次へ

7. TemplateクラスとVelocityContextクラス

2006.01.12 株式会社四次元データ 里見玲爾

この章ではVelocityの核となるTemplateクラスとVelocityContextクラスについて説明します。ちなみに執筆時のバージョンは1.3.1です。

7.1. org.apache.velocity.Template

Templateクラスはテンプレートの作業すべてを制御するために使うクラスです。

7.1.1. メソッド

Templateクラスでは、次の2つのメソッドが定義されています。

メソッド解説返り値
initDocument()文書を初期化しますvoid
merge(Context context, Writer writer) テンプレートオブジェクトとVelocityContextの値をマージするメソッドで、 マージした結果をWriterクラスのインスタンスに書き込みますvoid

mergeメソッドはVelocityで重要な役割を果たすメソッドです。以下のようにして使用します。

 (略)
 
 try{
     Template template = Velocity.getTemplate("sample.vm");
 
     template.merge(context, sw);
     
 }catch(ResourceNotFoundException e){
     //テンプレートが見つからなかった場合の処理
 }catch(ParseErrorException e){
     //テンプレート内の構文に関する例外などがあったときの処理
 }catch(java.lang.Exception e){
     //その他の例外があったときの処理
 }
 
 (略)

上の例で、mergeメソッドとgetTemplateメソッド(下で解説)は各種例外を投げる可能性があるため、 catchで例外を取得しています。

7.2. org.apache.velocity.VelocityContext

VelocityContextクラスは、テンプレートの変数部分に代入する値を格納するクラスです。 データの蓄積にはHashMapを使用しています。

7.2.1. メソッド

VelocityContextクラスはorg.apache.velocity.contextパッケージのContextインタフェースを実装したAbstractContextクラスのサブクラスで、 このAbstractContextではコンテキストの中身を制御するメソッドが定義されています。

メソッド解説返り値
internalContainsKey(java.lang.Object key)引数のキーの値が存在するかどうか調べる boolean
internalGet(String key)引数のキーと対応するデータの値をオブジェクトで返す java.lang.Object
internalGetKeys()キーの一覧のリストを配列で返すjava.lang.Object[]
internalPut(String key, java.lang.Object value)引数のキーと対応付けて データを格納する。返り値はそのキーで保管されていた以前のオブジェクトjava.lang.Object
internalRemove(java.lang.Object key)引数のキーとそれに対応するデータのペアを削除する。 返り値は削除したオブジェクトjava.lang.Object

またjava.lang.Objectのclone()メソッドでコンテキストオブジェクトのコピーを生成します。

7.2.2. コンテキストのラッピング

VelocityContextにはデフォルトのコンストラクタの他にもオーバーロードされたコンストラクタがいくつかあり、 その中のひとつに、

 VelocityContext(Context context)

の形のコンストラクタがあります。このコンストラクタは他のコンテキストをラッピング(包み込み)するものです。
コンテキストのラッピングとは、コンテキストを別のコンテキストに接続するための仕組みで、よくコンテキストのチェーンとも呼ばれます。 このチェーンの概念はVelocityのコンテキスト設計の画期的な機能で、階層化されたデータアクセスなどに使えます。 次の例により説明します。

 (略)
   VelocityContext context1 = new VelocityContext();
   context1.put("office", "4DD");
   context1.put("description", "This is context1");
   
   VelocityContext context2 = new VelocityContext( context1 );
   context2.put("lang", "Java");
   context2.put("description", "This is context2");
 
   template.merge(context2, writer);
    
 (略)

上の例のようにしてマージされた場合に、テンプレート内ではcontext1とcontext2のどちらに格納されたアイテムにもアクセスできます。 これは当然2つのコンテキストに同一のキーがないということが前提となりますが、上の例では"description"キーが重複しています。 このような場合にテンプレートで$descriptionにアクセスすると外側のコンテキスト、つまり上の例ではcontext2の値"This is context2"が取り出されます。
しかしラッピングをしてcontext2を生成した時点で値が上書きされるわけではなく、 テンプレートがマージされ、レンダリングする前には"This is context1"の値も保持されていますので、 context1.get("description")によってアクセスすることができます。
またテンプレート内から#setなどにより$descriptionにデータを代入しようとする場合、外側のコンテキストだけがその変更の対象となり、 内側のコンテキストにはデータが代入されません。

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp