Hi
This answer is from some days ago, but it wasn't sent to
jsr344-experts list, so I resend it to continue the discussion on this
list:
Hi
2011/7/1 Blake Sullivan <blake.sullivan_at_oracle.com>:
> Leonardo,
>
> I agree that you can get rid of the restriction in a very limited case, but
> is it worthwhile to make such a change? The reason the composite components
> are NamingContainers is to ensure isolation from the consuming page. Your
> solution to avoiding id conflicts in this case was to not set any ids in
> your composite component definition. This precludes the definition from
> EVER using any id-based services, such as <f:ajax> within its definition.
> In addition, your proposal does nothing to address abstraction failure
> issues regarding whether a composite component implementation happens to use
> NamingContainers as part of its implementation.
>
The intention is just allow the "exception", that theorically is
working on MyFaces without change anything. It is clear there will be
some hacks that just will not work, but the same is true for cases
that right know depends on ui:include or facelets user tags. By
default, composite components should be naming containers to work
fully. Note this feature does not need any change on the spec.
> I do not consider the initial findComponent() failure a bug. Page authors
> using components need to know whether they are NamingContainers or not.
> Good IDEs should be helping you out in this case. In many ways, it is
> easier for page authors to remember whether a component is a composite
> component or not if all of the composite components are NamingContainers.
>
> The abstraction failure is that findComponent() should always work in terms
> of the document that the page author is working in. In the case of
> composite components, this means that component references in the page
> consuming the composite component should stay the same regardless of whether
> a composite component uses NamingContainer in its implementation or not.
>
It sounds reasonable, but I don't see how can we do such change over
findComponent() without degrade its performance. Things are more
difficult if you consider nested composite components using
cc:insertChildren, cc:insertFacet and templating tags. The problem is
once the component tree is built, you lose the information related to
the page where the component was defined. The only information saved
is a marker to identify it on a further refresh (MARK_ID).
> Fixing findComponent() should not break invokeOnComponent() and visitTree()
> as we are not talking about changing the structure of the returned clientIds
> for the child components from the consuming page after they have been
> relocated into the composite component.
>
But an invokeOnComponent will not work too, without get the final
clientId. The intention of do not use a NamingContainer deliberately
is precisely to know beforehand the clientId of the component.
The problem with use facelets user tags or facelets dynamic components
is that all properties are strings that are put on a VariableMapper,
which is a nasty hack (I already changed that terrible code in MyFaces
to something better), and in practice there are some situations where
JSF composite components cannot be used, specifically by the
NamingContainer restriction.
regards,
Leonardo Uribe