private String itemType = info.magnolia.cms.core.ItemType.CONTENT.getSystemName();
public int doStartTag() throws javax.servlet.jsp.JspException {
String queryString = generateXPathQuery();
if (queryString == null) {
if (log.isDebugEnabled()) {
log.debug("A valid query could not be built, skipping"); }
return EVAL_PAGE;
}
if (log.isDebugEnabled()) {
log.debug("Executing xpath query " + queryString); }
org.apache.jackrabbit.core.query.QueryImpl q;
try {
info.magnolia.cms.core.search.QueryManager manager = info.magnolia.context.MgnlContext.getQueryManager(repository);
Class managerClass = manager.getClass();
java.lang.reflect.Field field = managerClass.getDeclaredField("queryManager");
field.setAccessible(true);
javax.jcr.query.QueryManager jcrManager = (javax.jcr.query.QueryManager) field.get(manager);
q = (org.apache.jackrabbit.core.query.QueryImpl) jcrManager.createQuery(queryString, "xpath");
q.setLimit(10);
q.setOffset((page-1)*10);
field = managerClass.getDeclaredField("accessManager");
field.setAccessible(true);
info.magnolia.cms.security.AccessManager accessManager = (info.magnolia.cms.security.AccessManager) field.get(manager);
javax.jcr.query.QueryResult result = q.execute();
java.util.Map objectStore = new java.util.Hashtable();
java.util.Map dirtyHandles = new java.util.Hashtable();
java.util.Collection resultSet = (java.util.Collection) objectStore.get(itemType);
if (resultSet == null) {
/* build it first time */
resultSet = new java.util.ArrayList();
try {
build(itemType, resultSet, objectStore, result, dirtyHandles, accessManager);
}
catch (javax.jcr.RepositoryException re) {
log.error(re.getMessage());
}
}
pageContext.setAttribute(var, resultSet, scope);
}
catch (Exception e) {
log.error(java.text.MessageFormat.format(
"{0} caught while parsing query for search term [{1}] - query is [{2}]: {3}", new Object[]{e.getClass().getName(), this.query, queryString, e.getMessage()}), e);
}
return EVAL_PAGE;
}
private void build(String nodeType, java.util.Collection collection, java.util.Map objectStore,
javax.jcr.query.QueryResult result, java.util.Map dirtyHandles,
info.magnolia.cms.security.AccessManager accessManager) throws javax.jcr.RepositoryException {
objectStore.put(nodeType, collection);
javax.jcr.NodeIterator nodeIterator = result.getNodes();
while (nodeIterator.hasNext()) {
javax.jcr.Node node = nodeIterator.nextNode();
try {
build(node, nodeType, collection, dirtyHandles, accessManager);
}
catch (javax.jcr.RepositoryException re) {
log.error("{} caught while iterating on query results: {}", re.getClass().getName(), re.getMessage());
if (log.isDebugEnabled()) {
log.debug(
re.getClass().getName() + " caught while iterating on query results: " + re.getMessage(),
re);
}
}
}
}
private void build(javax.jcr.Node node, String nodeType, java.util.Collection collection, java.util.Map dirtyHandles,
info.magnolia.cms.security.AccessManager accessManager) throws javax.jcr.RepositoryException {
if ((node.isNodeType(nodeType) || org.apache.commons.lang.StringUtils.isEmpty(nodeType)) &&
!node.isNodeType(info.magnolia.cms.core.ItemType.NT_RESOURCE)) {
if (dirtyHandles.get(node.getPath()) == null) {
boolean isAllowed = accessManager.isGranted(info.magnolia.cms.core.Path.getAbsolutePath(node.getPath()),
info.magnolia.cms.security.Permission.READ);
if (isAllowed) {
collection.add(new info.magnolia.cms.core.DefaultContent(node, accessManager));
dirtyHandles.put(node.getPath(), org.apache.commons.lang.StringUtils.EMPTY);
}
}
return;
}
if (node.getDepth() > 0) {
build(node.getParent(), nodeType, collection, dirtyHandles, accessManager);
}
}
Thanks Jason, but why not patch QueryManager to allow passing of limit and offset parameters, and use it proper in the tag? (and in turn, reporting this in Jira along with patches, which will benefit everyone without the need to resort to hackery
)
I like Jason's approach - the JCR does not support paging for the queries, Jackrabbit started supporting it with release 1.4 (older releases do not support it). Different implementations may be needed if one opts for CRX as a repository.
What I meant was patching info.magnolia.cms.core.search.QueryManager, which is just a wrapper around jcr
Since the JCR does not support the paging you would have to do it per implementation - note that the class org.apache.jackrabbit.core.query.QueryImpl - the Query interface does not support the paging.
oh, right, I hadn't noticed this was hacking into jackrabbit's QueryImpl class.