2013-04-04 10 views
5

複合コンポーネントまたはタグコンポーネントをプログラムでインスタンス化したいとします。コンポジットコンポーネントまたはタグコンポーネントをプログラムでインスタンス化する方法は?

このインスタンス化はカスタムコンポーネントによって実行され、通常、それらのコンポジットまたはタグコンポーネントを子として追加します。

フォーラムをクロールするときに私が見つけた最も良い答えはhttp://www.java.net/node/701640#comment-791881です。このフォーラムで見つけた別の回答とよく似ています:How to programmatically or dynamically create a composite component in JSF 2

この質問に取り組んでいる間、私は最終的にのために働くコードを書きました。インスタンス化はMyFacesを使用しています(リンクの例はMojarra固有のようです)。私は...それは同じように自動的にNetBeansのによって生成されます。私はそれは私にそれを書くためにいくつかの時間がかかったとして、そこにそれをコピーして、それが他の誰かを助けることを願っています:

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; 
} 

は醜い例外処理に注意を払っていないしてください醜い反射のハッキングを避ける方法がある場合、MyFaces開発者に尋ねます。タグライブラリ内

<tag> 
    <description>blah blah</description> 
    <tag-name>myWonderfulTag</tag-name> 
    <source>tags/mwl/myWonderfulTag.xhtml</source> 
<!-- attributes --> 
</tag> 

は、私は、タグのコンポーネントと同じことを行うことができますどのように、私は次のように宣言コンポーネントを意味します。

ありがとうございます。

答えて

0

私はMyFacesでそれを行う方法を見つけました。また、醜い反射のビットを必要とする...

public static UIComponent instantiateTagComponent(Location loc, String namespace, String localPrefix, String componentName, TagComponentParam params[]) { 
    final String ERROR_MESSAGE = "Erreur lors de l'instanciation d'un tag component"; 
    FacesContext ctx = FacesContext.getCurrentInstance(); 
    AbstractFaceletContext fctx = (AbstractFaceletContext) ctx.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY); 
    fctx.pushPageContext(new PageContextImpl()); 

    FaceletViewDeclarationLanguage vdl = new FaceletViewDeclarationLanguage(ctx); 

    UIPanel panel = (UIPanel) ctx.getApplication().createComponent(UIPanel.COMPONENT_TYPE); 

    try { 
     Method createCompiler = FaceletViewDeclarationLanguage.class.getDeclaredMethod("createCompiler",FacesContext.class); 
     Method 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); 
     FaceletFactory ff = (FaceletFactory) createFaceletFactory.invoke(vdl, ctx, compiler); 
     TagLibrary tl = compiler.createTagLibrary(); 
     TagConfig tc = new JSFUtilsTagUnit(tl, namespace, localPrefix, componentName,params,loc); 
     TagHandler th = tl.createTagHandler(namespace, componentName, tc); 
     Field declaredField = FaceletCompositionContext.class.getDeclaredField("FACELET_COMPOSITION_CONTEXT_KEY"); 
     declaredField.setAccessible(true); 
     FaceletCompositionContextImpl faceletCompositionContextImpl = new FaceletCompositionContextImpl(ff,ctx); 
     Class<?> dfcClass = Class.forName("org.apache.myfaces.view.facelets.impl.DefaultFaceletContext"); 
     Field fMCTX = dfcClass.getDeclaredField("_mctx"); 
     fMCTX.setAccessible(true); 
     fMCTX.set(fctx, faceletCompositionContextImpl); 
     FacesContext.getCurrentInstance().getAttributes().put((String)declaredField.get(null),faceletCompositionContextImpl); 
     FaceletCompositionContext mctx = (FaceletCompositionContext) FaceletCompositionContext.getCurrentInstance(fctx); 
     mctx.startComponentUniqueIdSection(); 
     th.apply(fctx, panel); 
    } catch (IOException ex) { 
     log.error(ERROR_MESSAGE, ex); 
    } catch (InvocationTargetException ex) { 
     log.error(ERROR_MESSAGE, ex); 
    } catch (NoSuchMethodException ex) { 
     log.error(ERROR_MESSAGE, ex); 
    } catch (NoSuchFieldException ex) { 
     log.error(ERROR_MESSAGE, ex); 
    } catch (SecurityException ex) { 
     log.error(ERROR_MESSAGE, ex); 
    } catch (ClassNotFoundException ex) { 
     log.error(ERROR_MESSAGE, ex); 
    } catch (IllegalArgumentException ex) { 
     log.error(ERROR_MESSAGE, ex); 
    } catch (IllegalAccessException ex) { 
     log.error(ERROR_MESSAGE, ex); 
    } 
    finally { 
     fctx.popPageContext(); 
    } 
    return panel; 
} 

JSFUtilsTagUnitクラスは次のとおりです。

static class JSFUtilsTagUnit implements TagConfig { 

    private final TagLibrary library; 
    private final String namespace; 
    private final String name; 
    private Tag tag; 

    public JSFUtilsTagUnit(TagLibrary library, String namespace, String localPrefix, String name, TagComponentParam params[], Location loc) { 
     this.library = library; 
     this.namespace = namespace; 
     this.name = name; 
     if(loc == null) { 
      loc = new Location("virtual", -1, -1); 
     } 
     TagAttribute[] tas; 
     if((params != null) && (params.length > 0)) { 
      tas = new TagAttribute[params.length]; 
      int iCurrent = 0; 
      for(TagComponentParam tcpCur : params) { 
       tas[iCurrent] = new TagAttributeImpl(loc,"",tcpCur.getName(), tcpCur.getName(), tcpCur.getValue()); 
       iCurrent++; 
      } 
     } else { 
      tas = new TagAttribute[0]; 
     } 
     TagAttributes tattrs = new TagAttributesImpl(tas); 
     tag = new Tag(loc, namespace, name, localPrefix+":"+name, tattrs); 
    } 

    public FaceletHandler getNextHandler() { 
     return new FaceletHandler() { 

      public void apply(FaceletContext ctx, UIComponent parent) throws IOException { 
      } 
     }; 
    } 

    public Tag getTag() { 
     return tag; 
    } 

    public String getTagId() { 
     return "-1"; 
    } 

} 

が、それは他の誰かを助けることを願っています!

関連する問題