[jsr-314-open-mirror] [jsr-314-open] composite:attribute "targets" property does not match with ViewDeclarationLanguage.retargetMethodExpressions

Ganesh ganesh at j4fry.org
Sat Oct 23 03:46:13 EDT 2010


Please follow Jakob's proposal on adding action, actionListener, valueChangeListener and validator the attributes map (#{cc.attrs.action}, #{cc.attrs.actionListener}, #{cc.attrs.valueChangeListener}, #{cc.attrs.validator}). This is what a developer would expect to happen (at least I did so) and one could easily pass them on to nested components.

Martin, I like your proposal on deprecating "targets". But how would you then handle this case: Using a cc I nest <f:actionListener "for=a" ... /> and inside the cc there is a <cc:actionSource name="a" targets="b, c" /> where b and c are buttons? The logic of the "for" attributes only includes this: "If present, this attribute refers to the value of *one* of the exposed attached objects within the composite component inside of which this tag is nested." IMO deprecating "targets" would require opening "for" to refer to *multiple* exposed attached objects within the composite component inside of which this tag is nested just the way targets is doing this right now. "targets" kind of bundles them right now.

To make this more convenient omitting "for" could simply be a synonym representing a "for" for *all* nested actionSources, actionSource2s and CCs.

Best regards,
Ganesh

After all the difficulties I had understanding what targets is good for with nested actionLiteners this is really a pity :-)

Am 22.10.2010 12:33, schrieb Martin Marinschek:
> Hi guys,
>
> my strong believe is that the target attribute should be immediately deprecated.
>
> It is wrongly placed where it is right now - an interface definition
> should never provide hooks into the implementation. It should only
> provide a meaningful context to which the implementation can refer.
> Someone from the outside wants to pass stuff to someone else, the
> interface defines what name this stuff receives. I have not seen
> something like the target attribute anywhere else in any interface
> definition language - but maybe this is just my lack of experience.
>
> I am sorry I haven't voiced this objection before - but at the time
> this was discussed I was not very active on the EG, and then it was
> too late to talk about this.
>
> best regards,
>
> Martin
>
> On 10/22/10, Jakob Korherr<jakob.korherr at gmail.com>  wrote:
>> Hi,
>>
>> I think we should do this a little differently:
>>
>> 1) try to add the e.g. ActionListener to the component specified in
>> the targets attribute, if possible. If it is not possible, log a
>> warning.
>>
>> 2) also expose the "well-known" attributes ("action",
>> "actionListener", ...) on the composite component attribute map, this
>> means being able to access the action attribute via #{cc.attrs.action}
>> (currently not possible, because those attributes are not put on the
>> attribute map).
>>
>> Thus the user can use the targets attribute if he/she wants to (and of
>> course, if it is possible) and also use #{cc.attrs.action} to refer to
>> the action attribute (like to any other attribute).
>>
>> Frankly I really don't understand why this was separated in the first
>> place. Of course, the targets attribute is neat, but IMHO it is also
>> kinda confusing. I find it a lot easier to access _every_ attribute
>> (regardless if well-known or custom) via #{cc.attrs.attributeName}.
>> Furthermore using this approach you can support nesting normal
>> components and also nesting composite components.
>>
>> In addition the targets attribute can't solve a scenario in which the
>> action attribute of the inner component is required (most likely the
>> attribute from a composite component), because you need to enter a
>> value for the attribute, but you currently can't use
>> #{cc.attrs.action}, because this one points "nowhere".
>>
>> Regards,
>> Jakob
>>
>> 2010/10/19 Leonardo Uribe<lu4242 at gmail.com>:
>>> Hi
>>>
>>> 2010/10/19 Ed Burns<edward.burns at oracle.com>
>>>>
>>>>>>>>> On Mon, 18 Oct 2010 20:36:06 -0500, Leonardo Uribe
>>>>>>>>> <lu4242 at gmail.com>  said:
>>>>
>>>> [...]
>>>>
>>>> LU>  There are two possible alternatives here:
>>>>
>>>> LU>    1. Implement the algorithm proposed for retargetMethodExpressions
>>>> LU>  and ignore composite:attribute "targets" property says.
>>>>
>>>> LU>    2. Implement the expected behavior of composite:attribute "targets"
>>>> LU>  property and make some changes to retargetMethodExpressions
>>>> LU>  algorithm.
>>>>
>>>> LU>  The intention is take option 2 and include it for JSF 2.0, because
>>>> LU>  in theory should be handled as an implementation detail of the
>>>> LU>  algorithm (anyway it could be good to update the documentation with
>>>> LU>  the same advice used for retargetAttachedObjects).
>>>>
>>>> Certainly you have identified a valid issue.  The root problem is that
>>>> the top level component needs to have a Java programming way to expose
>>>> its composite-ness.
>>>>
>>>> LU>  For "action", "actionListener", "validator" and
>>>> LU>  "valueChangeListener" it is clear that the action to take is
>>>> LU>  something like this:
>>>>
>>>> LU>    - If target is a composite component and that one "retarget" to
>>>> LU>  other components and additionally does not implements
>>>> LU>  [ActionSource2/EditableValueHolder], call:
>>>>
>>>> LU>      targetComponent.getAttributes().put(attributeName,
>>>> LU>  attributeNameValueExpression);
>>>>
>>>> LU>      and call retargetMethodExpressions recursively. Take care of
>>>> LU>  apply the method twice and if the property pointed by
>>>> LU>  "attributeName" was already set, revert its effects.
>>>>
>>>> The solution you propose will work, but it feels a bit too
>>>> implementation-ish.  Right now we declare that every compositeComponent
>>>> must be a NamingContainer.  Perhaps it's time to define a new abstract
>>>> sub-class of NamingContainer that is a union of all the behavioral
>>>> interfaces?
>>>>
>>>> public abstract class javax.faces.component.CompositeComponent
>>>> implements NamingContainer, ActionSource2, EditableValueHolder {
>>>>   public abstract void acceptRetargetedMethodExpressions(BeanInfo
>>>>     ccMetadata);
>>>> }
>>>>
>>>
>>> I like the way it works now. For example, tomahawk t:inputHtml component
>>> was
>>> rewritten into a composite component, and it is a good example about when
>>> it
>>> could
>>> be useful that the only requerimiento for a component to be composite is
>>> implement
>>> NamingContainer:
>>>
>>> <composite:interface componentType="org.apache.myfaces.InputHtml">
>>>
>>> public class InputHtml extends HtmlInputText implements NamingContainer,
>>> UniqueIdVendor {
>>>
>>> In my understanding, if a composite component base class implements a
>>> behavioral interface,
>>> (ActionSource2, EditableValueHolder, ...), "targets" behavior must not be
>>> allowed, because
>>> the code handling that will be on the base class. In the example shown
>>> InputHtml extends
>>> from HtmlInputText, so it implements EditableValueHolder.
>>>
>>> To decide when "targets" behavior applies I have something like this:
>>>
>>> if (isCompositeComponentRetarget(context, innerComponent, attributeName)
>>> &&
>>> !(innerComponent instanceof ActionSource2))
>>> {
>>>     //cc retarget
>>> }
>>> else
>>> {
>>>    //process on innerComponent
>>> }
>>>
>>> isCompositeComponentRetarget do two things:
>>>
>>> - Check if the component is a composite one.
>>> - Check if the attribute was defined looking on the BeanInfo.
>>>
>>> Leonardo
>>>
>>>> LU>  The tricky part is how to handle generic method expression
>>>> LU>  properties. The javadoc says:
>>>>
>>>> We could specify whatever we needed in that
>>>> acceptRetargetedMethodExpressions() method.
>>>>
>>>> Ed
>>>>
>>>> --
>>>> | edward.burns at oracle.com | office: +1 407 458 0017
>>>> | homepage:               | http://ridingthecrest.com/
>>>> | 16 work days until German Oracle User's Group Conference
>>>
>>>
>>
>>
>>
>> --
>> Jakob Korherr
>>
>> blog: http://www.jakobk.com
>> twitter: http://twitter.com/jakobkorherr
>> work: http://www.irian.at
>>
>
>

-- 
"There are two kinds of people in the world, those who believe there are two kinds of people and those who don't."
— Robert Benchley



More information about the jsr-314-open-mirror mailing list