私は、(通常はクライアント固有の) コードによって拡張できるコアコンポーネントで構成される JSF 2 アプリケーションに取り組んでいます。一般的に言えば、アプリケーションの拡張部分はコア部分よりも優先されます。
Java コードの場合、これは従来のメカニズムを使用して行われます。プレゼンテーション レイヤーでは、コアリソースが使用される前にまず拡張jarjavax.faces.view.facelets.ResourceResolver
内のリソースを見つけようとする実装を使用します。
再利用可能なマークアップのために、多くの複合コンポーネントを使用しています。住所、給与などを表示するためのコンポーネントを考えてみてください。
Facelets は、アプリケーションの拡張可能な性質に関して大きな頭痛の種を引き起こしています。私たちが直面している問題の解決策があるかどうか疑問に思い始めています。
私たちが達成したいのは、複合コンポーネントの標準インターフェースを持つことですが、複数の implementationを解決することによって、何らかの方法で実装をオーバーライドします。そのうちの拡張された実装は、コアの実装に先行する必要があります。
もちろん、コアはアプリケーションの標準レイアウト/テンプレートを定義し、拡張機能はクライアント固有の書式設定オプションを定義するか、アプリケーションが実行するマネージド モデルの一部を非表示/表示するという考え方です。
例えば:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pui="http://java.sun.com/jsf/composite/pui">
<cc:interface>
<cc:attribute name="saveButtonLabel" />
<cc:attribute name="saveButtonIcon" />
<cc:attribute name="saveButtonIconPosition" />
</cc:interface>
<cc:implementation>
<pui:pension_plan_custom_state pensionPlanBean="#{pensionPlanBean}" />
<pui:pension_plan_general pensionPlanBean="#{pensionPlanBean}" />
<pui:pension_plan_pension_plan pensionPlanBean="#{pensionPlanBean}" />
<pui:pension_plan_salary pensionPlanBean="#{pensionPlanBean}" />
<pui:pension_plan_investments pensionPlanBean="#{pensionPlanBean}" />
<pui:pension_plan_benefit_types benefitTypes="#{pensionPlanBean.benefitTypesViewData}" />
<div class="buttons">
<!-- Irrelevant -->
</div>
</cc:implementation>
</ui:composition>
pension_plan_benefit_types
複合コンポーネントを例にとってみましょう。そのインターフェースは、名前による属性がbenefitTypes
クライアントによって与えられることを規定しています。クライアントが画面のこの部分だけを標準の実装とは異なるコンテンツで上書きしたい場合は、これをどこかに上書きする場所が必要です。
また、コアは (オプションの)拡張機能が提供する名前空間を認識していないことに注意してください。コンポジットのインターフェースが安定していて、変更を必要としない限り、コアはあまり気にしません。
最後の手段として、以下を試してみました (疑似コード):
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pui="http://java.sun.com/jsf/composite/pui">
<cc:interface>
<cc:attribute name="benefitTypes" required="true" type="com.foo.bar.PensionPlanBenefitTypesViewData" />
</cc:interface>
<cc:implementation>
<ui:include src="/resources/pui/markup/pension_plan_benefit_types_markup.xhtml" />
</cc:implementation>
</ui:composition>
アイデアがどこにあるのか、それがjavax.faces.view.facelets.ResourceResolver
私たちの救助に来るということです。
それは「うまくいく」のですが、複合コンポーネントのために書かなければならない実装によっては、JSF ライフサイクルの悪名高いビルド対レンダリング時間部門であらゆる種類の問題に遭遇します。基本的に、私たちが期待するようには機能しません。
今の大きな問題は次のとおりです。
安定した契約/名前空間と、動的に解決される複数の実装の両方を持つ方法はありますか?
ご意見をお寄せいただきありがとうございます。
敬具、
レンズ