Is there any specific reason you want to follow that approach as you have mentioned in your problem statement?
You can call or inject QueryBuilder API using @ Reference annotation as shown below -
/**
*
*/
package com.aem.demo.core.servlets;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import javax.jcr.Session;
import javax.servlet.Servlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.aem.demo.core.services.WriteDataToFile;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.SearchResult;
import com.google.common.base.Strings;
/**
* @author debal
*
* This servlet is used to generate report associated with activated
* page or activated assets only Report will be generated for AEM sites
* under specific content path
*/
@Component(service = Servlet.class, property = { "sling.servlet.paths=" + "/bin/reports/resource",
"sling.servlet.methods=" + HttpConstants.METHOD_POST })
public class ResourceResportServlet extends SlingAllMethodsServlet {
private final Logger logger = LoggerFactory.getLogger(ResourceResportServlet.class);
private static final long serialVersionUID = 8383266648883534070L;
@Reference
private QueryBuilder queryBuilder;
@Reference
WriteDataToFile writeDataToFile;
protected void doPost(SlingHttpServletRequest slingHttpServletRequest,
SlingHttpServletResponse slingHttpServletResponse) {
int rowNumber = 0;
Map<String, String> map = new HashMap<String, String>();
Map<Integer, String> resourceMap = new TreeMap<>();
String resourceSearchPath = slingHttpServletRequest.getParameter("searchPath");
String lastReplicatedDate = slingHttpServletRequest.getParameter("lastPublishedDate");
logger.info("**** Report generation has been initiated under {}" + resourceSearchPath);
logger.info("**** Report generation has been generated from {}" + lastReplicatedDate);
String rseourceType = null;
if (!Strings.isNullOrEmpty(resourceSearchPath) && !Strings.isNullOrEmpty(lastReplicatedDate)) {
try (ResourceResolver resourceResolver = slingHttpServletRequest.getResourceResolver()) {
Session session = resourceResolver.adaptTo(Session.class);
Resource resource = resourceResolver.getResource(resourceSearchPath);
if (Objects.nonNull(resource)) {
String resourcepath = resource.getPath();
if (resource.isResourceType("cq:Page")) {
rseourceType = "cq:Page";
} else if (resourcepath.contains("/dam/")) {
rseourceType = "dam:Asset";
}
logger.info("**** Resource Type {}" + rseourceType);
/*
* create query description as hash map (simplest way, same as form post)
*/
map.put("path", resourceSearchPath.trim());
map.put("type", rseourceType.trim());
map.put("1_property", "jcr:content/cq:lastReplicationAction");
map.put("1_property.value", "Activate");
map.put("2_daterange.property", "jcr:content/cq:lastReplicated");
map.put("2_daterange.lowerBound", lastReplicatedDate);
map.put("p.limit", "-1");
Query searchquery = queryBuilder.createQuery(PredicateGroup.create(map), session);
SearchResult searchResult = searchquery.getResult();
logger.info("**** Number of Total Matches {}" + searchResult.getTotalMatches());
Iterator<Resource> resources = searchResult.getResources();
while (resources.hasNext()) {
Resource searchResultResource = resources.next();
String searchrseourcePath = searchResultResource.getPath();
slingHttpServletResponse.getWriter().write(searchrseourcePath);
resourceMap.put(rowNumber++, searchrseourcePath);
}
writeDataToFile.addDataToFile(resourceMap, slingHttpServletResponse);
}
} catch (IOException e) {
e.printStackTrace();
}
;
}
}
You could follow below steps also -
1. Create ResourceResover using ResourceResolverFactory and service user as shown below and define the entire logic in a separate utility interface and implementation class as shown below -
/**
*
*/
package com.aem.demo.core.services;
import org.apache.sling.api.resource.ResourceResolver;
/**
* @author debal
*
* This service will be used as a utility and it will help us to get
* resource resolver object , JCR session and close resource resolver
*
*/
public interface JcrUtility {
public ResourceResolver getResourceResolver();
public void closeResourceResolver(ResourceResolver resourceResolver);
}
/**
*
*/
package com.aem.demo.core.services.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.aem.demo.core.services.JcrUtility;
/**
* @author debal
*
*/
@Component(service = JcrUtility.class, immediate = true)
public class JcrUtilityImpl implements JcrUtility {
private final Logger logger = LoggerFactory.getLogger(JcrUtilityImpl.class);
@Reference
ResourceResolverFactory resourceResolverFactory;
@Override
public ResourceResolver getResourceResolver() {
Map<String, Object> map = new HashMap<String, Object>();
map.put(resourceResolverFactory.SUBSERVICE, "readWriteService");
ResourceResolver serviceResourceResolver = null;
try {
serviceResourceResolver = resourceResolverFactory.getServiceResourceResolver(map);
} catch (LoginException e) {
logger.error("Could not get service user [ {} ]", "demoSystemUser", e.getMessage());
}
return serviceResourceResolver;
}
@Override
public void closeResourceResolver(ResourceResolver resourceResolver) {
if (Objects.nonNull(resourceResolver)) {
resourceResolver.close();
}
}
}This will be an OSGi service.
2. Create a service user and assign requisite permission to that service user and do a service mapping as shown below -

3. Get the ResourceResolver instance via that OSGi service [created in step:1] like
@ Reference
JcrUtility jcrUtility;
ResourceResolver resourceResolver = jcrUtility.getResourceResolver();
Get the Session using ResourceResolver as shown below -
Session session = resourceResolver.adaptTo(Session.class);
Now inject QueryBuilder API using @ Reference annotation as shown below -
@ Reference
private QueryBuilder queryBuilder;
Finally your query part something like below one -
map.put("path", resourceSearchPath.trim());
map.put("type", rseourceType.trim());
map.put("1_property", "jcr:content/cq:lastReplicationAction");
map.put("1_property.value", "Activate");
map.put("2_daterange.property", "jcr:content/cq:lastReplicated");
map.put("2_daterange.lowerBound", lastReplicatedDate);
map.put("p.limit", "-1");
Query searchquery = queryBuilder.createQuery(PredicateGroup.create(map), session);