[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