jsr344-experts@javaserverfaces-spec-public.java.net

[jsr344-experts] Re: Referencing composite component attributes in child components outside of a tree traversal

From: Martin Marinschek <mmarinschek_at_apache.org>
Date: Thu, 16 Feb 2012 23:37:19 +0100

Hey guys,

this was a deliberate (=not by me) design decision when moving away
from Facelets: Facelets had a capability of storing (via variable
mappers) the path from an EL expression up through the chain. You
could evaluate a value expression anywhere, and it would deliver you
the correct value.

I don't know why (maybe because in Facelets you had to know a lot of
stuff when creating the value expressions, and you needed Facelets to
create those??), but it was decided to move away from this, and now
you have to be in a tree traversal to evaluate such expressions.

Of course, this is different, and hence people are running into
troubles. Maybe we should just move back to the Facelets way of doing
things?

best regards,

Martin

We could move

On 2/16/12, Blake Sullivan <blake.sullivan_at_oracle.com> wrote:
> On 2/16/12 5:09 AM, Kito Mann wrote:
>>
>>
>> On Wed, Feb 15, 2012 at 11:53 PM, Blake Sullivan
>> <blake.sullivan_at_oracle.com <mailto:blake.sullivan_at_oracle.com>> wrote:
>>
>> Maybe I'm misunderstanding this, but how is this different than
>> accessing any other potentially-EL-bound attribute in JSF?
>> EL-bound values can only be safely evaluated when the component in
>> question is in the correct context. This means either:
>> a) During lifecycle processing
>> b) During a tree visit callback
>> c) During an invokeOnComponent callback (which is really just a
>> degenerate version of b)
>>
>> I agree that this is has always been a major usability problem
>> with JSF, but that's how JSF is. The code below with
>> findComponent() has always been wrong. Programmers should not be
>> calling findComponent() and then attempting to evaluate
>> potentially EL-bound values.
>>
>>
>> The difference here is that the EL variable is "cc". The component is
>> simply referring to one of its own properties, not a backing bean, so
>> a developer would expect that to work when making an arbitrary call to
>> the component.
> Unless this is the composite component implementor's own code, then I
> would argue that when getting a the disabled property in this case:
> 1) How does the caller know that the property is not EL-bound
> 2) How does the caller know that an EL-bound property is only bound to "cc"
> 3) How does the caller know that for a "cc" bound property, the property
> is bound to a property that is not itself EL-bound
> 4) If the caller knows all this, they probably know the actual
> expression in the first place
>
> -- Blake Sullivan
>>
>>
>> As a side issue, the differences and uses of clientIds, the id
>> attribute of a components, and what the JSF findComponent
>> documentation calls "search expressions" are extremely important,
>> but poorly understood, as this code shows:
>>
>> HtmlImputText input =
>> (HtmlImputText)facesContext.findComponent(clientId);
>>
>> The Mojarra source is similarly confused in some places.
>>
>>
>> True --- I understand the distinction, but it is difficult to get across.
>>
>>
>>
>> -- Blake Sullivan
>>
>>
>> On 2/15/12 8:37 PM, Kito Mann wrote:
>>> Does anyone have any thoughts on this issue?
>>> ___
>>>
>>> Kito D. Mann | twitter: kito99 | Author, JSF in Action
>>> Virtua, Inc. | http://www.virtua.com | JSF/Java EE training and
>>> consulting
>>> http://www.JSFCentral.com - JavaServer Faces FAQ, news, and info
>>> | twitter: jsfcentral
>>> +1 203-404-4848 x3 <tel:%2B1%20203-404-4848%20x3>
>>>
>>> * Listen to the latest headlines in the JSF and Java EE newscast:
>>>
>>> http://blogs.jsfcentral.com/roller/editorsdesk/category/JSF+and+Java+EE+Newscast
>>> * Sign up for the JSFCentral newsletter:
>>> http://oi.vresp.com/?fid=ac048d0e17
>>>
>>>
>>>
>>> On Fri, Aug 19, 2011 at 6:11 PM, Kito Mann <kito.mann_at_virtua.com
>>> <mailto:kito.mann_at_virtua.com>> wrote:
>>>
>>>
>>> On Fri, Aug 19, 2011 at 3:31 PM, Leonardo Uribe
>>> <lu4242_at_gmail.com <mailto:lu4242_at_gmail.com>> wrote:
>>>
>>> Hi
>>>
>>> I have been thinking about this and it seems the missing
>>> part has to
>>> be with UIComponent.findComponent(String expr).
>>>
>>>
>>> Hmm.. Isn't the problem really that the ValueExpression
>>> implementations have no reference to the component for which
>>> they were created? If the expression knew which component it
>>> was created for, it could use that component to find the
>>> composite component parent (among other things).
>>>
>>> What if the spec said that setValueExpression() must use a
>>> "ComponentMethodExpression" instance that held a reference to
>>> the component for which the expression was created?
>>>
>>>
>>>
>>> I think it is possible to prevent this problem, doing some
>>> implementation specific tweaks, but from the user point
>>> of view, only
>>> an alternative like a visitTree receiving a findComponent
>>> expression
>>> is reasonable. It could be good to find some use cases
>>> where this
>>> improvement is useful, to support its addition to the spec.
>>>
>>>
>>> I ran into this when a client had implemented multi-field
>>> validation inside of a PostValidateEvent listener. The code
>>> uses findComponent() to query the properties of different
>>> input controls, and when I switched them over to composite
>>> components, this broke:
>>>
>>> HtmlImputText input =
>>> (HtmlImputText)facesContext.findComponent(clientId);
>>> if (input.isDisabled())
>>> {
>>> ....
>>> }
>>>
>>> (Nevermind the fact that using these types of casts isn't
>>> always the best idea.)
>>>
>>> Now, it so happens that clientId now refers to a composite
>>> component child, whereas before it referred to stand-along
>>> HtmlInputText component. This code now returns false when the
>>> #{cc.attrs.disabled} expression returns true, because cc
>>> evaluates to null.
>>>
>>> Even if we don't solve this for 2.2, the spec should mandate
>>> that implementations throw an exception or something in this
>>> case. This is something developers simply won't expect (I was
>>> certainly surprised).
>>>
>>>
>>> regards,
>>>
>>> Leonardo Uribe
>>>
>>> 2011/8/17 Kito Mann <kito.mann_at_virtua.com
>>> <mailto:kito.mann_at_virtua.com>>:
>>> > Hello everyone,
>>> >
>>> > I just ran into an issue where #{cc.attrs.property}
>>> expressions don't work
>>> > when referenced via properties of child components if
>>> they're not referenced
>>> > inside of a tree traversal. More information here:
>>> > https://issues.apache.org/jira/browse/MYFACES-3283
>>> (happens in both MyFaces
>>> > and Mojarra).
>>> >
>>> > Section 5.6.2.1 (Implicit Object ELResolver for
>>> Facelets and Programmatic
>>> > Access) of the spec states the following:
>>> >
>>> > cc -> the current composite component relative to
>>> > the declaring page in which the expression appears.
>>> >
>>> > Since "current composite component" usually means the
>>> current composite
>>> > being processed during a tree traversal, "cc" can
>>> return null when it's
>>> > referenced elsewhere (i.e. in an action listener);.
>>> >
>>> > I'm thinking that the "cc" implicit variable should
>>> return the parent
>>> > composite component in cases where no "current
>>> composite component" is
>>> > available.
>>> >
>>> > Thoughts?
>>> > ---
>>> > Kito D. Mann | twitter: kito99 | Author, JSF in Action
>>> > Virtua, Inc. | http://www.virtua.com | JSF/Java EE
>>> training and consulting
>>> > http://www.JSFCentral.com - JavaServer Faces FAQ, news,
>>> and info | twitter:
>>> > jsfcentral
>>> > +1 203-404-4848 x3 <tel:%2B1%20203-404-4848%20x3>
>>> >
>>> > * Listen to the latest headlines in the JSF and Java EE
>>> > newscast:
>>>
>>> http://blogs.jsfcentral.com/roller/editorsdesk/category/JSF+and+Java+EE+Newscast
>>> > * Keep up with the aftermath of the Oracle/Sun merger:
>>> > http://www.mergerspeak.com
>>> >
>>> >
>>>
>>>
>>>
>>
>>
>
>


-- 
http://www.irian.at
Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German
Professional Support for Apache MyFaces