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

[jsr344-experts] Re: [jsr-344-experts] should really a composite component requires NamingContainer interface?

From: Blake Sullivan <blake.sullivan_at_oracle.com>
Date: Fri, 01 Jul 2011 15:27:01 -0700

Martin,

I assume that this comes from the desire to have a single DOM node for
partial replacement (Which is actually a different implicit
assumption--that all of the DOM for a component is rendered under a
single DOM element). Anyway, is your complaint that there needs to be a
single root component at runtime or in the composite component
definition? If you only care about the definition case, would a
solution similar to the IMPLICIT_PANEL hack used in facets be sufficient?

-- Blake Sullivan

On 7/1/11 6:15 AM, Martin Marinschek wrote:
> Hi,
>
> I have a huge problem even with the assumption that a composite
> component needs to have a root component in JSF 2.0 - this is also
> backwards incompatible with Facelets dynamic components.
>
> Due to this, I have had to use both composite components and the old
> Facelets dynamic components in all my JSF 2.0 projects so far.
>
> For me: the less assumptions we have about the composite component
> root component, the better.
>
> As a sidenote: my problems might be a little alleviated by a
> possibility to identify the root component of a composite component -
> why is there no way to do this?
>
> best regards,
>
> Martin
>
> On 6/29/11, Leonardo Uribe<lu4242_at_gmail.com> wrote:
>> Hi
>>
>> In theory, a "non explicit" requeriment for a composite component
>> class is it should implement NamingContainer interface. Note I said
>> "non explicit", because in practice there is nothing on the spec that
>> enforces that. The only mention can be found on facelets taglib doc
>> for composite:interface, section titled Naming containers within
>> composite components:
>>
>> "... Composite components are themselves naming containers so that any
>> possible id conflicts between inner components and components in the
>> using page are avoided. However, special care must be taken when using
>> naming containers in the<composite:implementation> section. ..."
>>
>> It is true that by default, composite component base class is
>> UINamingContainer, and the component family should be
>> "javax.faces.NamingContainer" to get the renderer class.
>>
>> Let's take a look at this simple example:
>>
>> <h:form id="frmTst">
>> <ui:include src="demoui1.xhtml"/>
>> <ui:include src="demoui1.xhtml"/>
>> <ui:include src="demoui1.xhtml"/>
>> </h:form>
>>
>> demoui1.xhtml
>>
>> <ui:composition>
>> <p><h:commandButton value="Hello World!"/></p>
>> </ui:composition>
>>
>> The previous code works in both MyFaces and Mojarra. This is valid
>> from facelets 1.1.x. The idea is as long as there is no component with
>> "id" set, the previous code will work. Combinations of c:if and
>> ui:include could be possible, but this work well only on MyFaces 2.0.x
>> and upper and facelets 1.1.x. In Mojarra 2.0.x some changes were done
>> that makes such cases not work correctly (but in my opinion c:if is
>> something evil, because it causes a lot of nightmares).
>>
>> Now let's try to convert the previous case into a composite component,
>> but this time let's create a normal component that does not implement
>> NamingContainer, because after all the previous snippet followed the
>> rule that no components with id set were added:
>>
>> <h:form id="frmTst">
>> <test:ccc value="Hello World!"></test:ccc>
>> <test:ccc value="Hello World!"></test:ccc>
>> <test:ccc value="Hello World!"></test:ccc>
>> </h:form>
>>
>> ccc.xhtml
>>
>> <cc:interface componentType="test.ComponentCCC">
>> <cc:attribute name="value" type="java.lang.String" />
>> </cc:interface>
>> <cc:implementation>
>> <p><h:commandButton value="#{cc.attrs.value}"/></p>
>> </cc:implementation>
>>
>> @FacesComponent("test.ComponentCCC")
>> public class ComponentCCC extends UIOutput
>> {
>> public final static String COMPONENT_TYPE = "test.ComponentCCC";
>>
>>
>> @Override
>> public String getFamily()
>> {
>> return UINamingContainer.COMPONENT_FAMILY;
>> }
>> }
>>
>> In theory, since all ids are generated, everything should work like in
>> ui:include case. In practice, the previous code works on MyFaces but
>> does not on Mojarra.
>>
>> Why somebody could want to do this trick? Because NamingContainer has
>> its effects, specially with UIComponent.findComponent. Suppose you
>> want to create a component that works as a panel. You can imagine
>> something like this:
>>
>> <h:form prependId="true">
>> <y:myPanel>
>> <h:inputText id="field1" ... />
>> <!-- more components -->
>> </y:myPanel>
>> </h:form>
>>
>> y.xhtml
>>
>> <cc:implementation>
>> <!-- some javascript markup with html and css -->
>> <cc:insertChildren />
>> <!-- some javascript markup with html and css -->
>> <cc:implementation>
>>
>> The user wants that the final clientId be "field1", but instead he/she
>> has "[generated id]:field1", and the worst part is if you need some
>> call to invokeOnComponent or findComponent, you have to set the id of
>> your composite component and take into account the internals of such
>> cc to get the component instance.
>>
>> Basically the only thing we need to do on Mojarra to make it work is
>> do some small changes on id generation. Note in this case, the xhtml
>> file related to the composite component will only be used to render
>> the markup, and other stuff like attached objects should be done like
>> with normal components: adding the code on the class.
>>
>> Allow this behavior could be great, because makes possible to write
>> more JSF typical components as composite components, keeping the
>> markup on a xhtml file and the logic on the component/renderer
>> classes.
>>
>> Note that the trick proposed here is compliant with the spec, just
>> like the one proposed long time ago related to customize the renderer
>> instance for a composite component. In fact, I'm looking for a way to
>> write components more easily, and do this trick for me seems the way
>> to go.
>>
>> Should Mojarra fix this issue and enforce better compatibility with
>> facelets 1.1.x? Any comments about this one? Suggestions are welcome
>>
>> regards,
>>
>> Leonardo Uribe
>>
>