Search code examples
javaadobejcrsightly

How to iterate over JCR nodes in java?


I have a touch-ui multi-field component in Adobe 6.2 for slider, i am unable to iterate over multiple nodes saved in JCR, after iterating over the each node i need to create array list to further use in HTL.

JCR NODE look like below screenshot JCR NODE

JAVA Logic code 1:

public class SliderLogic extends WCMUse {
    private ValueMap childProperties;
    private Integer childCount;

    @Override
    public void activate() throws Exception {

        String childNode = get("childNode", String.class);
        Resource childResource = getResource().getChild(childNode);

        System.out.println("childResource++++" + childResource);
        if (childResource != null) {

            childProperties                     = childResource.adaptTo(ValueMap.class);

            for(Entry<String, Object> e : childProperties.entrySet()) {
                String key = e.getKey();
                Object value = e.getValue();
                System.out.println("Elements=" + e);
                System.out.println("key=" + key);
                System.out.println("value=" + value);
            }


        }
    }


    public ValueMap getChildProperties() {

        return childProperties;
    }
}

System output as follows for code 1:

childResource++++JcrNodeResource, type=nt:unstructured, superType=null, path=/content/zero-6/en/jcr:content/content-parsys/slider/slides
Elements=jcr:primaryType=nt:unstructured
key=jcr:primaryType
value=nt:unstructured

Code2: Another try but no luck

@Override
public void activate() throws Exception {

    String childNode = get("childNode", String.class);
    Resource childResource = getResource().getChild(childNode);

    System.out.println("childResource++++" + childResource);
    if (childResource != null) {

        childProperties                     = childResource.adaptTo(ValueMap.class);
        Iterable<Resource> getChildren      = getResource().getChildren();
        Iterator<Resource> children         = getResource().listChildren();

        System.out.println("childProperties="+childProperties);
        System.out.println("getChildren="+getChildren);

        while (children.hasNext()) {

            Resource child = children.next();
            System.out.println("child=" + child);

        }


    }
}

System out for code 2:

childResource++++JcrNodeResource, type=nt:unstructured, superType=null, path=/content/zero-6/en/jcr:content/content-parsys/slider/slides
childProperties=JcrPropertyMap [node=Node[NodeDelegate{tree=/content/zero-6/en/jcr:content/content-parsys/slider/slides: { jcr:primaryType = nt:unstructured, 1 = { ... }, 2 = { ... }, 3 = { ... }, 4 = { ... }}}], values={jcr:primaryType=nt:unstructured}]
getChildren=org.apache.sling.api.resource.AbstractResource$1@34488dc4
child=JcrNodeResource, type=nt:unstructured, superType=null, path=/content/zero-6/en/jcr:content/content-parsys/slider/bannerImage
child=JcrNodeResource, type=nt:unstructured, superType=null, path=/content/zero-6/en/jcr:content/content-parsys/slider/slides

HTL code to render

<div data-sly-use.slide="${'SliderLogic' @ childNode='slides'}">

        <ul data-sly-list.child="${resource.listChildren}">
            <li>${child} ==  ${child.slideTitle || 'no title'} </li>
        </ul>
</div>

Solution

  • Fix it using Apache sling, created an array list of resource object in java logic file and use it in sightly.

    SliderLogic.java

    package apps.site.components.structure.slider;
    
    import com.adobe.cq.sightly.WCMUse;
    import org.apache.sling.api.resource.Resource;
    import org.apache.sling.api.resource.ValueMap;
    
    import java.util.Collection;
    import java.util.Collections;
    import java.util.LinkedHashMap;
    import java.util.Map;
    import java.util.Map.*;
    import java.util.HashMap;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    /**
     * Simple utility class to help a Sightly component get a child node's properties
     */
    public class SliderLogic extends WCMUse {
    
    
        public ArrayList<Resource> childList = new ArrayList<Resource>();
    
    
        @Override
        public void activate() throws Exception {
    
            String childNode = get("childNode", String.class);
            Resource childResource = getResource().getChild(childNode);
    
            if (childResource != null) {
    
                Iterator<Resource> children = getResource().listChildren();
    
                while (children.hasNext()) {
    
                    Resource child = children.next();
                    String parentNodeName = child.getName();
    
                    if (parentNodeName.equals("slides")) {
                        setChildIterator(child);
                    }
                }
            }
        }
    
        public void setChildIterator(Resource childsResourceNode) {
    
            Iterator<Resource> childItems = childsResourceNode.listChildren();
    
            while (childItems.hasNext()) {
                Resource child              = childItems.next();
    
                childList.add(child);
            }
        }
    
        public ArrayList<Resource> getChildProperties() {
    
            System.out.println("\n items list " + childList);
            return childList;
        }
    }
    

    slider.html

    <div data-sly-use.slide="${'SliderLogic' @ childNode='slides'}">
    
        <ul data-sly-list.child="${slide.getChildProperties}">
            <li style="color: #4bff2a">bannerImageName : ${child.bannerImageName || 'no title'} </li>
            <li style="color: #ff3f10">bannerImageRef : ${child.bannerImageRef || 'no title'} </li>
            <li style="color: #ff3f10">img: <img src="${child.bannerImageRef}" width="100"> </li>
            <li style="color: #ebbcff">show : ${child.show || 'no title'} </li>
            <li style="color: #c7a6ff">slideText : ${child.slideText || 'no title'} </li>
            <li style="color: #ff19c2">slideTitle : ${child.slideTitle || 'no title'} </li>
            <li style="color: #6657ff">textPosition : ${child.textPosition || 'no title'} </li>
        </ul>
    </div>