Uploaded image for project: 'MyFaces Core'
  1. MyFaces Core
  2. MYFACES-3027

cc:attribute type="java.lang.Integer" does not enforce Integer when value is taken from facelets template

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.0.3
    • 2.0.4
    • JSR-314
    • None

    Description

      From jsr-314-open@jcp.org

      [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.

      Attachments

        Activity

          People

            lu4242 Leonardo Uribe
            lu4242 Leonardo Uribe
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: