Expand my Community achievements bar.

Join expert-led, customer-led sessions on Adobe Experience Manager Assets on August 20th at our Skill Exchange.

Mark Solution

This conversation has been locked due to inactivity. Please create a new post.

SOLVED

How to get properties of "jcr:content" of nested page

Avatar

Level 1

I have one parent page News. This parent page have several nested pages. I am trying to get properties of all jcr:content node of nested pages. But I am getting null response from getChild().

 

Here down is the snapshot of CRDXE Page. I need all properties of jcr:content

 

YxoWK.png

 

Here down is my code

 

NewsServiceImpl

 

@Component(service = NewsService.class
public class NewsServiceImpl implements NewsService {
    @Reference
    private QueryBuilder queryBuilder;
    
    @Override
    public Optional<Iterator<Resource>> getNews(SlingHttpServletRequest request, String searchPath) {
        Iterator<Resource> resourceIterator = null;
        Session session = request.getResourceResolver().adaptTo(Session.class);
        final Map<String, String> map = new HashMap<>();
        map.put("path", searchPath);
        map.put("1_property", "sling:resourceType");
        map.put("1_property.value", "xxx/components/page");

        Query query = queryBuilder.createQuery(PredicateGroup.create(map), session);
        SearchResult result = query.getResult();
        resourceIterator = result.getResources();
        return Optional.ofNullable(resourceIterator);
    }
    
}

 

Servlet

 

@Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "= Get All News",
        SLING_SERVLET_METHODS + "=GET", SLING_SERVLET_PATHS + "=/bin/news" })
public class NewsServlet extends SlingSafeMethodsServlet {

    @Reference
    transient NewsService newsService;

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("application/json;charset=utf-8");
        JsonArray resultArray = new JsonArray();
        Optional<Iterator<Resource>> isNews = newsService.getNews(request, request.getParameter("searchPath"));
        if (isNews.isPresent()) {
            Iterator<Resource> news = isNews.get();
            while (news.hasNext()) {
                Resource parentPageResource = news.next();
                        
                // is jcr:content present, Store response in resultArray
                if (parentPageResource.getChild("jcr:content") != null)
                {
                    resultArray.add(parentPageResource.getChild("jcr:content").getValueMap().toString());
                }
            }
        }
        response.getWriter().print(resultArray);
    }
}

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@faeemazaz92 

 

The code needs a small correction.

 

Following query returns you jcr:content already. Try printing the node name to confirm. Thats why getChild() fails. 

        final Map<String, String> map = new HashMap<>();
        map.put("path", searchPath);
        map.put("1_property", "sling:resourceType");
        map.put("1_property.value", "xxx/components/page");

 

You should improve the query.

- type should be cq:Page 

1_property should be jcr:content:resourceType

Example: This will improve the performance of the query and will only return jcr:content nodes.

final Map<String, String> map = new HashMap<>();
map.put("path", searchPath);
map.put("type", "cq:Page");
map.put("1_property", "jcr:content/sling:resourceType");
map.put("1_property.value", "xxx/components/page");

 


Aanchal Sikka

View solution in original post

2 Replies

Avatar

Correct answer by
Community Advisor

@faeemazaz92 

 

The code needs a small correction.

 

Following query returns you jcr:content already. Try printing the node name to confirm. Thats why getChild() fails. 

        final Map<String, String> map = new HashMap<>();
        map.put("path", searchPath);
        map.put("1_property", "sling:resourceType");
        map.put("1_property.value", "xxx/components/page");

 

You should improve the query.

- type should be cq:Page 

1_property should be jcr:content:resourceType

Example: This will improve the performance of the query and will only return jcr:content nodes.

final Map<String, String> map = new HashMap<>();
map.put("path", searchPath);
map.put("type", "cq:Page");
map.put("1_property", "jcr:content/sling:resourceType");
map.put("1_property.value", "xxx/components/page");

 


Aanchal Sikka

Avatar

Employee Advisor

Your code will not only read the direct child pages, but rather all child pages. If you just want the child pages of a specific type the straight-forward low-level implementation looks like this:

 

 

public Optional<Iterator<Resource>> getNews(SlingHttpServletRequest request, String searchPath) {

  Resource parentResource = request.getResourceResolver().getResource(searchPath);
  if (parentResource == null) {
    return Optional.empty();
  }
  Iterator<Resource> allChildren = parentResource.getChildren();
  List<Resource> result = new ArrayList<>();
  while (allChildren.hasNext()) {
    Resource child = allChildren.next();
    Resource jcrContent = child.getChild("jcr:content");
    if (jcrContent != null) {
      if (jcrContent.isResourceType("xxx/components/page")) {
        result.add(child);
      }
    }
  }  
  return result;
}


But that is not how I would write it, because you are encoding too much implementation details. I would rather code like this:

public Iterator<Page> getNewsPages(Resource parentResource) {

  Stream<Resource> children = StreamSupport.stream(Spliterators.spliteratorUnknownSize(parentResource.GetChildren), Spliterator.ORDERED), false);
  List<Page result = children.map( r -> r.adaptTo(Page.class)
    .filter(Objects::nonNull)
    .filter( p -> {
      return Optional.ofNullable(p.getProperties())
        .map(vm -> vm.get("sling:resourceType")
        .map(p -> p.equals("xxx/components/page")
        .get();
    })
    .collect(Collectors.toList());
  return result;
}


This goes via the "Page" API and avoids some of the implementation knowledge (although it would be great if the page API would have a "getResourceType()" method as well).