JSF Backing Component - Composite Component - Stackoverflow Exception
composite-component, jsf, jsf-2
Solution
`UIComponent#getAttributes()` is a very special map. On a given key, say `"foo"`, it first evaluates `#{component.foo}` as a `ValueExpression` which implicitly invokes `UIComponent#getFoo()` method. See also the javadoc. That totally explains the infinite loop. If the `getFoo()` method was absent, then it'd just have continued to look in the "static" map (which you can control by overriding `UIComponent#getValueExpression()`).
You need to solve your concrete functional requirement differently. I have actually had a hard time in wrapping my head around your concrete functional requirement, but I believe that you actually need to define separate properties with separate getters/setters, all properly delegating to the state helper:
public String getLocalName() {
return getStateHelper().eval("localName", getAttributes().get("name")); // Note: this thus defaults to #{cc.attrs.name} when not set before.
}
public void setLocalName(String localName) {
return getStateHelper().put("localName", localName);
}
and then use it in the composite implementation as
<h:inputText value="#{cc.localName}" />
instead of
<h:inputText value="#{cc.attrs.name}" />
Problem
I want to use a backing component as a layer for accessing the attributes of my composite component (as defined in its interface). What I wanted to achieve was reading the attributes of my componentent via my backing component class where i give back the property value of the attribute provided. ``` public String getName() { if (this.name == null) { this.name = getAttributes().get("name"); } return this.name; } ``` But when setting a new value e.g. via an input field I wanted to store the value only within my backing bean properties not updating the values of the original properties passed as attribute arguments to my composite component. ``` public void setName(final String name) { this.name = name; } ``` My problem now is when the getter of my backing component is called the first time or at some early stage of his life the code of the getter as shown above results in a Stackoverflow exception as getAttributes.get("name") calls the getter of my backing component (itself) instead fetching the property/attribute provided to my composite component. Fun part is using a simple getter only returning this.name instead of calling getAttributes() I can set a breakpoint there and then calling getAttributes.get("name") (via debugger) results not in a overflow/ calling its own getter but instead the attribute provided to my composite component is returned. I guess it has something to do with the coupling betweend the backing component and the composite component. That when the getter gets called for the first time no coupling between them is given and therefor the call of getAttributes.get("name") results in calling the getter of my backing component whereas later the call does not invoke its own getter but instead fetches the attribute provided to my comp component. Anyone have any idea how to solve this issue? Thnx in advance.