Assume we have a fairly simple composite component:
[pre]
<html
xmlns="
http://www.w3.org/1999/xhtml"
xmlns:h="
http://java.sun.com/jsf/html"
xmlns:composite="
http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<composite:interface>
<composite:facet name="foo"/>
<composite:attribute name="value"/>
</composite:interface>
<!-- IMPLEMENTATION -->
<composite:implementation>
<h:inputText id="value" value="#{cc.attrs.value}"/>
[<composite:renderFacet name="foo"/>]
(<composite:insertChildren/>)
</composite:implementation>
</html>
[/pre]
Using it from the Facelets page is straightforward:
[pre]
<d:test id="tag" value="#{stringValue.value}">
<f:facet name="foo">
<h:outputText value="Foo"/>
</f:facet>
<h:outputText value="Bar"/>
</d:test>
[/pre]
I'd like to create this composite component programmatically - ad I'd like to set the [b]value[/b] as well as the [b]facet foo[/b] and [b]children components[/b] programmatically as well.
Here's the first thing I tried:
[pre]
public void setComponent1(UIComponent component) throws Exception {
Application application = facesContext.getApplication();
Resource resource = application.getResourceHandler().createResource(
"test.xhtml", "components/dynamicfaces");
UIComponent compositeComponent = application.createComponent(
facesContext, resource);
component.getChildren().add(compositeComponent);
ValueExpression value = application.getExpressionFactory()
.createValueExpression(facesContext.getELContext(),
"#{stringValue.value}", String.class);
compositeComponent.setValueExpression("value", value);
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);
this.component = component;
}
[/pre]
This is the most straightforward thing, this is what I expect to work and this is what I think is designed in the specification. It's also what Ed Burns mentions here:
http://forums.java.net/jive/thread.jspa?messageID=339830
Very naive.
It fails with an exception with the following cause:
Unable to find composite component root for composite component with id null and class javax.faces.component.UINamingContainer
To avoid the exception I've added:
[pre]
UIComponent compositeRoot = application
.createComponent(UIPanel.COMPONENT_TYPE);
compositeRoot.setRendererType("javax.faces.Group");
compositeComponent.getFacets().put(UIComponent.COMPOSITE_FACET_NAME,
compositeRoot);
[/pre]
The exception was gone, but the component was still empty.
[Message sent by forum member 'lexi' (valikov_at_gmx.net)]
http://forums.java.net/jive/thread.jspa?messageID=389243