[jsr-314-open] #{cc} semantics
Ken Paulsen
Ken.Paulsen at Sun.COM
Tue Sep 15 19:53:13 EDT 2009
Well Andy.....
I agree 100% with you.
Thanks,
Ken
Andy Schwartz wrote:
> Ryan, All -
>
> Breaking this topic off into a separate thread, though I am impressed
> with the length of the "<h:dataTable> binding vs. ui:repeat" thread. :-)
>
> Ryan Lubke wrote:
>> On 9/7/09 6:06 PM, Andy Schwartz wrote:
>>> Thanks Lincoln. I haven't had time to debug this, but I have a
>>> theory about what might be happening. In your sample:
>>>
>>>> <a:editText value="#{cc.attrs.task.text}"
>>>> rendered="#{!cc.attrs.disabled}">
>>>> *<f:actionListener for="submit"
>>>> action="#{taskController.saveTaskAjax(cc.attrs.story,
>>>> cc.attrs.task)}" /> *
>>>> </a:editText>
>>>
>>> We expect "cc" to resolve to the containing composite component (ie.
>>> to the <socialpm:taskBlock> component). I wouldn't be surprised if
>>> what is actually happening is that "cc" is being resolved to the
>>> <a:editText> composite component instead.
>> Yep, that's what is happening.
>>> One reason why I suspect this might be happening is that I know that
>>> Ryan has investigated/resolved similar problems not too long ago.
>> The problem we resolved was the passing of #{cc.attrs} attributes
>> between nested composite components.
>> For this case, the spec recommends using cc.parent.attrs.story and
>> cc.parent.attrs.task, where parent resolves
>> to the nearest composite component parent of the current composite
>> component.
>
> I am concerned about this behavior. It isn't clear to me whether the
> spec is explicit about this behavior, or whether this is something
> that happens to fall out of the implementation. Either way, the
> current behavior seems counterintuitive to me, and, well... wrong.
>
> My feeling is that when a composite component author uses a #{cc}
> expression in a composite component implementation, eg:
>
> <composite:implementation>
> <h:outputText value="#{cc.attrs.value}">
> </composite:implementation>
>
> The correct behavior (the behavior expected by the composite component
> author) is to resolve the #{cc} expression relative to where the
> expression is defined - not relative to where it happens to end up in
> the component tree. So, for example, I believe that these three uses
> of the #{cc.attrs.value} expression should all evaluate to the same
> value:
>
> <composite:implementation>
>
> <!-- 1. Expression directly in the implementation -->
> <h:outputText value="#{cc.attrs.value}">
>
> <!-- 2. Expression in non-composite component facet -->
> <bar:someJavaComposite>
> <f:facet name="someFacet">
> <h:outputText value="#{cc.attrs.value}">
> </f:facet>
> </bar:someJavaComponent>
>
> <!-- 3. Expression in composite component facet -->
> <foo:someCompositeComponent>
> <f:facet name="someFacet">
> <h:outputText value="#{cc.attrs.value}">
> </f:facet>
> </foo:someCompositeComponent>
>
> </composite:implementation>
>
> The fact that the #{cc.attrs.value} expression evaluates the same in
> cases #1 and #2 but not in case #3 is non-obvious and is going to be
> confusing for our users. The fact that Lincoln and I were confused
> about this is a good indication that others will be as well.
>
> I am not happy with the work around of using #cc.parent.attrs, since
> this means that:
>
> 1. The user must recognize that the component in question is a
> composite component and code the expression differently. While at the
> moment it is fairly easy to determine whether a particular component
> is a composite or not (by looking at the namespace declaration), I
> think that we should strive to blur these lines rather than reinforce
> them. For example, I would like to see the ability to define a single
> tag library that consists of both composite and non-composite
> components, making the choice of component implementation more
> transparent to the user.
>
> 2. Once the user has coded the expression in a composite
> component-specific way, this introduces a dependency on the fact that
> the component in question is a composite component - a dependency that
> shouldn't be necessary for this particular case. Such dependencies
> inhibit flexibility. If in the future the provider of the composite
> component decides to switch to a Java-based component, this will break
> any code (or EL expression) that assumes that the component is a
> composite. We should keep such dependencies to a minimum.
>
> 3. This also introduces a subtle dependency on the composite
> component's implementation. What if the composite component
> implementation passes the expression along to yet another nested
> composite component? Does the user now need to specify an expression
> that pops out multiple levels of parents?
>
> While it is certainly trickier to deal with from an implementation
> perspective, I believe that it is very important that we re-consider
> the current behavior and consider spec'ing that #{cc} expressions
> always resolve relative to the context in which they are defined. I
> feel that the current behavior violates the principle of least
> surprise (both Lincoln and I were surprised) and also breaks
> encapsulation (ie. introduces implementation-specific dependencies).
>
> Leaving aside questions of how we might implement my preferred
> behavior for the moment... Does anyone have comments on which
> behavior makes sense from a spec/end user perspective?
>
> Andy
>
More information about the jsr-314-open-mirror
mailing list