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(a)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(a)gmail.com>:
>> Hi
>>
>> 2010/10/19 Ed Burns<edward.burns(a)oracle.com>
>>>
>>>>>>>> On Mon, 18 Oct 2010 20:36:06 -0500, Leonardo Uribe
>>>>>>>> <lu4242(a)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(a)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