Index: src/main/java/org/apache/jackrabbit/core/query/DerefQueryNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/DerefQueryNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/DerefQueryNode.java (working copy)
@@ -83,4 +83,14 @@
}
return false;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSystemTree() {
+ // Always return true since we don't know if the referenced nodes path
+ // is a child of /jcr:system
+ return true;
+ }
+
}
Index: src/main/java/org/apache/jackrabbit/core/query/ExactQueryNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/ExactQueryNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/ExactQueryNode.java (working copy)
@@ -93,4 +93,11 @@
}
return false;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSystemTree() {
+ return false;
+ }
}
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java (working copy)
@@ -241,4 +241,15 @@
return (QName[]) selectProps.toArray(new QName[selectProps.size()]);
}
+
+ /**
+ * Returns true if this query node needs items under
+ * /jcr:system to be queried.
+ *
+ * @return true if this query node needs content under
+ * /jcr:system to be queried; false otherwise.
+ */
+ protected boolean needsSystemTree() {
+ return this.root.needsSystemTree();
+ }
}
Index: src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (revision 540953)
+++ src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (working copy)
@@ -519,7 +519,7 @@
checkOpen();
SortField[] sortFields = createSortFields(orderProps, orderSpecs);
- IndexReader reader = getIndexReader();
+ IndexReader reader = getIndexReader(queryImpl.needsSystemTree());
IndexSearcher searcher = new IndexSearcher(reader);
Hits hits;
if (sortFields.length > 0) {
@@ -611,9 +611,14 @@
* @throws IOException the index reader cannot be obtained.
*/
public IndexReader getIndexReader() throws IOException {
+ return getIndexReader(true);
+ }
+
+ private IndexReader getIndexReader(boolean includeSystemIndex)
+ throws IOException {
QueryHandler parentHandler = getContext().getParentHandler();
IndexReader parentReader = null;
- if (parentHandler instanceof SearchIndex) {
+ if (parentHandler instanceof SearchIndex && includeSystemIndex) {
parentReader = ((SearchIndex) parentHandler).index.getIndexReader();
}
Index: src/main/java/org/apache/jackrabbit/core/query/NAryQueryNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/NAryQueryNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/NAryQueryNode.java (working copy)
@@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
/**
@@ -146,4 +147,20 @@
}
return false;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSystemTree() {
+ if (operands == null) {
+ return false;
+ }
+ for (Iterator iter = operands.iterator(); iter.hasNext();) {
+ QueryNode queryNode = (QueryNode) iter.next();
+ if (queryNode.needsSystemTree())
+ return true;
+ }
+ return false;
+ }
+
}
Index: src/main/java/org/apache/jackrabbit/core/query/OrderQueryNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/OrderQueryNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/OrderQueryNode.java (working copy)
@@ -188,4 +188,12 @@
return false;
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSystemTree() {
+ return false;
+ }
+
}
Index: src/main/java/org/apache/jackrabbit/core/query/PathQueryNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/PathQueryNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/PathQueryNode.java (working copy)
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.core.query;
+import org.apache.jackrabbit.name.QName;
+
/**
* Implements a query node that defines a path restriction.
*/
@@ -110,4 +112,45 @@
}
return false;
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSystemTree() {
+
+ LocationStepQueryNode[] pathSteps = getPathSteps();
+ if (pathSteps == null || pathSteps.length == 0) {
+ return true;
+ }
+
+ QName firstPathStepName = pathSteps[0].getNameTest();
+ // If the first location step has a null name test we need to include
+ // the system tree ("*")
+ if (firstPathStepName == null)
+ return true;
+
+ // Calculate the first workspace relative location step
+ LocationStepQueryNode firstWorkspaceRelativeStep = pathSteps[0];
+ if (firstPathStepName.equals(QName.ROOT)) {
+ // path starts with "/jcr:root"
+ if (pathSteps.length > 1) {
+ firstWorkspaceRelativeStep = pathSteps[1];
+ }
+ }
+
+ // First path step starts with "//"
+ if (firstWorkspaceRelativeStep.getIncludeDescendants())
+ return true;
+
+ // If the first workspace relative location step is jcr:system we need
+ // to include the system tree
+ QName firstWorkspaceRelativeName = firstWorkspaceRelativeStep.getNameTest();
+ if (firstWorkspaceRelativeName == null
+ || firstWorkspaceRelativeName.equals(QName.JCR_SYSTEM)) {
+ return true;
+ }
+
+ return super.needsSystemTree();
+ }
}
Index: src/main/java/org/apache/jackrabbit/core/query/PropertyFunctionQueryNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/PropertyFunctionQueryNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/PropertyFunctionQueryNode.java (working copy)
@@ -112,4 +112,12 @@
public String getFunctionName() {
return functionName;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSystemTree() {
+ return false;
+ }
+
}
Index: src/main/java/org/apache/jackrabbit/core/query/QueryNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/QueryNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/QueryNode.java (working copy)
@@ -125,4 +125,13 @@
* this; false otherwise.
*/
public abstract boolean equals(Object obj);
+
+ /**
+ * Returns true if this query node needs items under
+ * /jcr:system to be queried.
+ *
+ * @return true if this query node needs content under
+ * /jcr:system to be queried; false otherwise.
+ */
+ public abstract boolean needsSystemTree();
}
Index: src/main/java/org/apache/jackrabbit/core/query/QueryRootNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/QueryRootNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/QueryRootNode.java (working copy)
@@ -133,4 +133,12 @@
}
return false;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSystemTree() {
+ return (locationNode != null && locationNode.needsSystemTree()) || (orderNode != null && orderNode.needsSystemTree());
+ }
+
}
Index: src/main/java/org/apache/jackrabbit/core/query/TextsearchQueryNode.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/query/TextsearchQueryNode.java (revision 538490)
+++ src/main/java/org/apache/jackrabbit/core/query/TextsearchQueryNode.java (working copy)
@@ -209,4 +209,12 @@
}
return false;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean needsSystemTree() {
+ return false;
+ }
+
}
Index: src/test/java/org/apache/jackrabbit/core/query/PathQueryNodeTest.java
===================================================================
--- src/test/java/org/apache/jackrabbit/core/query/PathQueryNodeTest.java (revision 0)
+++ src/test/java/org/apache/jackrabbit/core/query/PathQueryNodeTest.java (revision 0)
@@ -0,0 +1,51 @@
+package org.apache.jackrabbit.core.query;
+
+import junit.framework.TestCase;
+
+import org.apache.jackrabbit.core.query.xpath.XPathQueryBuilder;
+import org.apache.jackrabbit.name.NamespaceResolver;
+import org.apache.jackrabbit.name.QName;
+
+public class PathQueryNodeTest extends TestCase {
+
+ private static final NamespaceResolver JCR_RESOLVER = new NamespaceResolver() {
+ public String getJCRName(QName qName) {
+ return this.getPrefix(qName.getNamespaceURI()) + ":"
+ + qName.getLocalName();
+ }
+
+ public String getPrefix(String uri) {
+ return QName.NS_JCR_PREFIX;
+ }
+
+ public QName getQName(String jcrName) {
+ return new QName(QName.NS_JCR_URI,
+ jcrName.substring(jcrName.indexOf(':')));
+ }
+
+ public String getURI(String prefix) {
+ return QName.NS_JCR_URI;
+ }
+ };
+
+ public void testNeedsSystemTree() throws Exception {
+ QueryRootNode queryRootNode = XPathQueryBuilder.createQuery("/jcr:root/*", JCR_RESOLVER);
+ assertTrue(queryRootNode.needsSystemTree());
+
+ queryRootNode = XPathQueryBuilder.createQuery("/jcr:root/test/*", JCR_RESOLVER);
+ assertFalse(queryRootNode.needsSystemTree());
+
+ queryRootNode = XPathQueryBuilder.createQuery("*", JCR_RESOLVER);
+ assertTrue(queryRootNode.needsSystemTree());
+
+ queryRootNode = XPathQueryBuilder.createQuery("jcr:system/*", JCR_RESOLVER);
+ assertTrue(queryRootNode.needsSystemTree());
+
+ queryRootNode = XPathQueryBuilder.createQuery("test//*", JCR_RESOLVER);
+ assertFalse(queryRootNode.needsSystemTree());
+
+ queryRootNode = XPathQueryBuilder.createQuery("//test/*", JCR_RESOLVER);
+ assertTrue(queryRootNode.needsSystemTree());
+ }
+
+}