-JSR252とTapestry4 (7)

UIComponentClassicTagBaseの担う役目は、UIComponentのツリーを構築することです。このロジックはややこしいというか、面白いというか、ベタベタというか。。。
コンポーネントツリーはStateManagerによって管理され、JSF-RIではSessionに保存します。そのため1度目のアクセスと、ボタンクリック等による同一ページへの2度目のアクセスでは動作が異なります。UIViewRootは1度目はViewHandler#createView()によって生成され、2度目はViewHandler#restoreView()によりSessionから戻されます。その際、1度目はUIViewRootの子が空っぽですし、2度目は1度目のアクセスで作成された子コンポーネントがぶら下がっています。しかし、Verbatimはぶらさがっていません。これは、コンポーネントの実装するStateHolder#setTransient(true)にて保存しないことを設定しているためです(UIComponentClassicTagBase#createVerbatim())。1度目は単純にコンポーネントをタグのstartイベント毎に生成してツリーを作っていけばよいのですが、2度目はすでに作って保持されているか、保持されていないかは毎度チェックしないといけません。1度目と2度目でループの回数や分岐などによって描画状況が変わってしまうかもしれないためです。そのためこのへん、念入りにチェックしながらツリーをメンテナンスしてます(さすがに面倒なので詳説は割愛)。「private List createdComponents = null;」と宣言されたリストを操作しているところ(addChild()、removeOldChildren()。特にremoveOldChildren()がベタベタでヤバイ)を読んでみてください。
コンポーネント作るところはループする場合が難しいですね。UIComponentClassicTagBase#doStartTag()の大半がそのためのコードです。