Jsf 如何以编程方式实例化复合组件或标记组件?
我希望以编程方式实例化复合组件或标记组件 该实例化将由自定义组件执行,通常将这些复合组件或标记组件添加为子组件 我在爬网论坛时找到的最佳答案是:。这看起来很像我在这个论坛上找到的另一个答案: 在研究这个问题时,我最终编写了使用MyFaces进行复合实例化的代码(链接中的示例似乎是特定于Mojarra的)。我把它复制到那里,因为我花了一些时间来写它,希望它能帮助其他人:Jsf 如何以编程方式实例化复合组件或标记组件?,jsf,jsf-2,components,Jsf,Jsf 2,Components,我希望以编程方式实例化复合组件或标记组件 该实例化将由自定义组件执行,通常将这些复合组件或标记组件添加为子组件 我在爬网论坛时找到的最佳答案是:。这看起来很像我在这个论坛上找到的另一个答案: 在研究这个问题时,我最终编写了使用MyFaces进行复合实例化的代码(链接中的示例似乎是特定于Mojarra的)。我把它复制到那里,因为我花了一些时间来写它,希望它能帮助其他人: public UIComponent instantiateComposite(String namespace, String
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开发者是否有办法避免丑陋的反射黑客
如何对标记组件执行相同的操作,我指的是声明如下的组件:
<tag>
<description>blah blah</description>
<tag-name>myWonderfulTag</tag-name>
<source>tags/mwl/myWonderfulTag.xhtml</source>
<!-- attributes -->
</tag>
废话
我的奇妙标签
tags/mwl/myWonderfulTag.xhtml
在taglib中
提前谢谢。好的,我找到了如何用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;
}
希望它能帮助别人
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";
}
}