-JSR252とTapestry4 (4)

UIComponentClassicTagBase は、JSPのBodyTagです。JSF1.1ではほとんどのタグが非BodyTagだったのですが、JSR252では全部がBodyTagになりました。JSP描画フェーズではJSF-RIタグは実際のアウトプットストリームに出力しませんが、JSTLJSPのテキストボディなどは出力されてしまいます。JSF1.1で有名なタグ追い越し問題など描画の諸問題はこのJSFから制御できないJSP出力にありました。JSF1.1でも全部をJSFのタグにしてしまえば描画の問題は起きません(これがS2JSFの解決方法)。JSR252ではJSF描画フェーズにおいて出力されてしまう非JSF-RIタグの出力を、BodyTagのBodyContentに書き出させ、適宜UIOutput(JSFでは内部で統一的に「verbatim」と読んでます)を作り、JSFコンポーネントツリーに組み込んでしまうのです。その実装も含め激しく力技ですが、なんということでしょう!問題はあとかたもなく解決されてしまうのです。
はじめてみたときには笑ってしまいました。いや、たしかに賢いんですけどね。私にとってはコロンブスの卵系なビックリ解決だったので(私は絶対、バックワードコンパチを捨てて、UIComponent#encodeChildren()を廃止するかと思った)。

verbatim-1
<viewタグ>
  verbatim-2
  <JSF-RIタグ/>
  verbatim-3
</viewタグ>
verbatim-4

上記がJSR252におけるJSP等テンプレートの基本構造です。新MayaFaces(実装中)も同じです。あとはJSF-RIタグがネストする場合を「viewタグ」と「JSF-RIタグ」の関係パターンで置換えて考えて下さい。

  • verbatim-1
    • viewタグ出力以前。
    • viewタグのstartイベントでストリームに書き出し、バッファをクリア。
  • verbatim-2
    • viewタグ(もしくはネストしたJSF-RIの親)のボディで、次の子JSF-RIタグ出現する毎。
    • JSF-RIタグのstartイベントで親のBodyContentを取り出し、UIOutputにして自分の前に追加。親のBodyContentバッファをクリア。
  • verbatim-3
    • viewタグ(もしくはネストしたJSF-RIの親)のボディで、最後のJSF-RIタグの後。
    • viewタグのafterBodyイベントでBodyContentを取り出し、UIOutputにして追加。BodyContentバッファクリア。
  • verbatim-4
    • viewタグの後。
    • encodeAll()のあと、改めてバッファをストリームに書き出す。

描画の基本は以上のとおりです。あとは、facetの理解が必要かな。ま、たいした問題ではないので、適宜見ておいてください。理解が難しいのはJSF-RIタグがイテレートしちゃうときなんですが、それは私もまだ適当にしか理解していません。
次に、UIComponentのツリー構築の話題。こちらは、主に実装の話題ですが、bindingによるコンポーネント指定の方法は、JSFアプリケーション開発時的にどんなもんかはあらかじめ理解しておく必要があるかな。