-メタXMLイベントの発火

以下の要件をこれからアイディアを示す機能ブロックで満たします。

  • テンプレートパースを行う
  • 実行時のコードジェネレーションとプラグインのモデルの生成を両立させる
  • テンプレートに対してルールベース的な複雑なインジェクション
  • アダプター的に機能追加できるように

テンプレートをNekoHTMLでSAXパースします。このことにより、HTML/XHTMLを透過的に対応できます。
その後、テンプレートのパース過程に発生するSAXイベントにおいて、QNameや属性に応じて簡易なルールベース的にTagSelectorを選択します。TagSelectorはTagProcessorのファクトリになっていて、テンプレートのパースの結果はTagProcessorによるツリー構造になります(S2JSF組み込みのMaya EA1ですでに実装されている構造です)。このTagProcessorツリーはそのままテンプレートの構造といえます。
パース結果としてパーサーはTagProcessorツリーのルートを返します。そのルートのTagProcessor#process()を呼び出すと、processStart()、processChildren()、processEnd()というようにメソッドを実行していきます。TagProcessorインターフェイスの実装に応じて、さまざま動きます。その動きの主なものとは、メタXMLのSAXイベント発火。
void processStart(..., ContentHandler handler);
というようにジャストアイディアでは引数にハンドラをわたすことを考えています(要検討)。このときに、ひとつのハンドラ内で、handler.startElement(...); handler.endElement(...);などのSAXイベント発火を柔軟にやることで、XML構造を変化させることもできますし、同時にJavaでできる細工を施すことができます。
API的にあらかじめスペックを定めたメタXMLになった後は、ContentHandlerでコードジェネレーションのものと、プラグインモデル生成のものとを差し替えられる方法にできます。
TagSelectorおよびTagProcessorの差し替えによって、アダプター的に機能を実装および後の追加ができます。

public interface TagProcessor {
  void processStart(Engine engine, Tag parentTag, ContentHandler handler);
  void processChildren(Engine engine, ContentHandler handler);
  void processEnd(Engine engine, Tag parentTag, ContentHandler handler);
}
public interface TagSelector {
  public boolean isSelectable(String namespaceURI, String localName, 
    String qName, Attributes attributes);
  public TagProcessor getProcessor();
}
public interface TagSelectorManager {
  TagSelector getTagSelector(String namespaceURI, String localName,
    String qName, Attributes attributes);
}

ジャストアイディアですが、こんなことを考えています。インターフェイスはまだ練りこみ悪いです。