After that I've read the following topics:
http://forums.java.net/jive/thread.jspa?threadID=63877
http://forums.java.net/jive/thread.jspa?messageID=384548
The solution sketched out there basically repeats the functionality of the CompositeComponentTagHandler. The user janderssn wrote that he's got the basic solution, but things like composite:insertChildren and composite:renderFacet don't work. The reason why these things did not work was that the composite component must have been pushed and poped from/to EL. I have reworked the code a bit an now here's the working version (with facets and children):
[pre]
public void setComponent3(UIComponent component) {
Application application = facesContext.getApplication();
Resource resource = application.getResourceHandler().createResource(
"test.xhtml", "components/dynamicfaces");
// Create the composite component
// See CompositeComponentTagHandler#createComponent
UIComponent compositeComponent = facesContext.getApplication()
.createComponent(facesContext, resource);
compositeComponent.pushComponentToEL(facesContext, compositeComponent);
boolean compcompPushed = false;
CompositeComponentStackManager ccStackManager = CompositeComponentStackManager
.getManager(facesContext);
compcompPushed = ccStackManager.push(compositeComponent, TreeCreation);
// Important: set the id - otherwise newly created components get
// different ids
// and "old" request values are not decoded.
compositeComponent.setId("composite");
// Populate the component with value expressions
compositeComponent.setValueExpression("value", application
.getExpressionFactory().createValueExpression(
facesContext.getELContext(), "#{stringValue.value}",
String.class));
// super.applyNextHandler
// Populate the component with facets and child components
UIOutput foo = (UIOutput) application
.createComponent(HtmlOutputText.COMPONENT_TYPE);
foo.setValue("Foo");
compositeComponent.getFacets().put("foo", foo);
UIOutput bar = (UIOutput) application
.createComponent(HtmlOutputText.COMPONENT_TYPE);
bar.setValue("Bar");
compositeComponent.getChildren().add(bar);
// applyCompositeComponent
FaceletFactory factory = (FaceletFactory) RequestStateManager.get(
facesContext, RequestStateManager.FACELET_FACTORY);
final UIComponent compositeRoot = application
.createComponent(UIPanel.COMPONENT_TYPE);
compositeRoot.setRendererType("javax.faces.Group");
// See CompositeComponentTagHandler#applyCompositeComponent(...)
try {
Facelet f = factory.getFacelet(resource.getURL());
f.apply(facesContext, compositeRoot);
compositeComponent.getFacets().put(
UIComponent.COMPOSITE_FACET_NAME, compositeRoot);
} catch (IOException ioex) {
throw new FaceletException(ioex);
}
// Add the created composite component to the tree
component.getChildren().add(compositeComponent);
compositeComponent.popComponentFromEL(facesContext);
if (compcompPushed) {
ccStackManager.pop(TreeCreation);
}
// Black magic ends here
// Not important: finally assign the component to the inner field
this.component = component;
}
[/pre]
As I said above, this code [b]does[/b] work as expected. Figuring it out was like alchemy - trying different things in different orders and so on.
My problem with this code is that it is very very complicated. This is not what client code should be. It's just black magic, nothing else.
[Message sent by forum member 'lexi' (valikov_at_gmx.net)]
http://forums.java.net/jive/thread.jspa?messageID=389244