Search code examples
javaaem

AEM 6.1: Get all 'parsys' and 'iparsys' components of the page


I have a path to the page (/content/my-site/en/cars, for example) and I need a list of all 'parsys' and 'iparsys' components presented on this page in java code. Are there any ways to do it? Thanks for any help.


Solution

  • I assume you are trying a Sling model or WCMUsePOJO to read inner nodes of a page. Here the techniques:

    1. If you dont know how many parsys nodes are present: This is not an ideal case since page rendering script dictates all included parsys and iparsys. But just incase, you ll run a query for sling:resourceType like this:
    Iterator<Resource> parsysResources = resourceResolver.findResources("/jcr:root/content/my-site/en/cars//*[sling:resourceType='foundation/components/parsys']", Query.XPATH);
    Iterator<Resource> iparsysResources = resourceResolver.findResources("/jcr:root/content/my-site/en/cars//*[sling:resourceType='foundation/components/iparsys']", Query.XPATH);
    
    1. Similar query but with Query Builder (Recommended): It is recommended to use query builder API for readability and extensible in future.
    List<Resource> parsysIpaysysResources = new ArrayList<>();
    Map<String, String> predicateMap = new HashMap<>();
    predicateMap.put("path", "/content/my-site/en/cars");
    predicateMap.put("1_property", "sling:resourceType");
    predicateMap.put("1_property.value", "foundation/components/parsys");
    predicateMap.put("2_property", "sling:resourceType");
    predicateMap.put("2_property.value", "foundation/components/iparsys");
    predicateMap.put("p.limit", "-1");
    
    QueryBuilder queryBuilder = resourceResolver.adaptTo(QueryBuilder.class);
    Session session = resourceResolver.adaptTo(Session.class);
    com.day.cq.search.Query query = queryBuilder.createQuery(PredicateGroup.create(predicateMap), session);
    SearchResult result = query.getResult();
    Iterator<Resource> resources = result.getResources();
    while (resources.hasNext()) {
        parsysIpaysysResources.add(resources.next());
    }
    
    1. If the parsys nodes are known to be immediate children of page content, listChildren will be cheaper compared to query.
    Page pageContent = pageManager.getContainingPage("/content/my-site/en/cars");
            Iterator<Resource> children = pageContent.getContentResource().listChildren();
            while(children != null && children.hasNext()) {
                Resource child = children.next();
                if(child.isResourceType("foundation/components/parsys") || child.isResourceType("foundation/components/iparsys")) {
                    // do something
                }
            }
    
    1. If the node name of inner parsys is known, JCR API can be leveraged
    Page pageContent = pageManager.getContainingPage("/content/my-site/en/cars");
        Node pageContentNode  = pageContent.adaptTo(Node.class);
        try {
            NodeIterator nodeIter = pageContentNode.getNodes("parsys*");
            // iterate nodes
        } catch (RepositoryException e) {
            e.printStackTrace();
        }