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

        

Reply via email to