[ https://issues.apache.org/jira/browse/MYFACES-3283?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13086685#comment-13086685 ]
Kito D. Mann commented on MYFACES-3283: --------------------------------------- I just took a look at the spec, and section 5.6.2.2 states the following: 5.6.2.2 Composite Component Attributes ELResolver This ELResolver makes it so expressions that refer to the attributes of a composite component get correctly evaluated. For example, the expression #{cc.attrs.usernameLabel} says, “find the current composite component, call its getAttributes() method, within the returned Map look up the value under the key “usernameLable”. If the value is a ValueExpression, call getValue() on it and the result is returned as the evaluation of the expression. Otherwise, if the value is not a ValueExpression the value itself is returned as the evaluation of the expression.” It goes on to define the specific behavior of getValue(): If base is non-null, is an instance of UIComponent, is a composite component, and property is non-null and is equal to the string “attrs”, return a Map implementation with the following characteristics. Wrap the attributes map of the composite component and delegate all calls to the composite component attributes map with the following exceptions: Only get() and put() are required to be supported. get(): if the result of calling get() on the component attributes map is null, and a default value was declared in the composite component metadata, the value will be a ValueExpression. Evaluate it and return it. Otherwise, simply return the value from the component attributes map. put(): Call getValueExpression() on the component. If this returns non-null, call setValue() on it, passing the value argument as the last argument. Otherwise, simply call through to put on the component attributes map. The Map implementation must also implement the interface javax.faces.el.CompositeComponentExpressionHolder. Otherwise, take no action. Nowhere in here does it say "this should only work in the context of a tree visit". The only ambiguous statement is "current composite component". In the Implicit EL Resolver description (section 5.6.2.1) you can find the following: cc -> the current composite component relative to the declaring page in which the expression appears. The "current composite component" can be considered the value returned from UIComponent.getCurrentCompositeComponent(), which has this description: Returns the closest ancestor component relative to getCurrentComponent that is a composite component, or null if no such component is exists. UIComponent.getCurrentComponent() is described as follows: Returns the UIComponent instance that is currently being processed. So, this does imply a tree traversal. It just doesn't make sense from a developer's perspective... > #{cc.attr} attributes fail when a child component is accessed outside of the > composite component (i.e. in action listeners or other events) > ------------------------------------------------------------------------------------------------------------------------------------------- > > Key: MYFACES-3283 > URL: https://issues.apache.org/jira/browse/MYFACES-3283 > Project: MyFaces Core > Issue Type: Bug > Components: General > Affects Versions: 2.0.7 > Environment: Mac OS 10.6, Tomcat 7 > Reporter: Kito D. Mann > Attachments: myfaces_cc_issue.war > > > If you reference a property of child component anywhere outside of the > composite's context (i.e. in an action method, a component system event > listener, etc.), the property will not be evaluated properly if the > expression is a composite component attribute (i.e. "#{cc.attrs.property}"). > This is because the EL evaluation code can't find the parent composite > component. > For example, consider the composite component: > <?xml version="1.0"?> > <html xmlns="http://www.w3.org/1999/xhtml" > xmlns:h="http://java.sun.com/jsf/html" > xmlns:composite="http://java.sun.com/jsf/composite"> > <composite:interface> > <composite:attribute name="label" /> > <composite:attribute name="value" required="true" /> > </composite:interface> > <composite:implementation> > <h:outputLabel for="input" value="#{cc.attrs.label}" /> > <h:inputText id="input" value="#{cc.attrs.value}" /> > </composite:implementation> > </html> > The calling page: > <!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:ui="http://java.sun.com/jsf/facelets" > xmlns:h="http://java.sun.com/jsf/html" > xmlns:f="http://java.sun.com/jsf/core" > xmlns:ez="http://java.sun.com/jsf/composite/demo"> > <h:head></h:head> > <h:body> > <h:form id="form"> > <h:messages /> > <ez:input id="composite" label="Enter something:" > value="#{testBean.value}" /> > <h:commandButton value="Submit" > action="#{testBean.testCcAttribute}" /> > </h:form> > </h:body> > </html> > Here's testBean.testCcAttribute(): > public String testCcAttribute() { > HtmlInputText input = > (HtmlInputText)FacesContext.getCurrentInstance().getViewRoot().findComponent("form:composite:input"); > UIComponent composite = > FacesContext.getCurrentInstance().getViewRoot().findComponent("form:composite"); > String message = "Input control label attribute is: " + > input.getLabel() + "; Composite label attribute is: " + > composite.getAttributes().get("label"); > display(message); > return null; > } > This action method generates the following message: > Input control label attribute is: null; Composite label attribute is: Enter > something: > --- > Full example WAR attached. > Note this is the same as the following issue with Mojarra: > http://java.net/jira/browse/JAVASERVERFACES-2009. -- This message is automatically generated by JIRA. For more information on JIRA, see: http://www.atlassian.com/software/jira