複合コンポーネントまたはタグ コンポーネントをプログラムでインスタンス化したいと考えています。
このインスタンス化はカスタム コンポーネントによって実行され、通常はこれらの複合コンポーネントまたはタグ コンポーネントを子として追加します。
フォーラムをクロールしたときに見つけた最良の答えは、http://www.java.net/node/701640#comment-791881です。このフォーラムで見つけた別の回答によく似ています: How to programmatically or dynamic create a composite component in JSF 2 .
この質問に取り組んでいる間、最終的にMyFaces を使用した複合インスタンス化で機能するコードを書きました (リンクの例は Mojarra 固有のようです)。それを書くのに時間がかかったので、そこにコピーし、他の人の助けになることを願っています:
public UIComponent instantiateComposite(String namespace, String componentName) {
FacesContext ctx = FacesContext.getCurrentInstance();
Resource resource = ctx.getApplication().getResourceHandler().createResource( componentName + ".xhtml", namespace );
UIComponent cc = ctx.getApplication().createComponent( ctx, resource );
UIPanel panel = (UIPanel) ctx.getApplication().createComponent( UIPanel.COMPONENT_TYPE );
// set the facelet's parent
cc.getFacets().put( UIComponent.COMPOSITE_FACET_NAME, panel );
FaceletFactory ff = (DefaultFaceletFactory) DefaultFaceletFactory.getInstance();
if(ff == null) {
FaceletViewDeclarationLanguage vdl = new FaceletViewDeclarationLanguage(ctx);
Method createCompiler = null;
Method createFaceletFactory = null;
try {
createCompiler = FaceletViewDeclarationLanguage.class.getDeclaredMethod("createCompiler",FacesContext.class);
createFaceletFactory = FaceletViewDeclarationLanguage.class.getDeclaredMethod("createFaceletFactory",FacesContext.class,org.apache.myfaces.view.facelets.compiler.Compiler.class);
createCompiler.setAccessible(true);
createFaceletFactory.setAccessible(true);
org.apache.myfaces.view.facelets.compiler.Compiler compiler = (org.apache.myfaces.view.facelets.compiler.Compiler) createCompiler.invoke(vdl, ctx);
ff = (FaceletFactory) createFaceletFactory.invoke(vdl, ctx, compiler);
} catch (IllegalAccessException ex) {
Logger.getLogger(SenatDataTableEntryDetail.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(SenatDataTableEntryDetail.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(SenatDataTableEntryDetail.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(SenatDataTableEntryDetail.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(SenatDataTableEntryDetail.class.getName()).log(Level.SEVERE, null, ex);
}
}
try {
Facelet facelet = ff.getFacelet(resource.getURL());
facelet.apply( ctx, panel );
} catch ( IOException e ) {
e.printStackTrace();
}
return cc;
}
醜い例外処理に注意を払わないでください: これはちょうど netbeans によって自動的に生成されます... 醜いリフレクション ハックを回避する方法があるかどうか、MyFaces 開発者に尋ねます。
タグ components で同じことを行うにはどうすればよいですか。つまり、次のように宣言されたコンポーネントを意味します。
<tag>
<description>blah blah</description>
<tag-name>myWonderfulTag</tag-name>
<source>tags/mwl/myWonderfulTag.xhtml</source>
<!-- attributes -->
</tag>
タグライブラリで。
前もって感謝します。