[ http://issues.apache.org/jira/browse/MYFACES-920?page=all ]
Simon Kitching updated MYFACES-920: ----------------------------------- Attachment: _ComponentAttributesMap.java.patch.txt UIComponentTagUtils.java.patch.txt > Avoid invoking value-bindings during component initialisation > ------------------------------------------------------------- > > Key: MYFACES-920 > URL: http://issues.apache.org/jira/browse/MYFACES-920 > Project: MyFaces > Type: Improvement > Components: General > Reporter: Simon Kitching > Attachments: UIComponentTagUtils.java.patch.txt, > _ComponentAttributesMap.java.patch.txt > > When a component is created by a JSP tag, calls to setStringProperty, > setBooleanProperty, etc are used to copy the JSP tag attributes onto the new > component. (NB: other view implementations will be doing something similar > I'm sure). > The setStringProperty et. al. eventually call > component.getAttributes().put(propName, value) > Unfortunately, the Map.put method is defined to return the old value of the > property. While the specs are a little vague on whether a return value is > actually required as far as I can see, both MyFaces and Sun do try to return > the old value. But this means calling the getter method on the component, > which typically calls getValueBinding(). > During component initialisation, this call to the component's getter method > and thence to getValueBinding isn't actually *too* bad; the binding will > never be found because each attribute is initially null, and is set only > once. However it's still inefficient; it's a call via reflection, a HashMap > lookup, etc. that is all completely unnecessary as the return value will (a) > always be null, and (b) is ignored. > This behaviour *is* a major pain for anyone (like me) who would like to > override the getValueBinding method for a component; it gets called once for > each attribute of the JSP tag, and during a time when the component is not > completely initialised. And there's no way to tell when component > initialisation has completed as far as I know. > Attached is a proposed solution. The UIComponent.getAttributes method returns > a custom (private) Map implementation already. It isn't possible to add any > methods to this, as it's in the API namespace. Instead I've modified the put > method so that if the provided propName has a special prefix then the method > doesn't bother to fetch and return the old value. Updating the > setStringProperty/setBooleanProperty/etc methods to add the prefix then > solves the issue. > What do people think of this? Is this ok to commit? > NB: I will be creating some unit tests to go along with this, to prove that > the patch does what it says. I don't have time just now, though, and wanted > to post this before I left for the weekend. > NB2: If this does go in (or some other solution to this problem) I've got a > rather cool use for it. A "backingBean" attribute can then be defined on a > component, and via a customised ValueBinding, any property on the component > that supports value-binding will automatically try to fetch the data from an > identically-named property on the specified backingBean for the component. > It's very useful when dealing with components with lots of bindable > properties, like a UIData - or my custom extension of that class, which has > even more properties. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira