Comment créer par programme ou dynamiquement un composant composite dans JSF 2

J'ai besoin de créer par programmation composite composants JSF 2. Après quelques jours de recherches et d'expériences je figure sur cette méthode (très inspiré par Lexi à java.net):

/**
* Method will attach composite component to provided component
* @param viewPanel parent component of newly created composite component
*/
public void setComponentJ(UIComponent viewPanel) {
FacesContext context = FacesContext.getCurrentInstance();
viewPanel.getChildren().clear();
//load composite component from file
Resource componentResource = context.getApplication().getResourceHandler().createResource("whatever.xhtml", "components/form");
UIComponent composite = context.getApplication().createComponent(context, componentResource);
//push component to el
composite.pushComponentToEL(context, composite);
boolean compcompPushed = false;
CompositeComponentStackManager ccStackManager = CompositeComponentStackManager.getManager(context);
compcompPushed = ccStackManager.push(composite, CompositeComponentStackManager.StackType.TreeCreation);
//Populate the component with value expressions 
Application application = context.getApplication();
composite.setValueExpression("value", application.getExpressionFactory().createValueExpression(
context.getELContext(), "#{stringValue.value}",
String.class));
//Populate the component with facets and child components (Optional)
UIOutput foo = (UIOutput) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
foo.setValue("Foo");
composite.getFacets().put("foo", foo);
UIOutput bar = (UIOutput) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
bar.setValue("Bar");
composite.getChildren().add(bar);
//create composite components Root
UIComponent compositeRoot = context.getApplication().createComponent(UIPanel.COMPONENT_TYPE);
composite.getAttributes().put(Resource.COMPONENT_RESOURCE_KEY, componentResource);
compositeRoot.setRendererType("javax.faces.Group");
composite.setId("compositeID");
try {
FaceletFactory factory = (FaceletFactory) RequestStateManager.get(context, RequestStateManager.FACELET_FACTORY);
Facelet f = factory.getFacelet(componentResource.getURL());
f.apply(context, compositeRoot); //<==[here]
} catch (Exception e) {
log.debug("Error creating composite component!!", e);
}
composite.getFacets().put(
UIComponent.COMPOSITE_FACET_NAME, compositeRoot);
//attach composite component to parent componet
viewPanel.getChildren().add(composite);
//pop component from el
composite.popComponentFromEL(context);
if (compcompPushed) {
ccStackManager.pop(CompositeComponentStackManager.StackType.TreeCreation);
}
}

Problème est que ce code fonctionne pour moi que quand javax.des visages.PROJECT_STAGE est mis à la PRODUCTION (Il m'a fallu toute la journée pour comprendre cela). Si javax.des visages.PROJECT_STAGE est réglé pour le DÉVELOPPEMENT Exception est levée sur le point marqué (<==[ici]):

javax.faces.view.facelets.TagException: /resources/components/form/pokus.xhtml @8,19 <cc:interface> Component Not Found for identifier: j_id2.getParent().  
at com.sun.faces.facelets.tag.composite.InterfaceHandler.validateComponent(InterfaceHandler.java:135)  
at com.sun.faces.facelets.tag.composite.InterfaceHandler.apply(InterfaceHandler.java:125)  
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)  
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)  
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:82)  
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152)  
at cz.boza.formcreator.formcore.Try.setComponentJ(Try.java:83)  
at cz.boza.formcreator.formcore.FormCreator.<init>(FormCreator.java:40)  
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)  
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)  
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)  

C'est un problème avec le parent mis en compositeRoot composant (j_id2 est automatiquement généré ID de compositeRoot). Aussi ce code n'est pas testé thorougly assez, donc je ne suis pas sûr si je peux compter sur elle.

Je pense qu'il est très important d'être capable de manipuler des Composants Composites programmaticaly. Sinon Composite Composants sont à moitié inutile.

Merci beaucoup.

source d'informationauteur Ondrej Bozek