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

suga [E-MAIL ADDRESS DELETED]
2014年 2月 6日 (木) 20:38:15 JST


suga です。

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

基本的には、SpecificationNode は Processor のインスタンスを作るための指示なので、
通常のビルドプロセス後であれば何かを追加したところで Mayaa 側からは何もしません。(できません)

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

それは「後発の処理」次第ですね。
TemplateBuilder#afterBuild であればそのテンプレートに対する Mayaa の処理は
終わっているので、「複数重ね合わせ」る処理がどうするかです。


> このような書き方は問題ありませんでしょうか?

これも以下同文で、拡張したビルド処理の後にさらに拡張するのであればそれ次第、というところです。

描画時にはビルドの結果出来上がる TemplateImpl が持つ TemplateProcessor のツリーだけを使うので、
そこに破綻がなければ問題ありません。

ただ、元のテンプレートの情報を使うような Processor (echoなど)には
対応する値をセットしておかないと正常に動作しないことがあるでしょう。



おそらく前提が省略されているだけだと思いますが、

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

これだけ読むと Mayaa(一般にはjsp)に渡す前にServletで全部結果をまとめておくのが良いのでは、と思うのですが。
全部のデータを持つのが現実的では無いサイズの場合はキャッシュできないでしょうし。
--
suga ( ko.suga @ gmail.com )


2014-02-03 Susumu ISHIGAMI <susumu.ishigami @ gmail.com>:
> 石上です
>
> そのまま処理をすると遅くなってしまうテンプレートがあり、
> 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 mailing list
> mayaa-user @ ml.seasar.org
> https://ml.seasar.org/mailman/listinfo/mayaa-user


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