Is your suggestion that we
1) Add a new Map(String, Object>) implementation that takes both the
FacesBean and the UIComponent
2) Explicitly test for the id attribute in all of the accessor and
mutator functions, in addition to the the Sets returned
3) Override the state saving/restoration code to explicitly handle id
-- Blake Sullivan
Simon Lessard said the following On 1/5/2010 12:08 PM PT:
Have the AttributeMap call the getId/setId. The contract for the Map
returned by getAttributes is supposed to call the getter/setter method on
the component anyway, from
http://java.sun.com/javaee/5/docs/api/javax/faces/component/UIComponent.html#getAttributes%28%29
:
- get() - If the property is readable, call the getter method and
return the returned value (wrapping primitive values in their corresponding
wrapper classes); otherwise throw IllegalArgumentException.
- put() - If the property is writeable, call the setter method to set
the corresponding value (unwrapping primitive values in their corresponding
wrapper classes). If the property is not writeable, or an attempt is made to
set a property of primitive type to null, throw
IllegalArgumentException.
Regards,
~ Simon
On Tue, Jan 5, 2010 at 2:50 PM, Blake Sullivan <[email protected]>wrote:
The reason is that we need to support AttributeMap/component accessor
equivalence--get/set of the id attribute through the Map is supposed to work
correctly. The ValueExpression only exists to make this work.
-- Blake Sullivan
Simon Lessard said the following On 1/5/2010 10:57 AM PT:
Hi,
Why not simply NOT support a PropertyKey for the id attribute? I know it
isn't consistent with the other properties, but id is a very special case
not supporting EL anyway. In all the project I ever did, I never used
FacesBean.getProperty(ID_PROPERTY_KEY). The only drawback I would see is if
the component's id actually need to be read in a property getter method in a
renderer which receive only the FacesBean instance and not the component
itself. That would be much faster than a custom ValueExpression and the
memory footprint would also be better.
Regards,
~ Simon
On Tue, Jan 5, 2010 at 1:49 PM, Matthias Wessendorf <[email protected]>
<[email protected]>wrote:
On Thu, Dec 31, 2009 at 11:12 PM, Blake Sullivan<[email protected]>
<[email protected]> wrote:
UIComponent.getId() is by far the most requested component attribute.
There
are a number of reasons for this:
1) The JSF RI has an issue in the JSP-JSF integration which causes
getId()
to be called n^2 times where n is the number of children a component has
I guess this is true for MyFaces as well, right?
2) getClientId() calls getId()
3) FindComponent calls getId()
4) The tree visiting code trades off calls to getClientId() for calls to
getId()
FacesBean optimizes attribute Map access at the expense of access
directly
through the component. The the extent that Renderers are Components are
accessing the attributes through the attribute Map, this is fine, however
even the Renderers access attributes common to all UIComponents such as
id()
through the component directly. Considering the huge number of times
that
the the id is accessed (for some renders, this was 8% of the rendering
time), it makes sense to optimize this path.
The proposal is to:
1) Store the id an an instance variable on the UIXComponent
2) Add a new capability flag to PropertyKey indicating that the property
is
actually stored elsewhere using a ValueExpression will be stored as the
property's value in the PropertyMap. For access through the FacesBean,
the
ValueExpression will be evaluated to get/set the actual value
3) For state saving the ValueExpression is used to retrieve the actual
value
and for state restoration the ValueExpression (which has been
rebootstrapped
by the UIXComponent) is used to write the value back
4) Instead of setting the id attribute in the FacesBean, UIXComponent
stores
it locally and sets an ValueExpression implementation into the FacesBean
that retrieves the value from the UIXComponent
+1 on api/patch
API Changes:
PropertyKey:
add
/**
* Capability indicating that values for this property should be
* be stored and retrieved through a ValueExpression rather than on the
* FacesBean itself
*/
static public final int CAP_VALUE_EXPRESSION_IMPLEMENTATION = 16;
/**
* Returns <code>true</code> if property values for this key are set and
get
* using a ValueExpression rather than storing the value in the
FacesBean.
* @return <code>true</code> if properties values for this key are
retrieved
* with a ValueExpression.
*/
public boolean usesValueExpressionAsImplementation()
After this change id retrieval doesn't make the 1% YourKit profiler hot
spot
cut off
--
Matthias Wessendorf
blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf