webtier@glassfish.java.net

Facets vs children in composite components

From: <webtier_at_javadesktop.org>
Date: Sun, 02 Aug 2009 02:11:46 PDT

I've been doing some tests with composite components and I would like to understand why they produce different results when I use facets and children. Here are the files I'm using:

test.xhtml
-----------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
    xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:fn="http://java.sun.com/jsp/jstl/functions"
        xmlns:h="http://java.sun.com/jsf/html"
    xmlns:tags="http://java.sun.com/jsf/composite/tags">
        
        <h:head>
           <title>Test</title>
        </h:head>
        
        <h:body>
           
           <h1><h:outputText value="listFacets" /></h1>
           <tags:listFacets value="#{fn:split('1,2,3', ',')}">
               <f:facet name="content">
                   <h:outputText value="Test1" styleClass="test" />
                   <h:outputText value="Test2" styleClass="test" />
               </f:facet>
           </tags:listFacets>
           
           <h1><h:outputText value="listChildren" /></h1>
       <tags:listChildren value="#{fn:split('1,2,3', ',')}">
           <h:outputText value="Test1" styleClass="test" />
           <h:outputText value="Test2" styleClass="test" />
       </tags:listChildren>
                  
        </h:body>
        
</html>


listFacets.xhtml
-----------------------------------------------
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:composite="http://java.sun.com/jsf/composite">
        
    <composite:interface>
        <composite:attribute name="value" />
        <composite:facet name="content" />
    </composite:interface>
    
    <composite:implementation>
        <c:forEach items="#{cc.attrs.value}" var="current">
                <composite:renderFacet name="content" />
                <hr />
            </c:forEach>
        <c:forEach items="#{cc.facets.content.children}" var="child">
            #{child.attributes.styleClass}
            <hr />
        </c:forEach>
    </composite:implementation>
        
</html>


listChildren.xhtml
-----------------------------------------------
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:composite="http://java.sun.com/jsf/composite">
        
    <composite:interface>
        <composite:attribute name="value" />
    </composite:interface>
    
    <composite:implementation>
            <c:forEach items="#{cc.attrs.value}" var="current">
                <composite:insertChildren />
                <hr />
            </c:forEach>
        <c:forEach items="#{cc.children}" var="child">
            #{child.attributes.styleClass}
            <hr />
        </c:forEach>
        </composite:implementation>
        
</html>


The above produce the following HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

   <head><title>Test</title></head>
   
   <body>
   
        <h1>listFacets</h1>
        <span class="test">Test1</span><span class="test">Test2</span>
        <hr />
        <span class="test">Test1</span><span class="test">Test2</span>
        <hr />
        <span class="test">Test1</span><span class="test">Test2</span>
        <hr />
        test
        <hr />
        test
        <hr />
   
        <h1>listChildren</h1>
        <span class="test">Test1</span><span class="test">Test2</span>
        <hr />
        <hr />
        <hr />
        <hr />
        <hr />
    </body>
        
</html>


So, when using a single facet I'm able to print it multiple times inside a loop but the composite:insertChildren is printed only one. The children are printed multiple times when I replace c:forEach with ui:repeat but I really prefer using c:forEach. I had to check again but ui:repeat worked well in Jetty 6.1.18 but throw an exception in Tomcat 6.0.16.

Another cool feature of the facet is that I can access it's children and their attributes using the cc.facets.content.children collection. I wasn't able to achieve the same using the children variant. A bug I also noticed when doing the tests is that when there is a single child inside the facet the cc.facets.content.children doesn't work as expected. It works fine when there are multiple children inside the facet.

I'm wondering is this behavior expected by design. I don't need the single facet if I can use the composite:insertChildren functionality but so far the facet approach only satisfies my needs.

Thanks!
[Message sent by forum member 'rostislav' (rostislav)]

http://forums.java.net/jive/thread.jspa?messageID=358500