How to get properties of "jcr:content" of nested page | Community
Skip to main content
June 17, 2023
Solved

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

  • June 17, 2023
  • 2 replies
  • 1328 views

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

 

 

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);
    }
}

 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by aanchal-sikka

@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");

 

2 replies

aanchal-sikka
Community Advisor
aanchal-sikkaCommunity AdvisorAccepted solution
Community Advisor
June 17, 2023

@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
joerghoh
Adobe Employee
Adobe Employee
June 18, 2023

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).