「手を抜け」と言っているココロは、できるだけ小さくて単純なモノにしたいから。だけど、リアライザーのコンテキストはほんの少しだけリッチにしたい。その理由は、Xionの一部をXion自体で記述する実験になるから。別な言い方をすると、Xion処理系がXion処理の応用事例になっているようにする。
ファイルを元にしてコンテキストを作る
プログラムコードでコンテキストを自由に作れるけど、やっぱりめんどうなのでファイルを元にコンテクストを作れるといいですね。そのファイルの形式は当然にXion。
形式その1:配列
// タグはコンバータから取得
XionRealizerContext [
JavaClass "foo.bar.PersonConverter",
JavaClass "foo.bar.PersonNameJaConverter"
]
形式その2:オブジェクト
// 指定のタグを使う
XionRealizerContext {
人物 : JavaClass "foo.bar.PersonConverter",
"人名(日本語)" : JavaClass "foo.bar.PersonNameJaConverter"
}
これらの形式では、タグ"XionRealizerContext"と"JavaClass"が出てくる。これらに対応するコンバータを準備すれば、リアライザーによりContextオブジェクトを作れる(自分で自分の機能を使う)。"JavaClass"のコンバータは文字列からClass.forName()で作ったClassオブジェクトを返せばいいでしょう。"XionRealizerContext"のほうは:
public Object convert(Object data) throws XionConvertException {
if (data instanceof XionArray) {
// 形式その1の処理
} else if (data instanceof XionObject) {
// 形式その2の処理
} else {
// だめだこりゃ
}
}
ただし、形式その1の配列内に形式その2のオブジェクトを埋め込めたほうがいいな。
// 一部のタグは指定する
XionRealizerContext [
JavaClass "foo.bar.PersonConverter",
XionRealizerContext {
"人名(日本語)" : JavaClass "foo.bar.PersonNameJaConverter"
}
]
ファイルからコンテキスト内容をロードする
JavaClassコンバータ(タグ"JavaClass"のコンバータ)とXionRealizerContextコンバータを準備して、リアライザーを動かすと、外部ファイルからいきなりContextオブジェクトを作ることもできるわけだが、使い勝手の観点から少し方式を変える。
XionRealizerContextコンバータが作るのは(Contextではなくて)Map<String, Converter>オブジェクトにしておく。それで、Context実装側に次のメソッドを準備するとよさそう。
- loadAdd :ファイルの内容を現コンテキストに追加、上書きはしない。
- loadSet :ファイルの内容を現コンテキストにセット、上書きする。
addとsetの区別は引数にするテもあるが憶えにくいのがイヤだからメソッド名に埋め込んだけど、好みの問題かな。もっとも、ミニマリズム(最小主義)の観点からは、loadSetだけをloadという名前で実装すればいいのかもしれない。