You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org> on 2010/10/19 03:30:27 UTC

[jira] Created: (MYFACES-2946) composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions

composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions
------------------------------------------------------------------------------------------------------------

                 Key: MYFACES-2946
                 URL: https://issues.apache.org/jira/browse/MYFACES-2946
             Project: MyFaces Core
          Issue Type: Bug
          Components: JSR-314
    Affects Versions: 2.0.2
            Reporter: Leonardo Uribe
            Assignee: Leonardo Uribe


Some days ago, it was mentioned on myfaces dev list that "targets"
attribute does not seem to work as expected. After review the available
documentation and doing some test, my conclusion was the spec is good,
but this part needs a little bit more documentation (and fix some 
bugs), because there are use cases that are causing problems to users.
Some of these problems has been already mentioned (spec issue 755) but
my intention here is do a full and detailed analysis. 

The property "targets" is used for these tags:

composite:actionSource
composite:editableValueHolder
composite:valueHolder
composite:clientBehavior
composite:attribute

For the first four cases, this property is used by :

ViewDeclarationLanguage.retargetAttachedObjects(FacesContext context,
                                    UIComponent topLevelComponent,
                                    List<AttachedObjectHandler> handlers)

In JSF 2.0 rev A it was made explicit the need to handle nested
composite component with this lines:

"... The implementation must support retargeting attached objects from 
the top level compsite component to targets that are composite and 
non-composite components ...."

This is ok ;-).

The problem is the description about how composite:attribute "targets" 
property works does not match with the algorithm for:

ViewDeclarationLanguage.retargetMethodExpressions(FacesContext context, 
                                    UIComponent topLevelComponent)

Here is the documentation about composite:attribute "targets":

"... If this element has a method-signature attribute, 

the value of the targets attribute must be interpreted as a space 
(not tab) separated list of client ids (relative to the top level 
component) of components within the <composite:implementation>  section. 

Space is used as the delimiter for compatibility with the IDREFS and 
NMTOKENS data types from the XML Schema. 

Each entry in the list must be interpreted as the id of an inner 
component to which the MethodExpression  from the composite component 
tag in the using page must be applied. 

If this element has a method-signature attribute, but no targets 
attribute, the value of the name  attribute is used as the single entry 
in the list. 

If the value of the name  attribute is not one of the special values 
listed in the description of the name attribute, targets  (or its 
derived value) need not correspond to the id of an inner component ...".

At this point everything seems to be ok. But look this documentation
(I'll put the important points):

".....
 # Get the value of the targets attribute. If the value is a ValueExpression 
   evaluate it. If there is no targets attribute, let the name of the 
   metadata element be the evaluated value of the targets attribute.
 # Interpret targets as a space (not tab) separated list of ids. For each entry 
   in the list:
     ......
    # If name is equal to the string "action" without the quotes, call 
      ActionSource2.setActionExpression(javax.el.MethodExpression) on target, 
      passing attributeMethodExpression.
    # If name is equal to the string "actionListener" without the quotes, call 
      ActionSource.addActionListener(javax.faces.event.ActionListener) on target, 
      passing attributeMethodExpression wrapped in a MethodExpressionActionListener.
    # If name is equal to the string "validator" without the quotes, call 
      EditableValueHolder.addValidator(javax.faces.validator.Validator) on target, 
      passing attributeMethodExpression wrapped in a MethodExpressionValidator.
    # If name is equal to the string "valueChangeListener" without the quotes, call 
      EditableValueHolder.addValueChangeListener(javax.faces.event.ValueChangeListener) 
      on target, passing attributeMethodExpression wrapped in a 
      MethodExpressionValueChangeListener.
    # Otherwise, assume that the MethodExpression should be placed in the 
      components attribute set. The runtme must create the MethodExpression 
      instance based on the value of the "method-signature" attribute.
....."

My first interpretation of this javadoc was that "targets" only has sense for "action",
"actionListener", "validator" and "valueChangeListener". But note if that's true,
someone could expect something like the description on retargetAttachedObjects, right?

The current behavior (Mojarra 2.0.3 and Myfaces 2.0.2) is the same, if we have two
nested composite components, that will throw a ClassCastException. There is a issue already
open for this one:

https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=755

There are two possible alternatives here:

 1. Implement the algorithm proposed for retargetMethodExpressions and ignore 
    composite:attribute "targets" property says. 
 2. Implement the expected behavior of composite:attribute "targets" property and make
    some changes to retargetMethodExpressions algorithm.

The intention is take option 2 and include it for JSF 2.0, because in theory should be 
handled as an implementation detail of the algorithm (anyway it could be good to update 
the documentation with the same advice used for retargetAttachedObjects).

For "action", "actionListener", "validator" and "valueChangeListener" it is clear that
the action to take is something like this: 

 - If target is a composite component and that one "retarget" to other components and 
   additionally does not implements [ActionSource2/EditableValueHolder], call:
   
   targetComponent.getAttributes().put(attributeName, attributeNameValueExpression);
   
   and call retargetMethodExpressions recursively. Take care of apply the method twice
   and if the property pointed by "attributeName" was already set, revert its effects. 
   
The tricky part is how to handle generic method expression properties. The javadoc says:

"....
    # Otherwise, assume that the MethodExpression should be placed in the 
      components attribute set. The runtme must create the MethodExpression 
      instance based on the value of the "method-signature" attribute.
....."

But I have identified three valid cases:

 1. testSimpleAttributeMethodExpressionEmpty.xhtml (Using an EL #{cc} reference)

    <testComposite:simpleAttributeMethodExpressionEmpty id="cc1" 
    customMethod="#{methodExpressionBean.doSomethingFunny}">
    </testComposite:simpleAttributeMethodExpressionEmpty>

    simpleAttributeMethodExpressionEmpty.xhtml

    <composite:interface>
        <composite:attribute 
        name="customMethod" 
        method-signature="String doSomething(String)"/>
    </composite:interface>
    <composite:implementation>
        <tc:testComponent id="testComponent" customMethod="#{cc.attrs.customMethod}"/>
    </composite:implementation>

 2. testSimpleAttributeMethodExpressionTarget.xhtml (Using "targets" to call 
    a property setter directly)

    <testComposite:simpleAttributeMethodExpressionTarget id="cc1"
     customMethod="#{methodExpressionBean.doSomethingFunny}">
    </testComposite:simpleAttributeMethodExpressionTarget>
    
   simpleAttributeMethodExpressionTarget.xhtml
   
   <composite:interface>
        <composite:attribute 
        name="customMethod" 
        method-signature="String doSomething(String)" 
        targets="testComponent"/>
   </composite:interface>
    <composite:implementation>
        <tc:testComponent id="testComponent"/>
    </composite:implementation>
    
 3. testCompositeAttributeMethodExpressionTarget.xhtml (Using "targets", 
    but the target component is a composite one)

    <testComposite:compositeAttributeMethodExpressionTarget id="cc1" 
    customMethod="#{methodExpressionBean.doSomethingFunny}">
    </testComposite:compositeAttributeMethodExpressionTarget>

    compositeAttributeMethodExpressionTarget.xhtml

    <composite:interface>
        <composite:attribute 
        name="customMethod" 
        method-signature="String doSomething(String)" 
        targets="simpleAttributeMethodExpressionTarget"/>
    </composite:interface>
    <composite:implementation>
        <testComposite:simpleAttributeMethodExpressionTarget id="simpleAttributeMethodExpressionTarget"/>
    </composite:implementation>
    
    simpleAttributeMethodExpressionTarget.xhtml (could be like in 1 or 2)

The case (1) actually works but the case (2) and (3) does not work on both 
MyFaces 2.0.2 and Mojarra 2.0.3 . 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (MYFACES-2946) composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions

Posted by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org>.
     [ https://issues.apache.org/jira/browse/MYFACES-2946?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Leonardo Uribe updated MYFACES-2946:
------------------------------------

    Status: Patch Available  (was: Open)

> composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-2946
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2946
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-314
>    Affects Versions: 2.0.2
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>         Attachments: MYFACES-2946-1.patch
>
>
> Some days ago, it was mentioned on myfaces dev list that "targets"
> attribute does not seem to work as expected. After review the available
> documentation and doing some test, my conclusion was the spec is good,
> but this part needs a little bit more documentation (and fix some 
> bugs), because there are use cases that are causing problems to users.
> Some of these problems has been already mentioned (spec issue 755) but
> my intention here is do a full and detailed analysis. 
> The property "targets" is used for these tags:
> composite:actionSource
> composite:editableValueHolder
> composite:valueHolder
> composite:clientBehavior
> composite:attribute
> For the first four cases, this property is used by :
> ViewDeclarationLanguage.retargetAttachedObjects(FacesContext context,
>                                     UIComponent topLevelComponent,
>                                     List<AttachedObjectHandler> handlers)
> In JSF 2.0 rev A it was made explicit the need to handle nested
> composite component with this lines:
> "... The implementation must support retargeting attached objects from 
> the top level compsite component to targets that are composite and 
> non-composite components ...."
> This is ok ;-).
> The problem is the description about how composite:attribute "targets" 
> property works does not match with the algorithm for:
> ViewDeclarationLanguage.retargetMethodExpressions(FacesContext context, 
>                                     UIComponent topLevelComponent)
> Here is the documentation about composite:attribute "targets":
> "... If this element has a method-signature attribute, 
> the value of the targets attribute must be interpreted as a space 
> (not tab) separated list of client ids (relative to the top level 
> component) of components within the <composite:implementation>  section. 
> Space is used as the delimiter for compatibility with the IDREFS and 
> NMTOKENS data types from the XML Schema. 
> Each entry in the list must be interpreted as the id of an inner 
> component to which the MethodExpression  from the composite component 
> tag in the using page must be applied. 
> If this element has a method-signature attribute, but no targets 
> attribute, the value of the name  attribute is used as the single entry 
> in the list. 
> If the value of the name  attribute is not one of the special values 
> listed in the description of the name attribute, targets  (or its 
> derived value) need not correspond to the id of an inner component ...".
> At this point everything seems to be ok. But look this documentation
> (I'll put the important points):
> ".....
>  # Get the value of the targets attribute. If the value is a ValueExpression 
>    evaluate it. If there is no targets attribute, let the name of the 
>    metadata element be the evaluated value of the targets attribute.
>  # Interpret targets as a space (not tab) separated list of ids. For each entry 
>    in the list:
>      ......
>     # If name is equal to the string "action" without the quotes, call 
>       ActionSource2.setActionExpression(javax.el.MethodExpression) on target, 
>       passing attributeMethodExpression.
>     # If name is equal to the string "actionListener" without the quotes, call 
>       ActionSource.addActionListener(javax.faces.event.ActionListener) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionActionListener.
>     # If name is equal to the string "validator" without the quotes, call 
>       EditableValueHolder.addValidator(javax.faces.validator.Validator) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionValidator.
>     # If name is equal to the string "valueChangeListener" without the quotes, call 
>       EditableValueHolder.addValueChangeListener(javax.faces.event.ValueChangeListener) 
>       on target, passing attributeMethodExpression wrapped in a 
>       MethodExpressionValueChangeListener.
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> My first interpretation of this javadoc was that "targets" only has sense for "action",
> "actionListener", "validator" and "valueChangeListener". But note if that's true,
> someone could expect something like the description on retargetAttachedObjects, right?
> The current behavior (Mojarra 2.0.3 and Myfaces 2.0.2) is the same, if we have two
> nested composite components, that will throw a ClassCastException. There is a issue already
> open for this one:
> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=755
> There are two possible alternatives here:
>  1. Implement the algorithm proposed for retargetMethodExpressions and ignore 
>     composite:attribute "targets" property says. 
>  2. Implement the expected behavior of composite:attribute "targets" property and make
>     some changes to retargetMethodExpressions algorithm.
> The intention is take option 2 and include it for JSF 2.0, because in theory should be 
> handled as an implementation detail of the algorithm (anyway it could be good to update 
> the documentation with the same advice used for retargetAttachedObjects).
> For "action", "actionListener", "validator" and "valueChangeListener" it is clear that
> the action to take is something like this: 
>  - If target is a composite component and that one "retarget" to other components and 
>    additionally does not implements [ActionSource2/EditableValueHolder], call:
>    
>    targetComponent.getAttributes().put(attributeName, attributeNameValueExpression);
>    
>    and call retargetMethodExpressions recursively. Take care of apply the method twice
>    and if the property pointed by "attributeName" was already set, revert its effects. 
>    
> The tricky part is how to handle generic method expression properties. The javadoc says:
> "....
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> But I have identified three valid cases:
>  1. testSimpleAttributeMethodExpressionEmpty.xhtml (Using an EL #{cc} reference)
>     <testComposite:simpleAttributeMethodExpressionEmpty id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionEmpty>
>     simpleAttributeMethodExpressionEmpty.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)"/>
>     </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent" customMethod="#{cc.attrs.customMethod}"/>
>     </composite:implementation>
>  2. testSimpleAttributeMethodExpressionTarget.xhtml (Using "targets" to call 
>     a property setter directly)
>     <testComposite:simpleAttributeMethodExpressionTarget id="cc1"
>      customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionTarget>
>     
>    simpleAttributeMethodExpressionTarget.xhtml
>    
>    <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="testComponent"/>
>    </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent"/>
>     </composite:implementation>
>     
>  3. testCompositeAttributeMethodExpressionTarget.xhtml (Using "targets", 
>     but the target component is a composite one)
>     <testComposite:compositeAttributeMethodExpressionTarget id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:compositeAttributeMethodExpressionTarget>
>     compositeAttributeMethodExpressionTarget.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="simpleAttributeMethodExpressionTarget"/>
>     </composite:interface>
>     <composite:implementation>
>         <testComposite:simpleAttributeMethodExpressionTarget id="simpleAttributeMethodExpressionTarget"/>
>     </composite:implementation>
>     
>     simpleAttributeMethodExpressionTarget.xhtml (could be like in 1 or 2)
> The case (1) actually works but the case (2) and (3) does not work on both 
> MyFaces 2.0.2 and Mojarra 2.0.3 . 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (MYFACES-2946) composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions

Posted by "Jakob Korherr (JIRA)" <de...@myfaces.apache.org>.
    [ https://issues.apache.org/jira/browse/MYFACES-2946?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12922511#action_12922511 ] 

Jakob Korherr commented on MYFACES-2946:
----------------------------------------

Also I was wondering: shouldn't it be possible to reference the known attributes (e.g. "action") also via #{cc.attrs.action}. The spec actually does not "allow" this, but I think it really should be possible, because this may really confuse users, because some attributes are available via #{cc.attrs} and some are not.

WDYT Leo?

> composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-2946
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2946
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-314
>    Affects Versions: 2.0.2
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>         Attachments: MYFACES-2946-1.patch
>
>
> Some days ago, it was mentioned on myfaces dev list that "targets"
> attribute does not seem to work as expected. After review the available
> documentation and doing some test, my conclusion was the spec is good,
> but this part needs a little bit more documentation (and fix some 
> bugs), because there are use cases that are causing problems to users.
> Some of these problems has been already mentioned (spec issue 755) but
> my intention here is do a full and detailed analysis. 
> The property "targets" is used for these tags:
> composite:actionSource
> composite:editableValueHolder
> composite:valueHolder
> composite:clientBehavior
> composite:attribute
> For the first four cases, this property is used by :
> ViewDeclarationLanguage.retargetAttachedObjects(FacesContext context,
>                                     UIComponent topLevelComponent,
>                                     List<AttachedObjectHandler> handlers)
> In JSF 2.0 rev A it was made explicit the need to handle nested
> composite component with this lines:
> "... The implementation must support retargeting attached objects from 
> the top level compsite component to targets that are composite and 
> non-composite components ...."
> This is ok ;-).
> The problem is the description about how composite:attribute "targets" 
> property works does not match with the algorithm for:
> ViewDeclarationLanguage.retargetMethodExpressions(FacesContext context, 
>                                     UIComponent topLevelComponent)
> Here is the documentation about composite:attribute "targets":
> "... If this element has a method-signature attribute, 
> the value of the targets attribute must be interpreted as a space 
> (not tab) separated list of client ids (relative to the top level 
> component) of components within the <composite:implementation>  section. 
> Space is used as the delimiter for compatibility with the IDREFS and 
> NMTOKENS data types from the XML Schema. 
> Each entry in the list must be interpreted as the id of an inner 
> component to which the MethodExpression  from the composite component 
> tag in the using page must be applied. 
> If this element has a method-signature attribute, but no targets 
> attribute, the value of the name  attribute is used as the single entry 
> in the list. 
> If the value of the name  attribute is not one of the special values 
> listed in the description of the name attribute, targets  (or its 
> derived value) need not correspond to the id of an inner component ...".
> At this point everything seems to be ok. But look this documentation
> (I'll put the important points):
> ".....
>  # Get the value of the targets attribute. If the value is a ValueExpression 
>    evaluate it. If there is no targets attribute, let the name of the 
>    metadata element be the evaluated value of the targets attribute.
>  # Interpret targets as a space (not tab) separated list of ids. For each entry 
>    in the list:
>      ......
>     # If name is equal to the string "action" without the quotes, call 
>       ActionSource2.setActionExpression(javax.el.MethodExpression) on target, 
>       passing attributeMethodExpression.
>     # If name is equal to the string "actionListener" without the quotes, call 
>       ActionSource.addActionListener(javax.faces.event.ActionListener) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionActionListener.
>     # If name is equal to the string "validator" without the quotes, call 
>       EditableValueHolder.addValidator(javax.faces.validator.Validator) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionValidator.
>     # If name is equal to the string "valueChangeListener" without the quotes, call 
>       EditableValueHolder.addValueChangeListener(javax.faces.event.ValueChangeListener) 
>       on target, passing attributeMethodExpression wrapped in a 
>       MethodExpressionValueChangeListener.
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> My first interpretation of this javadoc was that "targets" only has sense for "action",
> "actionListener", "validator" and "valueChangeListener". But note if that's true,
> someone could expect something like the description on retargetAttachedObjects, right?
> The current behavior (Mojarra 2.0.3 and Myfaces 2.0.2) is the same, if we have two
> nested composite components, that will throw a ClassCastException. There is a issue already
> open for this one:
> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=755
> There are two possible alternatives here:
>  1. Implement the algorithm proposed for retargetMethodExpressions and ignore 
>     composite:attribute "targets" property says. 
>  2. Implement the expected behavior of composite:attribute "targets" property and make
>     some changes to retargetMethodExpressions algorithm.
> The intention is take option 2 and include it for JSF 2.0, because in theory should be 
> handled as an implementation detail of the algorithm (anyway it could be good to update 
> the documentation with the same advice used for retargetAttachedObjects).
> For "action", "actionListener", "validator" and "valueChangeListener" it is clear that
> the action to take is something like this: 
>  - If target is a composite component and that one "retarget" to other components and 
>    additionally does not implements [ActionSource2/EditableValueHolder], call:
>    
>    targetComponent.getAttributes().put(attributeName, attributeNameValueExpression);
>    
>    and call retargetMethodExpressions recursively. Take care of apply the method twice
>    and if the property pointed by "attributeName" was already set, revert its effects. 
>    
> The tricky part is how to handle generic method expression properties. The javadoc says:
> "....
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> But I have identified three valid cases:
>  1. testSimpleAttributeMethodExpressionEmpty.xhtml (Using an EL #{cc} reference)
>     <testComposite:simpleAttributeMethodExpressionEmpty id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionEmpty>
>     simpleAttributeMethodExpressionEmpty.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)"/>
>     </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent" customMethod="#{cc.attrs.customMethod}"/>
>     </composite:implementation>
>  2. testSimpleAttributeMethodExpressionTarget.xhtml (Using "targets" to call 
>     a property setter directly)
>     <testComposite:simpleAttributeMethodExpressionTarget id="cc1"
>      customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionTarget>
>     
>    simpleAttributeMethodExpressionTarget.xhtml
>    
>    <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="testComponent"/>
>    </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent"/>
>     </composite:implementation>
>     
>  3. testCompositeAttributeMethodExpressionTarget.xhtml (Using "targets", 
>     but the target component is a composite one)
>     <testComposite:compositeAttributeMethodExpressionTarget id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:compositeAttributeMethodExpressionTarget>
>     compositeAttributeMethodExpressionTarget.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="simpleAttributeMethodExpressionTarget"/>
>     </composite:interface>
>     <composite:implementation>
>         <testComposite:simpleAttributeMethodExpressionTarget id="simpleAttributeMethodExpressionTarget"/>
>     </composite:implementation>
>     
>     simpleAttributeMethodExpressionTarget.xhtml (could be like in 1 or 2)
> The case (1) actually works but the case (2) and (3) does not work on both 
> MyFaces 2.0.2 and Mojarra 2.0.3 . 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Reopened: (MYFACES-2946) composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions

Posted by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org>.
     [ https://issues.apache.org/jira/browse/MYFACES-2946?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Leonardo Uribe reopened MYFACES-2946:
-------------------------------------


Checking how this algorithm works, I found a misunderstanding between two concepts:

- It is necessary to save the object created for actionListener, validator and valueChangeListener, so we can revert them later when we resolve a nested retargetMethodExpressions. That should be saved for each target component.
- It is necessary to mark the attribute on the composite component parent, to prevent apply twice the algorithm when a nested retargetMethodExpressions is called.

For do both I tried to use just one map, but clearly the intention require use a different map for each one of them, so we need to refactor the algorithm properly.

> composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-2946
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2946
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-314
>    Affects Versions: 2.0.2
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>             Fix For: 2.0.3-SNAPSHOT
>
>         Attachments: MYFACES-2946-1.patch
>
>
> Some days ago, it was mentioned on myfaces dev list that "targets"
> attribute does not seem to work as expected. After review the available
> documentation and doing some test, my conclusion was the spec is good,
> but this part needs a little bit more documentation (and fix some 
> bugs), because there are use cases that are causing problems to users.
> Some of these problems has been already mentioned (spec issue 755) but
> my intention here is do a full and detailed analysis. 
> The property "targets" is used for these tags:
> composite:actionSource
> composite:editableValueHolder
> composite:valueHolder
> composite:clientBehavior
> composite:attribute
> For the first four cases, this property is used by :
> ViewDeclarationLanguage.retargetAttachedObjects(FacesContext context,
>                                     UIComponent topLevelComponent,
>                                     List<AttachedObjectHandler> handlers)
> In JSF 2.0 rev A it was made explicit the need to handle nested
> composite component with this lines:
> "... The implementation must support retargeting attached objects from 
> the top level compsite component to targets that are composite and 
> non-composite components ...."
> This is ok ;-).
> The problem is the description about how composite:attribute "targets" 
> property works does not match with the algorithm for:
> ViewDeclarationLanguage.retargetMethodExpressions(FacesContext context, 
>                                     UIComponent topLevelComponent)
> Here is the documentation about composite:attribute "targets":
> "... If this element has a method-signature attribute, 
> the value of the targets attribute must be interpreted as a space 
> (not tab) separated list of client ids (relative to the top level 
> component) of components within the <composite:implementation>  section. 
> Space is used as the delimiter for compatibility with the IDREFS and 
> NMTOKENS data types from the XML Schema. 
> Each entry in the list must be interpreted as the id of an inner 
> component to which the MethodExpression  from the composite component 
> tag in the using page must be applied. 
> If this element has a method-signature attribute, but no targets 
> attribute, the value of the name  attribute is used as the single entry 
> in the list. 
> If the value of the name  attribute is not one of the special values 
> listed in the description of the name attribute, targets  (or its 
> derived value) need not correspond to the id of an inner component ...".
> At this point everything seems to be ok. But look this documentation
> (I'll put the important points):
> ".....
>  # Get the value of the targets attribute. If the value is a ValueExpression 
>    evaluate it. If there is no targets attribute, let the name of the 
>    metadata element be the evaluated value of the targets attribute.
>  # Interpret targets as a space (not tab) separated list of ids. For each entry 
>    in the list:
>      ......
>     # If name is equal to the string "action" without the quotes, call 
>       ActionSource2.setActionExpression(javax.el.MethodExpression) on target, 
>       passing attributeMethodExpression.
>     # If name is equal to the string "actionListener" without the quotes, call 
>       ActionSource.addActionListener(javax.faces.event.ActionListener) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionActionListener.
>     # If name is equal to the string "validator" without the quotes, call 
>       EditableValueHolder.addValidator(javax.faces.validator.Validator) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionValidator.
>     # If name is equal to the string "valueChangeListener" without the quotes, call 
>       EditableValueHolder.addValueChangeListener(javax.faces.event.ValueChangeListener) 
>       on target, passing attributeMethodExpression wrapped in a 
>       MethodExpressionValueChangeListener.
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> My first interpretation of this javadoc was that "targets" only has sense for "action",
> "actionListener", "validator" and "valueChangeListener". But note if that's true,
> someone could expect something like the description on retargetAttachedObjects, right?
> The current behavior (Mojarra 2.0.3 and Myfaces 2.0.2) is the same, if we have two
> nested composite components, that will throw a ClassCastException. There is a issue already
> open for this one:
> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=755
> There are two possible alternatives here:
>  1. Implement the algorithm proposed for retargetMethodExpressions and ignore 
>     composite:attribute "targets" property says. 
>  2. Implement the expected behavior of composite:attribute "targets" property and make
>     some changes to retargetMethodExpressions algorithm.
> The intention is take option 2 and include it for JSF 2.0, because in theory should be 
> handled as an implementation detail of the algorithm (anyway it could be good to update 
> the documentation with the same advice used for retargetAttachedObjects).
> For "action", "actionListener", "validator" and "valueChangeListener" it is clear that
> the action to take is something like this: 
>  - If target is a composite component and that one "retarget" to other components and 
>    additionally does not implements [ActionSource2/EditableValueHolder], call:
>    
>    targetComponent.getAttributes().put(attributeName, attributeNameValueExpression);
>    
>    and call retargetMethodExpressions recursively. Take care of apply the method twice
>    and if the property pointed by "attributeName" was already set, revert its effects. 
>    
> The tricky part is how to handle generic method expression properties. The javadoc says:
> "....
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> But I have identified three valid cases:
>  1. testSimpleAttributeMethodExpressionEmpty.xhtml (Using an EL #{cc} reference)
>     <testComposite:simpleAttributeMethodExpressionEmpty id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionEmpty>
>     simpleAttributeMethodExpressionEmpty.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)"/>
>     </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent" customMethod="#{cc.attrs.customMethod}"/>
>     </composite:implementation>
>  2. testSimpleAttributeMethodExpressionTarget.xhtml (Using "targets" to call 
>     a property setter directly)
>     <testComposite:simpleAttributeMethodExpressionTarget id="cc1"
>      customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionTarget>
>     
>    simpleAttributeMethodExpressionTarget.xhtml
>    
>    <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="testComponent"/>
>    </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent"/>
>     </composite:implementation>
>     
>  3. testCompositeAttributeMethodExpressionTarget.xhtml (Using "targets", 
>     but the target component is a composite one)
>     <testComposite:compositeAttributeMethodExpressionTarget id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:compositeAttributeMethodExpressionTarget>
>     compositeAttributeMethodExpressionTarget.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="simpleAttributeMethodExpressionTarget"/>
>     </composite:interface>
>     <composite:implementation>
>         <testComposite:simpleAttributeMethodExpressionTarget id="simpleAttributeMethodExpressionTarget"/>
>     </composite:implementation>
>     
>     simpleAttributeMethodExpressionTarget.xhtml (could be like in 1 or 2)
> The case (1) actually works but the case (2) and (3) does not work on both 
> MyFaces 2.0.2 and Mojarra 2.0.3 . 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (MYFACES-2946) composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions

Posted by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org>.
     [ https://issues.apache.org/jira/browse/MYFACES-2946?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Leonardo Uribe resolved MYFACES-2946.
-------------------------------------

    Resolution: Fixed

> composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-2946
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2946
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-314
>    Affects Versions: 2.0.2
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>             Fix For: 2.0.3-SNAPSHOT
>
>         Attachments: MYFACES-2946-1.patch
>
>
> Some days ago, it was mentioned on myfaces dev list that "targets"
> attribute does not seem to work as expected. After review the available
> documentation and doing some test, my conclusion was the spec is good,
> but this part needs a little bit more documentation (and fix some 
> bugs), because there are use cases that are causing problems to users.
> Some of these problems has been already mentioned (spec issue 755) but
> my intention here is do a full and detailed analysis. 
> The property "targets" is used for these tags:
> composite:actionSource
> composite:editableValueHolder
> composite:valueHolder
> composite:clientBehavior
> composite:attribute
> For the first four cases, this property is used by :
> ViewDeclarationLanguage.retargetAttachedObjects(FacesContext context,
>                                     UIComponent topLevelComponent,
>                                     List<AttachedObjectHandler> handlers)
> In JSF 2.0 rev A it was made explicit the need to handle nested
> composite component with this lines:
> "... The implementation must support retargeting attached objects from 
> the top level compsite component to targets that are composite and 
> non-composite components ...."
> This is ok ;-).
> The problem is the description about how composite:attribute "targets" 
> property works does not match with the algorithm for:
> ViewDeclarationLanguage.retargetMethodExpressions(FacesContext context, 
>                                     UIComponent topLevelComponent)
> Here is the documentation about composite:attribute "targets":
> "... If this element has a method-signature attribute, 
> the value of the targets attribute must be interpreted as a space 
> (not tab) separated list of client ids (relative to the top level 
> component) of components within the <composite:implementation>  section. 
> Space is used as the delimiter for compatibility with the IDREFS and 
> NMTOKENS data types from the XML Schema. 
> Each entry in the list must be interpreted as the id of an inner 
> component to which the MethodExpression  from the composite component 
> tag in the using page must be applied. 
> If this element has a method-signature attribute, but no targets 
> attribute, the value of the name  attribute is used as the single entry 
> in the list. 
> If the value of the name  attribute is not one of the special values 
> listed in the description of the name attribute, targets  (or its 
> derived value) need not correspond to the id of an inner component ...".
> At this point everything seems to be ok. But look this documentation
> (I'll put the important points):
> ".....
>  # Get the value of the targets attribute. If the value is a ValueExpression 
>    evaluate it. If there is no targets attribute, let the name of the 
>    metadata element be the evaluated value of the targets attribute.
>  # Interpret targets as a space (not tab) separated list of ids. For each entry 
>    in the list:
>      ......
>     # If name is equal to the string "action" without the quotes, call 
>       ActionSource2.setActionExpression(javax.el.MethodExpression) on target, 
>       passing attributeMethodExpression.
>     # If name is equal to the string "actionListener" without the quotes, call 
>       ActionSource.addActionListener(javax.faces.event.ActionListener) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionActionListener.
>     # If name is equal to the string "validator" without the quotes, call 
>       EditableValueHolder.addValidator(javax.faces.validator.Validator) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionValidator.
>     # If name is equal to the string "valueChangeListener" without the quotes, call 
>       EditableValueHolder.addValueChangeListener(javax.faces.event.ValueChangeListener) 
>       on target, passing attributeMethodExpression wrapped in a 
>       MethodExpressionValueChangeListener.
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> My first interpretation of this javadoc was that "targets" only has sense for "action",
> "actionListener", "validator" and "valueChangeListener". But note if that's true,
> someone could expect something like the description on retargetAttachedObjects, right?
> The current behavior (Mojarra 2.0.3 and Myfaces 2.0.2) is the same, if we have two
> nested composite components, that will throw a ClassCastException. There is a issue already
> open for this one:
> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=755
> There are two possible alternatives here:
>  1. Implement the algorithm proposed for retargetMethodExpressions and ignore 
>     composite:attribute "targets" property says. 
>  2. Implement the expected behavior of composite:attribute "targets" property and make
>     some changes to retargetMethodExpressions algorithm.
> The intention is take option 2 and include it for JSF 2.0, because in theory should be 
> handled as an implementation detail of the algorithm (anyway it could be good to update 
> the documentation with the same advice used for retargetAttachedObjects).
> For "action", "actionListener", "validator" and "valueChangeListener" it is clear that
> the action to take is something like this: 
>  - If target is a composite component and that one "retarget" to other components and 
>    additionally does not implements [ActionSource2/EditableValueHolder], call:
>    
>    targetComponent.getAttributes().put(attributeName, attributeNameValueExpression);
>    
>    and call retargetMethodExpressions recursively. Take care of apply the method twice
>    and if the property pointed by "attributeName" was already set, revert its effects. 
>    
> The tricky part is how to handle generic method expression properties. The javadoc says:
> "....
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> But I have identified three valid cases:
>  1. testSimpleAttributeMethodExpressionEmpty.xhtml (Using an EL #{cc} reference)
>     <testComposite:simpleAttributeMethodExpressionEmpty id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionEmpty>
>     simpleAttributeMethodExpressionEmpty.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)"/>
>     </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent" customMethod="#{cc.attrs.customMethod}"/>
>     </composite:implementation>
>  2. testSimpleAttributeMethodExpressionTarget.xhtml (Using "targets" to call 
>     a property setter directly)
>     <testComposite:simpleAttributeMethodExpressionTarget id="cc1"
>      customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionTarget>
>     
>    simpleAttributeMethodExpressionTarget.xhtml
>    
>    <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="testComponent"/>
>    </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent"/>
>     </composite:implementation>
>     
>  3. testCompositeAttributeMethodExpressionTarget.xhtml (Using "targets", 
>     but the target component is a composite one)
>     <testComposite:compositeAttributeMethodExpressionTarget id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:compositeAttributeMethodExpressionTarget>
>     compositeAttributeMethodExpressionTarget.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="simpleAttributeMethodExpressionTarget"/>
>     </composite:interface>
>     <composite:implementation>
>         <testComposite:simpleAttributeMethodExpressionTarget id="simpleAttributeMethodExpressionTarget"/>
>     </composite:implementation>
>     
>     simpleAttributeMethodExpressionTarget.xhtml (could be like in 1 or 2)
> The case (1) actually works but the case (2) and (3) does not work on both 
> MyFaces 2.0.2 and Mojarra 2.0.3 . 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (MYFACES-2946) composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions

Posted by "Leonardo Uribe (JIRA)" <de...@myfaces.apache.org>.
     [ https://issues.apache.org/jira/browse/MYFACES-2946?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Leonardo Uribe updated MYFACES-2946:
------------------------------------

       Resolution: Fixed
    Fix Version/s: 2.0.3-SNAPSHOT
           Status: Resolved  (was: Patch Available)

Unfortunately, we can't do that, because that is not explicit on the spec javadoc, and there is a way to do what is expected using "targets" property.

> composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-2946
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2946
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-314
>    Affects Versions: 2.0.2
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>             Fix For: 2.0.3-SNAPSHOT
>
>         Attachments: MYFACES-2946-1.patch
>
>
> Some days ago, it was mentioned on myfaces dev list that "targets"
> attribute does not seem to work as expected. After review the available
> documentation and doing some test, my conclusion was the spec is good,
> but this part needs a little bit more documentation (and fix some 
> bugs), because there are use cases that are causing problems to users.
> Some of these problems has been already mentioned (spec issue 755) but
> my intention here is do a full and detailed analysis. 
> The property "targets" is used for these tags:
> composite:actionSource
> composite:editableValueHolder
> composite:valueHolder
> composite:clientBehavior
> composite:attribute
> For the first four cases, this property is used by :
> ViewDeclarationLanguage.retargetAttachedObjects(FacesContext context,
>                                     UIComponent topLevelComponent,
>                                     List<AttachedObjectHandler> handlers)
> In JSF 2.0 rev A it was made explicit the need to handle nested
> composite component with this lines:
> "... The implementation must support retargeting attached objects from 
> the top level compsite component to targets that are composite and 
> non-composite components ...."
> This is ok ;-).
> The problem is the description about how composite:attribute "targets" 
> property works does not match with the algorithm for:
> ViewDeclarationLanguage.retargetMethodExpressions(FacesContext context, 
>                                     UIComponent topLevelComponent)
> Here is the documentation about composite:attribute "targets":
> "... If this element has a method-signature attribute, 
> the value of the targets attribute must be interpreted as a space 
> (not tab) separated list of client ids (relative to the top level 
> component) of components within the <composite:implementation>  section. 
> Space is used as the delimiter for compatibility with the IDREFS and 
> NMTOKENS data types from the XML Schema. 
> Each entry in the list must be interpreted as the id of an inner 
> component to which the MethodExpression  from the composite component 
> tag in the using page must be applied. 
> If this element has a method-signature attribute, but no targets 
> attribute, the value of the name  attribute is used as the single entry 
> in the list. 
> If the value of the name  attribute is not one of the special values 
> listed in the description of the name attribute, targets  (or its 
> derived value) need not correspond to the id of an inner component ...".
> At this point everything seems to be ok. But look this documentation
> (I'll put the important points):
> ".....
>  # Get the value of the targets attribute. If the value is a ValueExpression 
>    evaluate it. If there is no targets attribute, let the name of the 
>    metadata element be the evaluated value of the targets attribute.
>  # Interpret targets as a space (not tab) separated list of ids. For each entry 
>    in the list:
>      ......
>     # If name is equal to the string "action" without the quotes, call 
>       ActionSource2.setActionExpression(javax.el.MethodExpression) on target, 
>       passing attributeMethodExpression.
>     # If name is equal to the string "actionListener" without the quotes, call 
>       ActionSource.addActionListener(javax.faces.event.ActionListener) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionActionListener.
>     # If name is equal to the string "validator" without the quotes, call 
>       EditableValueHolder.addValidator(javax.faces.validator.Validator) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionValidator.
>     # If name is equal to the string "valueChangeListener" without the quotes, call 
>       EditableValueHolder.addValueChangeListener(javax.faces.event.ValueChangeListener) 
>       on target, passing attributeMethodExpression wrapped in a 
>       MethodExpressionValueChangeListener.
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> My first interpretation of this javadoc was that "targets" only has sense for "action",
> "actionListener", "validator" and "valueChangeListener". But note if that's true,
> someone could expect something like the description on retargetAttachedObjects, right?
> The current behavior (Mojarra 2.0.3 and Myfaces 2.0.2) is the same, if we have two
> nested composite components, that will throw a ClassCastException. There is a issue already
> open for this one:
> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=755
> There are two possible alternatives here:
>  1. Implement the algorithm proposed for retargetMethodExpressions and ignore 
>     composite:attribute "targets" property says. 
>  2. Implement the expected behavior of composite:attribute "targets" property and make
>     some changes to retargetMethodExpressions algorithm.
> The intention is take option 2 and include it for JSF 2.0, because in theory should be 
> handled as an implementation detail of the algorithm (anyway it could be good to update 
> the documentation with the same advice used for retargetAttachedObjects).
> For "action", "actionListener", "validator" and "valueChangeListener" it is clear that
> the action to take is something like this: 
>  - If target is a composite component and that one "retarget" to other components and 
>    additionally does not implements [ActionSource2/EditableValueHolder], call:
>    
>    targetComponent.getAttributes().put(attributeName, attributeNameValueExpression);
>    
>    and call retargetMethodExpressions recursively. Take care of apply the method twice
>    and if the property pointed by "attributeName" was already set, revert its effects. 
>    
> The tricky part is how to handle generic method expression properties. The javadoc says:
> "....
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> But I have identified three valid cases:
>  1. testSimpleAttributeMethodExpressionEmpty.xhtml (Using an EL #{cc} reference)
>     <testComposite:simpleAttributeMethodExpressionEmpty id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionEmpty>
>     simpleAttributeMethodExpressionEmpty.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)"/>
>     </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent" customMethod="#{cc.attrs.customMethod}"/>
>     </composite:implementation>
>  2. testSimpleAttributeMethodExpressionTarget.xhtml (Using "targets" to call 
>     a property setter directly)
>     <testComposite:simpleAttributeMethodExpressionTarget id="cc1"
>      customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionTarget>
>     
>    simpleAttributeMethodExpressionTarget.xhtml
>    
>    <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="testComponent"/>
>    </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent"/>
>     </composite:implementation>
>     
>  3. testCompositeAttributeMethodExpressionTarget.xhtml (Using "targets", 
>     but the target component is a composite one)
>     <testComposite:compositeAttributeMethodExpressionTarget id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:compositeAttributeMethodExpressionTarget>
>     compositeAttributeMethodExpressionTarget.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="simpleAttributeMethodExpressionTarget"/>
>     </composite:interface>
>     <composite:implementation>
>         <testComposite:simpleAttributeMethodExpressionTarget id="simpleAttributeMethodExpressionTarget"/>
>     </composite:implementation>
>     
>     simpleAttributeMethodExpressionTarget.xhtml (could be like in 1 or 2)
> The case (1) actually works but the case (2) and (3) does not work on both 
> MyFaces 2.0.2 and Mojarra 2.0.3 . 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (MYFACES-2946) composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions

Posted by "Jakob Korherr (JIRA)" <de...@myfaces.apache.org>.
    [ https://issues.apache.org/jira/browse/MYFACES-2946?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12922508#action_12922508 ] 

Jakob Korherr commented on MYFACES-2946:
----------------------------------------

The patch looks very good. +1 for committing it!

> composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-2946
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2946
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-314
>    Affects Versions: 2.0.2
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>         Attachments: MYFACES-2946-1.patch
>
>
> Some days ago, it was mentioned on myfaces dev list that "targets"
> attribute does not seem to work as expected. After review the available
> documentation and doing some test, my conclusion was the spec is good,
> but this part needs a little bit more documentation (and fix some 
> bugs), because there are use cases that are causing problems to users.
> Some of these problems has been already mentioned (spec issue 755) but
> my intention here is do a full and detailed analysis. 
> The property "targets" is used for these tags:
> composite:actionSource
> composite:editableValueHolder
> composite:valueHolder
> composite:clientBehavior
> composite:attribute
> For the first four cases, this property is used by :
> ViewDeclarationLanguage.retargetAttachedObjects(FacesContext context,
>                                     UIComponent topLevelComponent,
>                                     List<AttachedObjectHandler> handlers)
> In JSF 2.0 rev A it was made explicit the need to handle nested
> composite component with this lines:
> "... The implementation must support retargeting attached objects from 
> the top level compsite component to targets that are composite and 
> non-composite components ...."
> This is ok ;-).
> The problem is the description about how composite:attribute "targets" 
> property works does not match with the algorithm for:
> ViewDeclarationLanguage.retargetMethodExpressions(FacesContext context, 
>                                     UIComponent topLevelComponent)
> Here is the documentation about composite:attribute "targets":
> "... If this element has a method-signature attribute, 
> the value of the targets attribute must be interpreted as a space 
> (not tab) separated list of client ids (relative to the top level 
> component) of components within the <composite:implementation>  section. 
> Space is used as the delimiter for compatibility with the IDREFS and 
> NMTOKENS data types from the XML Schema. 
> Each entry in the list must be interpreted as the id of an inner 
> component to which the MethodExpression  from the composite component 
> tag in the using page must be applied. 
> If this element has a method-signature attribute, but no targets 
> attribute, the value of the name  attribute is used as the single entry 
> in the list. 
> If the value of the name  attribute is not one of the special values 
> listed in the description of the name attribute, targets  (or its 
> derived value) need not correspond to the id of an inner component ...".
> At this point everything seems to be ok. But look this documentation
> (I'll put the important points):
> ".....
>  # Get the value of the targets attribute. If the value is a ValueExpression 
>    evaluate it. If there is no targets attribute, let the name of the 
>    metadata element be the evaluated value of the targets attribute.
>  # Interpret targets as a space (not tab) separated list of ids. For each entry 
>    in the list:
>      ......
>     # If name is equal to the string "action" without the quotes, call 
>       ActionSource2.setActionExpression(javax.el.MethodExpression) on target, 
>       passing attributeMethodExpression.
>     # If name is equal to the string "actionListener" without the quotes, call 
>       ActionSource.addActionListener(javax.faces.event.ActionListener) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionActionListener.
>     # If name is equal to the string "validator" without the quotes, call 
>       EditableValueHolder.addValidator(javax.faces.validator.Validator) on target, 
>       passing attributeMethodExpression wrapped in a MethodExpressionValidator.
>     # If name is equal to the string "valueChangeListener" without the quotes, call 
>       EditableValueHolder.addValueChangeListener(javax.faces.event.ValueChangeListener) 
>       on target, passing attributeMethodExpression wrapped in a 
>       MethodExpressionValueChangeListener.
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> My first interpretation of this javadoc was that "targets" only has sense for "action",
> "actionListener", "validator" and "valueChangeListener". But note if that's true,
> someone could expect something like the description on retargetAttachedObjects, right?
> The current behavior (Mojarra 2.0.3 and Myfaces 2.0.2) is the same, if we have two
> nested composite components, that will throw a ClassCastException. There is a issue already
> open for this one:
> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=755
> There are two possible alternatives here:
>  1. Implement the algorithm proposed for retargetMethodExpressions and ignore 
>     composite:attribute "targets" property says. 
>  2. Implement the expected behavior of composite:attribute "targets" property and make
>     some changes to retargetMethodExpressions algorithm.
> The intention is take option 2 and include it for JSF 2.0, because in theory should be 
> handled as an implementation detail of the algorithm (anyway it could be good to update 
> the documentation with the same advice used for retargetAttachedObjects).
> For "action", "actionListener", "validator" and "valueChangeListener" it is clear that
> the action to take is something like this: 
>  - If target is a composite component and that one "retarget" to other components and 
>    additionally does not implements [ActionSource2/EditableValueHolder], call:
>    
>    targetComponent.getAttributes().put(attributeName, attributeNameValueExpression);
>    
>    and call retargetMethodExpressions recursively. Take care of apply the method twice
>    and if the property pointed by "attributeName" was already set, revert its effects. 
>    
> The tricky part is how to handle generic method expression properties. The javadoc says:
> "....
>     # Otherwise, assume that the MethodExpression should be placed in the 
>       components attribute set. The runtme must create the MethodExpression 
>       instance based on the value of the "method-signature" attribute.
> ....."
> But I have identified three valid cases:
>  1. testSimpleAttributeMethodExpressionEmpty.xhtml (Using an EL #{cc} reference)
>     <testComposite:simpleAttributeMethodExpressionEmpty id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionEmpty>
>     simpleAttributeMethodExpressionEmpty.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)"/>
>     </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent" customMethod="#{cc.attrs.customMethod}"/>
>     </composite:implementation>
>  2. testSimpleAttributeMethodExpressionTarget.xhtml (Using "targets" to call 
>     a property setter directly)
>     <testComposite:simpleAttributeMethodExpressionTarget id="cc1"
>      customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:simpleAttributeMethodExpressionTarget>
>     
>    simpleAttributeMethodExpressionTarget.xhtml
>    
>    <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="testComponent"/>
>    </composite:interface>
>     <composite:implementation>
>         <tc:testComponent id="testComponent"/>
>     </composite:implementation>
>     
>  3. testCompositeAttributeMethodExpressionTarget.xhtml (Using "targets", 
>     but the target component is a composite one)
>     <testComposite:compositeAttributeMethodExpressionTarget id="cc1" 
>     customMethod="#{methodExpressionBean.doSomethingFunny}">
>     </testComposite:compositeAttributeMethodExpressionTarget>
>     compositeAttributeMethodExpressionTarget.xhtml
>     <composite:interface>
>         <composite:attribute 
>         name="customMethod" 
>         method-signature="String doSomething(String)" 
>         targets="simpleAttributeMethodExpressionTarget"/>
>     </composite:interface>
>     <composite:implementation>
>         <testComposite:simpleAttributeMethodExpressionTarget id="simpleAttributeMethodExpressionTarget"/>
>     </composite:implementation>
>     
>     simpleAttributeMethodExpressionTarget.xhtml (could be like in 1 or 2)
> The case (1) actually works but the case (2) and (3) does not work on both 
> MyFaces 2.0.2 and Mojarra 2.0.3 . 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.