[mayaa-user:999] builderをカスタマイズしてexec processorを自動挿入したい

Susumu ISHIGAMI [E-MAIL ADDRESS DELETED]
2014年 2月 3日 (月) 15:32:48 JST


石上です

そのまま処理をすると遅くなってしまうテンプレートがあり、
builderを改良してソースコードを解析した上で、
事前にテンプレート定義を書き換えてしまって高速化しようと考えました。

具体的には画面で何回も細切れにlazyローディングなデータのselectを発行してしまって遅いので、
最初にまとめてがっつり取ってきてキャッシュしておきたいという場面があります。
既に実装はほぼできていて、次のような方式で実現しました。

TemplateBuilderImpl
をextendした独自クラスで、
afterBuildをOverrideし、specificationの中身を解析した上で、
動的にscriptを生成し、execプロセッサーを強制的に追加することで、
そのscriptが実行されると適切にキャッシュが作られて
後続の処理が高速化される

ここで、execプロセッサーを動的追加するために以下の様なコードを
書きました。(インデントを見やすくするためタブを全角スペースに変換しています)

static void injectHeaderScript(Specification specification, String script) {
  Template template = (Template) specification;
  QName qName = QNameImpl.getInstance("exec");
  LibraryManager libraryManager = ProviderUtil.getLibraryManager();
  ProcessorDefinition def = libraryManager.getProcessorDefinition(qName);
  SpecificationNodeImpl exec = new SpecificationNodeImpl(qName);
  exec.addAttribute(QNameImpl.getInstance("script"), "${" + script + "}");
  SpecificationNode htmlNode = getHtmlNode(template);
  TemplateProcessor proc = def.createTemplateProcessor(htmlNode, exec);
  if (htmlNode != null) {
    proc.setOriginalNode(htmlNode);
    proc.setInjectedNode(exec);
    template.insertProcessor(0, proc);
  }
}

static SpecificationNode getHtmlNode(NodeTreeWalker current) {
  Specification specification = SpecificationUtil.findSpecification(current);
  for (Iterator<?> it = specification.iterateChildNode(); it.hasNext();) {
    SpecificationNode node = (SpecificationNode) it.next();
    if (node.getQName().getLocalName().toLowerCase().equals("html")) {
      return node;
    }
  }
  return null;
}

よくわかっていないことが、SpecificationNodeとProcessorは一対一に
しなければならないのかということです。

例えば今後このような対応を複数重ねあわせた時、
後発の処理が同じhtmlタグにプロセッサーを上書きしてしまうのでしょうか。
それとも、insertChildNodeで、テンプレートにダミーのタグを追加する方が良いでしょうか?

また、htmlタグを探さずに、単に
  SpecificationNode node = (SpecificationNode) template.getChildNode(0)
  TemplateProcessor proc = def.createTemplateProcessor(node, exec);
としても動きました。
この場合、nodeはDOCTYPEノードになるようです。
このような書き方は問題ありませんでしょうか?

マニアックで申し訳ありませんが、
builderを書き換えてprocessorやnodeを操作できると、面白いことができそうです。


mayaa-user メーリングリストの案内