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

[jsr372-experts] Re: recursive use of a custom component

From: Bauke Scholtz <balusc_at_gmail.com>
Date: Mon, 8 Feb 2016 23:25:36 +0100

Hi,

For more clarity on the technical problem, I blogged about it:
http://balusc.omnifaces.org/2016/02/recursive-tree-of-composite-components.html

Cheers, B


On Mon, Feb 8, 2016 at 10:02 PM, Bauke Scholtz <balusc_at_gmail.com> wrote:

> Hi,
>
> Technical problem is the context of #{cc} and statefulness of #{cc.attrs}.
>
> The #{cc} refers to *current* composite. So when you pass #{cc} to the
> nested composite , it will in turn refer the nested composite itself, not
> its parent. This results in infinite loop. This can be tricked by passing
> #{cc.parent} to the nested composite instead.
>
> The statefulness of #{cc.attrs} can be tricked by overriding
> setValueExpression() and delegating to a local variable instead of
> statehelper and then referring the local variable via #{cc.node} instead of
> the attribute. This will avoid another infinite loop when nested component
> refers attributes of its parent.
>
> Here's an example:
>
> <cc:interface componentType="treeComposite">
> <cc:attribute name="node" type="org.omnifaces.model.tree.TreeModel" />
> </cc:interface>
> <cc:implementation>
> <c:if test="#{not empty cc.node.children}">
> <ul>
> <c:forEach items="#{cc.node.children}" var="node" varStatus="loop">
> <li>#{node.data} <my:tree node="#{cc.parent.node.children[loop.index]}"
> /></li>
> </c:forEach>
> </ul>
> </c:if>
> </cc:implementation>
>
> With this backing component:
>
> @FacesComponent("treeComposite")
> public class TreeComposite extends UINamingContainer {
>
> private TreeModel node;
>
> @Override
> public void setValueExpression(String name, ValueExpression binding) {
> if ("node".equals(name)) {
> setNode((TreeModel)
> binding.getValue(getFacesContext().getELContext()));
> }
> else {
> super.setValueExpression(name, binding);
> }
> }
>
> public TreeModel getNode() {
> return node;
> }
>
> public void setNode(TreeModel node) {
> this.node = node;
> }
>
> }
>
>
> By the way, just a few remarks: this is a composite component, not a
> custom component. The <cc:attribute class> doesn't exist, you meant to use
> <cc:attribute type>. The <c:forEach> doesn't support rendered attribute.
> Just omit it.
>
> Cheers, B
>
>
>
> On Mon, Feb 8, 2016, 17:43 Michael Müller <
> michael.mueller_at_mueller-bruehl.de> wrote:
>
>> Hi,
>>
>> I defined a node element with a text, an URL, and a list of nodes. Using
>> JSF, this should be shown as a kind of menu or tree, which might be
>> expanded or collapsed.
>>
>> I created a custom component "MenuNode" to handle the tree in a recursive
>> way.
>> Using ui:repeat, I allways get a stack overflow.
>> Using c:forEach together with c:if, I'll get the stack overflow every
>> time the parent node is expanded.
>>
>> <cc:interface>
>> <cc:attribute name="parentNode"
>> class="org.mm.portallib.tree.MenuTreeNode"/>
>> </cc:interface>
>>
>> <!-- IMPLEMENTATION -->
>> <cc:implementation>
>> <c:forEach items="#{cc.attrs.parentNode.children}" var="node"
>> varStatus="status" rendered="#{cc.attrs.parentNode.children.size() gt 0}">
>> <div style="margin-left:16px;">
>> <mm:MenuItem/>
>> <c:if test="#{node.expanded}" id="SubNode#{status.index}">
>> <mm:MenuNode parentNode="#{node}"/>
>> </c:if>
>> </div>
>> </c:forEach>
>>
>> </cc:implementation>
>>
>> It seems, JSF will analyze this structure independent from its data
>> content: The structure terminates after few levels, whilst the tree build
>> seems to run into an endless loop. Is this a bug, or does cc do not support
>> any recursion?
>>
>> --
>>
>> Herzliche Grüße - Best Regards,
>>
>> Michael Müller
>> Brühl, Germany
>> blog.mueller-bruehl.de
>> it-rezension.de
>> @muellermi
>>
>>
>> Read my books
>> "Web Development with Java and JSF": <https://leanpub.com/jsf>
>> https://leanpub.com/jsf
>> "Java Lambdas und (parallel) Streams" Deutsche Ausgabe:
>> <https://leanpub.com/lambdas-de>https://leanpub.com/lambdas-de
>> "Java Lambdas and (parallel) Streams" English edition:
>> <https://leanpub.com/lambdas>https://leanpub.com/lambdas
>>
>>