You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Simon Kitching <sk...@obsidium.com> on 2005/12/06 05:51:46 UTC
value-bindings fetched during component initialisation
Hi,
Quick summary:
UIComponent.getAttributes().put(propName, value)
returns the old value of the property. When the property is a
value-binding this can cause problems, but there is no obvious way to
set a property without getting the old value returned.
== details
When a component is created and initialised by a JSP tag, attributes are
commonly assigned to the component by calls to:
UIComponentBodyTagBase.setStringProperty(component, propName, value).
This method delegates to UIComponentTagUtils.setStringProperty, which
implements this as:
if (isValueReference(value))
{
ValueBinding vb =
context.getApplication().createValueBinding(value);
component.setValueBinding(propName, vb);
}
else
{
component.getAttributes().put(propName, value);
}
The problem is that the component.getAttributes() method returns an
instance of _ComponentAttributesMap, and the put method of that class
tries to return the old value of the property.
Fetching the old value of the property typically invokes the getXXX
method of the component, which calls getValueBinding("XXX"), just to
return a value that the caller then ignores.
This is a waste of cpu.
It's also causing me problems because I want to override getValueBinding
in a custom component, but am finding that this method is being called
during the initialisation of the component which was not expected.
Unfortunately, I can't see an easy fix. This would be nice:
else
{
_ComponentAttributesMap attrs =
(_ComponentAttributesMap) component.getAttributes();
attrs.putNoReturn(propName, value);
}
however the _ComponentAttributesMap class is package-scope only.
_ComponentAttributesMap can't be made public, as new classes can't be
added to the javax.faces packages. It can't be moved out of the "api"
project (eg into "share", as the api project shouldn't have compile
dependencies on other subprojects).
Duplicating the _ComponentAttributesMap logic isn't good, as it's
non-trivial code. It also contains a very useful cache of
PropertyDescriptors that it would be a shame to recalculate.
Question: is it actually part of the JSF standard for the attributes.put
method to return the old value? That is indeed part of the java.util.Map
definition, but this class is only very loosely a Map.
Any thoughts???
Regards,
Simon