I'm using Mojarra 2.1. Reading this answer about when to use custom tags and composite components, I came across with the question about internals of the components.
So, the most important difference between custom tags and composite components is that every composite component has a single UIComponent
instance, representing it in the component tree after view build time's finshed. Custom tag, in turn doesn't have a single UIComponent
instance representing it in the tree.
So, what is that class, representing the composite component in the tree? How is it created? Is that some anonymous class? Let's consider an example from the wiki-page:
<ui:component
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
>
<cc:interface>
<!-- Define component attributes here -->
</cc:interface>
<cc:implementation>
<!-- Define component body here -->
</cc:implementation>
</ui:component>
How can I get the instance of UIComponent
, representing that composite component?
Digging into the source code of the UIComponent
I found the following method:
public static boolean isCompositeComponent(UIComponent component) {
if (component == null) {
throw new NullPointerException();
}
boolean result = false;
if (null != component.isCompositeComponent) {
result = component.isCompositeComponent.booleanValue();
} else {
result = component.isCompositeComponent =
(component.getAttributes().containsKey(
Resource.COMPONENT_RESOURCE_KEY));
}
return result;
}
I suspect that it's implementation details how the composite-component class is created. In fact, I'd like to find where the Mojarra implemenattion generates the composite component class instance.
UPD: The defintion of the composite compoent's replaced with one that doesn't explicitly defines the componentType
attribute.
It's basically a UIPanel
instance which you can just get via UIComponent#findComponent()
the usual way, passing the composite component client ID. In case of Mojarra, you can find the code responsible for creating it in com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler
which has in Mojarra 2.2.11 the below logic:
360 if (ComponentHandler.isNew(c)) {
361 facetComponent = (UIPanel)
362 facesContext.getApplication().createComponent("javax.faces.Panel");
363 facetComponent.setRendererType("javax.faces.Group");
364 c.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facetComponent);
365 }
366 else {
367 facetComponent = (UIPanel)
368 c.getFacets().get(UIComponent.COMPOSITE_FACET_NAME);
369 }