0

Basic Question

Is this a bug in Mojarra or am I trying to do something that is not supported by the spec?

Overview

I have a composite component "outerComposite" that ui:includes a facelet with another composite component "innerComposite". I want to pass the client id of the outer composite to the inner composite using <ui:param>. Depending on how the EL expression looks like, this works or fails on Wildfly 10/11 but works in all cases on Websphere Liberty 17.0.0.1.

Basic Code

outerCompositeUsingPage.xhtml

<h:head />
<h:body>
    <h:form id="form">
        <app:outerComposite id="outer" value="Test" />
    </h:form>
</h:body>

outerComposite.xhtml that includes a facelet with innerComposite:

<cc:implementation>
<c:set var="clientIdViaSet" value="#{cc.clientId}" /> 
<div id="#{cc.clientId}">
   <ui:include src="innerCompositeInclude.xhtml">
        <ui:param name="clientIdDirect" value="#{cc.clientId}" />     <-- WORKS   
        <ui:param name="clientIdViaMethod" value="#{compositeHelperBean.getClientId(cc)}" />    <-- FAILS   
        <ui:param name="clientIdViaSet" value="#{clientIdViaSet}" />        <-- WORKS
   </ui:include>
</div>

innerCompositeInclude.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:app="http://xmlns.jcp.org/jsf/composite/components/app" >
    <app:innerComposite id="inner"
                    value1Key="Direct"
                    value1Value="#{clientIdDirect}"
                    value2Key="Via Method"
                    value2Value="#{clientIdViaMethod}"
                    value3Key="Via c:set"
                    value3Value="#{clientIdViaSet}"
                   />
</ui:composition>

innerComposite.xhtml

<cc:interface>
    <cc:attribute name="value1Key" type="java.lang.String" />
    <cc:attribute name="value2Key" type="java.lang.String" />
    <cc:attribute name="value3Key" type="java.lang.String" />
    <cc:attribute name="value1Value" type="java.lang.String" />
    <cc:attribute name="value2Value" type="java.lang.String" />
    <cc:attribute name="value3Value" type="java.lang.String" />
</cc:interface>
<cc:implementation>
    <div id="#{cc.clientId}">
       <h:panelGrid columns="2">
           <h:outputText value="#{cc.attrs.value1Key}" />
           <h:outputText value="#{cc.attrs.value1Value}" />
           <h:outputText value="#{cc.attrs.value2Key}" />
           <h:outputText value="#{cc.attrs.value2Value}" />
           <h:outputText value="#{cc.attrs.value3Key}" />
           <h:outputText value="#{cc.attrs.value3Value}" />
        </h:panelGrid>                    
    </div>
 </cc:implementation>

ComponentHelperBean.java

@ApplicationScoped
@Named
public class CompositeHelperBean {
    public String getClientId(UIComponent comp) {
       return comp.getClientId();
    }
}

Observation

Because #{cc.clientId} is passed as a parameter to an include file, I expect #{cc.clientId} to be the value of the outer composite. This indeed works. Because #{compositeHelperBean(cc)} just calls cc.getClientId(), I expect this to yield the same result as the direct EL expression #{cc.clientId}. This is not the case; instead, it resolves to the client id of the inner composite component. The result looks as follows in Wildfly 10/11:

Direct      form:outer            <--- OK
Via Method  form:outer:inner      <--- WRONG
Via c:set   form:outer            <--- OK

The result looks as follows in Websphere Liberty Profile 17.0.0.1

Direct      form:outer            <--- OK
Via Method  form:outer            <--- OK
Via c:set   form:outer            <--- OK

Research

I have looked into the code of Mojarra as well as MyFaces. Both have a TagHandlerImpl that create a ValueExpression. In there, they use a regular expression to determine if the EL has something to do with cc. Both expressions are different which could explain why the behaviour is different.

beosign
  • 433
  • 5
  • 10
  • Related: https://stackoverflow.com/questions/29987055/nested-jsf-composite-components-leading-to-a-stack-overflow-exception ? Not the error but the 'cause' and solution? – Kukeltje Nov 25 '17 at 14:17
  • @Kukeltje I think it's rather the opposite. The 'cause' in the related post is that `#{cc}` is always resolved to the current composite. If this behaviuor would also hold here, them I would expect all outputs to be the "inner composite", so `form:outer:inner` for all three outputs. However, this is *not* the case here, so in contrast to the other post the `#{cc}` gets (alomost always) actually resolved to the outer component (well, except the second case where it outputs the inner id). – beosign Nov 25 '17 at 14:35

0 Answers0