myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kito D. Mann (JIRA)" <>
Subject [jira] [Commented] (MYFACES-3283) #{cc.attr} attributes fail when a child component is accessed outside of the composite component (i.e. in action listeners or other events)
Date Wed, 17 Aug 2011 23:46:27 GMT


Kito D. Mann commented on MYFACES-3283:

I just took a look at the spec, and section states the following: 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
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
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 you can find the following:

cc -> the current composite component relative to the declaring page in which the expression

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:
>             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. "#{}").
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=""
> 	xmlns:h=""
> 	xmlns: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" "">
> <html xmlns=""
> 	xmlns:ui=""
> 	xmlns:h=""
> 	xmlns:f=""
> 	xmlns:ez="">
> <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:

This message is automatically generated by JIRA.
For more information on JIRA, see:


View raw message