0

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.

Community
  • 1
  • 1
St.Antario
  • 26,175
  • 41
  • 130
  • 318

1 Answers1

1

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        }
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Got it, thank you. In the Mojarra 2.1, Sources are almost the same. But one more question, the facetComponent is a local variable, so I presume including the component's performed by the `ctx.includeFacelet(facetComponent, ccResource.getURL());` invocation. But javadocs for that method are not perfectly clear: _Include another Facelet defined at some path, absolute to this ClassLoader/OS_. Couldn't you clarify what it means in simple words? – St.Antario Aug 25 '15 at 07:59
  • `` inside component represented by `facetComponent`. – BalusC Aug 25 '15 at 08:07