cc:attribute type="java.lang.Integer" does not enforce Integer when value is
taken from facelets template
---------------------------------------------------------------------------------------------------------
Key: MYFACES-3027
URL: https://issues.apache.org/jira/browse/MYFACES-3027
Project: MyFaces Core
Issue Type: Bug
Reporter: Leonardo Uribe
>From [email protected]
[jsr-314-open] Composite component metadata runtime behavior
I checked in deep how attribute for composite components works, and here is
what I found.
This is the javadoc of cc:attribute type:
"... Declares that this attribute must be a ValueExpression whose expected type
is given by the value of this attribute. If not specified, and no
"method-signature" attribute is present, java.lang.Object is assumed. This
attribute is mutually exclusive with the "method-signature" attribute. If both
attributes are present, the "method-signature" attribute is ignored. ..."
MyFaces (2.0.3 and earlier) implemented what javadoc says, but in practice
Mojarra (tested 2.0.3 and 2.1.0 snapshot branch) behaves different in this
case. For example, if it is written this:
<cc:attribute name="foo" type="java.lang.Integer"/>
With the following component definition:
<comp:bar foo="5"/>
In MyFaces the String "5" is stored on the map, but in Mojarra an Integer 5 is.
It is obvious the right behavior is the one shown by Mojarra, even if the
javadoc is to explicit about this fact.
Now think about a little bit more complex example:
<cc:attribute name="foo" type="java.lang.Integer" default="5"/>
both MyFaces and Mojarra fails in this case, because the default is assumed to
be a String "5" and not an Integer 5.
It is obvious the author expect "type" attribute enforce the value to the type
using EL coercions, like it is done for all other components, right? Maybe the
javadoc is not explicit, but it is clear the way to go.
Now try to get a value programatically instead use EL expressions.
myCompositeBar.getAttributes.get("foo")
the default is just ignored. Why? by the spec, composite component default
values are handled by "Composite Component Attribute EL Resolver". This is what
JSF 2.0 spec section 5.6.6.2 says about it (getValue description)
"... 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. ..."
In my opinion, we should do that on UIComponent.getAttributes() map instead on
an EL resolver, after all we could use the value stored on BEANINFO_KEY to get
the descriptor and handle the default value only if all fails.
But here is the big question: It is really necessary to support that case? The
common case is lookup attributes map using an EL expression
#{cc.attrs.myproperty}. This could be necessary only if we do a composite
component with a custom component type and we need to play with properties
defined on the component class and the composite component definition, but
that's very exotic (but theorically possible).
Now it is possible to answer the questions (in my personal opinion, based on
the previous reasoning):
1. Should JSF implementations be making use of composite component metadata
(like "type") at runtime to enforce the intentions of the composite component
author?
Ans: Really this is already done, because ValueExpressions are created and
values are coerced taking into account the type, but we don't have any code on
the default component attribute map class that enforces it.
2. Should this behavior be specified?
Ans: the javadoc of cc:attribute type is incomplete and definitively needs to
be fixed.
3. Are there other places where we have similar metadata (eg. Facelets
taglib.xml files) that we should review as well?
Ans: User tag handlers does not have any semantic about how to handle
attributes, so there is nothing we can do or other places to review (after all,
one of the intentions of composite components is provide a transparent way to
create components with the flexibility of custom facelets tag handlers).
What do we need to do? Fix the bugs on MyFaces and Mojarra related to this
issue.
--
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira