You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2007/08/27 14:56:03 UTC
svn commit: r570095 - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/query/
main/java/org/apache/jackrabbit/core/query/lucene/
main/java/org/apache/jackrabbit/core/query/sql/
main/java/org/apache/jackrabbit/core/query/xp...
Author: mreutegg
Date: Mon Aug 27 05:56:01 2007
New Revision: 570095
URL: http://svn.apache.org/viewvc?rev=570095&view=rev
Log:
JCR-1066: Exclude system index for queries that restrict the result set to nodetypes not availble in the "jcr:system" subtree
Added:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DefaultQueryNodeFactory.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryNodeFactory.java (with props)
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AndQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DerefQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/LocationStepQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NodeTypeQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NotQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrderQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PathQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PropertyFunctionQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryParser.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryRootNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryTreeBuilder.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/RelationQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/TextsearchQueryNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/JCRSQLQueryBuilder.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/QueryBuilder.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryBuilder.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/PathQueryNodeTest.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AndQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AndQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AndQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AndQueryNode.java Mon Aug 27 05:56:01 2007
@@ -28,20 +28,8 @@
*
* @param parent the parent of <code>this</code> <code>AndQueryNode</code>.
*/
- public AndQueryNode(QueryNode parent) {
+ protected AndQueryNode(QueryNode parent) {
super(parent);
- }
-
- /**
- * Creates a new <code>AndQueryNode</code> with a <code>parent</code> query
- * node and <code>operands</code> for <code>this</code>
- * <code>AndQueryNode</code>.
- *
- * @param parent the parent of <code>this</code> <code>AndQueryNode</code>.
- * @param operands the operands for this AND operation.
- */
- public AndQueryNode(QueryNode parent, QueryNode[] operands) {
- super(parent, operands);
}
/**
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DefaultQueryNodeFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DefaultQueryNodeFactory.java?rev=570095&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DefaultQueryNodeFactory.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DefaultQueryNodeFactory.java Mon Aug 27 05:56:01 2007
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.query;
+
+import java.util.List;
+
+import org.apache.jackrabbit.name.QName;
+
+/**
+ * Default implementetation of a {@link QueryNodeFactory}.
+ */
+public class DefaultQueryNodeFactory implements QueryNodeFactory {
+
+ /**
+ * List of valid node type names under /jcr:system
+ */
+ private final List validJcrSystemNodeTypeNames;
+
+ /**
+ * Creates a DefaultQueryNodeFactory with the given node types under
+ * /jcr:system .
+ */
+ public DefaultQueryNodeFactory(List validJcrSystemNodeTypeNames) {
+ super();
+ this.validJcrSystemNodeTypeNames = validJcrSystemNodeTypeNames;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NodeTypeQueryNode createNodeTypeQueryNode(QueryNode parent,
+ QName nodeType) {
+ return new NodeTypeQueryNode(parent, nodeType);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AndQueryNode createAndQueryNode(QueryNode parent) {
+ return new AndQueryNode(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LocationStepQueryNode createLocationStepQueryNode(QueryNode parent) {
+ return new LocationStepQueryNode(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DerefQueryNode createDerefQueryNode(QueryNode parent,
+ QName nameTest,
+ boolean descendants) {
+ return new DerefQueryNode(parent, nameTest, descendants);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NotQueryNode createNotQueryNode(QueryNode parent) {
+ return new NotQueryNode(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public OrQueryNode createOrQueryNode(QueryNode parent) {
+ return new OrQueryNode(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public RelationQueryNode createRelationQueryNode(QueryNode parent,
+ int operation) {
+ return new RelationQueryNode(parent, operation);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PathQueryNode createPathQueryNode(QueryNode parent) {
+ return new PathQueryNode(parent, validJcrSystemNodeTypeNames);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public OrderQueryNode createOrderQueryNode(QueryNode parent) {
+ return new OrderQueryNode(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PropertyFunctionQueryNode createPropertyFunctionQueryNode(
+ QueryNode parent, String functionName) {
+ return new PropertyFunctionQueryNode(parent, functionName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public QueryRootNode createQueryRootNode() {
+ return new QueryRootNode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public TextsearchQueryNode createTextsearchQueryNode(QueryNode parent,
+ String query) {
+ return new TextsearchQueryNode(parent, query);
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DefaultQueryNodeFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DerefQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DerefQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DerefQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/DerefQueryNode.java Mon Aug 27 05:56:01 2007
@@ -36,8 +36,10 @@
* @param descendants if <code>true</code> this location step uses the
* descendant-or-self axis; otherwise the child axis.
*/
- public DerefQueryNode(QueryNode parent, QName nameTest, boolean descendants) {
- super(parent, nameTest, descendants);
+ protected DerefQueryNode(QueryNode parent, QName nameTest, boolean descendants) {
+ super(parent);
+ setNameTest(nameTest);
+ setIncludeDescendants(descendants);
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/LocationStepQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/LocationStepQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/LocationStepQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/LocationStepQueryNode.java Mon Aug 27 05:56:01 2007
@@ -65,26 +65,11 @@
private int index = NONE;
/**
- * Creates a new <code>LocationStepQueryNode</code> with a reference to
- * its <code>parent</code>.
- * @param parent the parent of this <code>LocationStepQueryNode</code>.
- * @param nameTest the name test or <code>null</code> if this step should
- * match all names.
- * @param descendants if <code>true</code> this location step uses the
- * descendant-or-self axis; otherwise the child axis.
- */
- public LocationStepQueryNode(QueryNode parent, QName nameTest, boolean descendants) {
- super(parent);
- this.nameTest = nameTest;
- this.includeDescendants = descendants;
- }
-
- /**
* Creates a new <code>LocationStepQueryNode</code> that matches only
* the empty name (the repository root). The created location step
* uses only the child axis.
*/
- public LocationStepQueryNode(QueryNode parent) {
+ protected LocationStepQueryNode(QueryNode parent) {
super(parent);
this.nameTest = EMPTY_NAME;
this.includeDescendants = false;
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NodeTypeQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NodeTypeQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NodeTypeQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NodeTypeQueryNode.java Mon Aug 27 05:56:01 2007
@@ -29,7 +29,7 @@
* @param parent the parent node for this query node.
* @param nodeType the name of the node type.
*/
- public NodeTypeQueryNode(QueryNode parent, QName nodeType) {
+ protected NodeTypeQueryNode(QueryNode parent, QName nodeType) {
// we only use the jcr primary type as a dummy value
// the property name is actually replaced in the query builder
// when the runtime query is created to search the index.
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NotQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NotQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NotQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/NotQueryNode.java Mon Aug 27 05:56:01 2007
@@ -26,20 +26,8 @@
*
* @param parent the parent node for this query node.
*/
- public NotQueryNode(QueryNode parent) {
+ protected NotQueryNode(QueryNode parent) {
super(parent);
- }
-
- /**
- * Creates a new <code>NotQueryNode</code> instance.
- *
- * @param parent the parent node for this query node.
- * @param node the child query node to invert.
- */
- public NotQueryNode(QueryNode parent, QueryNode node) {
- super(parent, new QueryNode[]{
- node
- });
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrQueryNode.java Mon Aug 27 05:56:01 2007
@@ -28,20 +28,8 @@
*
* @param parent the parent of <code>this</code> <code>OrQueryNode</code>.
*/
- public OrQueryNode(QueryNode parent) {
+ protected OrQueryNode(QueryNode parent) {
super(parent);
- }
-
- /**
- * Creates a new <code>OrQueryNode</code> with a <code>parent</code> query
- * node and <code>operands</code> for <code>this</code>
- * <code>OrQueryNode</code>.
- *
- * @param parent the parent of <code>this</code> <code>OrQueryNode</code>.
- * @param operands the operands for this OR operation.
- */
- public OrQueryNode(QueryNode parent, QueryNode[] operands) {
- super(parent, operands);
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrderQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrderQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrderQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/OrderQueryNode.java Mon Aug 27 05:56:01 2007
@@ -38,7 +38,7 @@
*
* @param parent the parent node of this query node.
*/
- public OrderQueryNode(QueryNode parent) {
+ protected OrderQueryNode(QueryNode parent) {
super(parent);
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PathQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PathQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PathQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PathQueryNode.java Mon Aug 27 05:56:01 2007
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.core.query;
+import java.util.List;
+
import org.apache.jackrabbit.name.QName;
/**
@@ -29,17 +31,33 @@
private boolean absolute = false;
/**
+ * List of valid node type names under /jcr:system
+ */
+ private final List validJcrSystemNodeTypeNames;
+
+ /**
* Empty step node array.
*/
private static final LocationStepQueryNode[] EMPTY = new LocationStepQueryNode[0];
/**
- * Creates a relative <code>PathQueryNode</code> with no location steps.
+ * Creates a relative <code>PathQueryNode</code> with no location steps and
+ * the list of node types under /jcr:system.
*
* @param parent the parent query node.
*/
- public PathQueryNode(QueryNode parent) {
+ protected PathQueryNode(QueryNode parent, List validJcrSystemNodeTypeNames) {
super(parent);
+ this.validJcrSystemNodeTypeNames = validJcrSystemNodeTypeNames;
+ }
+
+ /**
+ * Returns a list of valid node types under /jcr:system. List<QName>.
+ *
+ * @return a list of valid node types under /jcr:system.
+ */
+ public List getValidJcrSystemNodeTypeNames() {
+ return validJcrSystemNodeTypeNames;
}
/**
@@ -125,10 +143,23 @@
}
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)
+ if (firstPathStepName == null) {
+ // If the first operand of the path steps is a node type query
+ // we do not need to include the system index if the node type is
+ // none of the node types that may occur in the system index.
+ QueryNode[] pathStepOperands = pathSteps[0].getOperands();
+ if (pathStepOperands.length > 0) {
+ if (pathStepOperands[0] instanceof NodeTypeQueryNode) {
+ NodeTypeQueryNode nodeTypeQueryNode = (NodeTypeQueryNode) pathStepOperands[0];
+ if (!validJcrSystemNodeTypeNames.contains(nodeTypeQueryNode.getValue())) {
+ return false;
+ }
+ }
+ }
+ // If the first location step has a null name test we need to include
+ // the system tree ("*")
return true;
+ }
// Calculate the first workspace relative location step
LocationStepQueryNode firstWorkspaceRelativeStep = pathSteps[0];
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PropertyFunctionQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PropertyFunctionQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PropertyFunctionQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/PropertyFunctionQueryNode.java Mon Aug 27 05:56:01 2007
@@ -70,7 +70,7 @@
* @throws IllegalArgumentException if <code>functionName</code> is not a
* supported function.
*/
- public PropertyFunctionQueryNode(QueryNode parent, String functionName)
+ protected PropertyFunctionQueryNode(QueryNode parent, String functionName)
throws IllegalArgumentException {
super(parent);
if (!SUPPORTED_FUNCTION_NAMES.contains(functionName)) {
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryNodeFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryNodeFactory.java?rev=570095&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryNodeFactory.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryNodeFactory.java Mon Aug 27 05:56:01 2007
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.query;
+
+import org.apache.jackrabbit.name.QName;
+
+/**
+ * A factory for {@link QueryNode}s.
+ */
+public interface QueryNodeFactory {
+
+ /**
+ * Creates a {@link NodeTypeQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @param nodeType the name of the node type.
+ * @return a {@link NodeTypeQueryNode}.
+ */
+ public NodeTypeQueryNode createNodeTypeQueryNode(
+ QueryNode parent, QName nodeType);
+
+ /**
+ * Creates a {@link AndQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @return a {@link AndQueryNode}.
+ */
+ public AndQueryNode createAndQueryNode(
+ QueryNode parent);
+
+ /**
+ * Creates a {@link LocationStepQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @return a {@link LocationStepQueryNode}.
+ */
+ public LocationStepQueryNode createLocationStepQueryNode(
+ QueryNode parent);
+
+ /**
+ * Creates a {@link DerefQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @param nameTest the name test on the referenced target node.
+ * @param descendants if the axis is //
+ * @return a {@link DerefQueryNode}.
+ */
+ public DerefQueryNode createDerefQueryNode(
+ QueryNode parent, QName nameTest, boolean descendants);
+
+ /**
+ * Creates a {@link NotQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @return a {@link NotQueryNode}.
+ */
+ public NotQueryNode createNotQueryNode(
+ QueryNode parent);
+
+ /**
+ * Creates a {@link OrQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @return a {@link OrQueryNode}.
+ */
+ public OrQueryNode createOrQueryNode(
+ QueryNode parent);
+
+ /**
+ * Creates a {@link RelationQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @param operation the operation type.
+ * @return a {@link RelationQueryNode}.
+ */
+ public RelationQueryNode createRelationQueryNode(
+ QueryNode parent, int operation);
+
+ /**
+ * Creates a {@link PathQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @return a {@link PathQueryNode}.
+ */
+ public PathQueryNode createPathQueryNode(
+ QueryNode parent);
+
+ /**
+ * Creates a {@link OrderQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @return a {@link OrderQueryNode}.
+ */
+ public OrderQueryNode createOrderQueryNode(
+ QueryNode parent);
+
+ /**
+ * Creates a {@link PropertyFunctionQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @param functionName the name of the function.
+ * @return a {@link PropertyFunctionQueryNode}.
+ */
+ public PropertyFunctionQueryNode createPropertyFunctionQueryNode(
+ QueryNode parent, String functionName);
+
+ /**
+ * Creates a {@link QueryRootNode} instance.
+ *
+ * @return a {@link QueryRootNode}.
+ */
+ public QueryRootNode createQueryRootNode();
+
+ /**
+ * Creates a {@link TextsearchQueryNode} instance.
+ *
+ * @param parent the parent node.
+ * @param query the textsearch statement.
+ * @return a {@link TextsearchQueryNode}.
+ */
+ public TextsearchQueryNode createTextsearchQueryNode(
+ QueryNode parent, String query);
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryNodeFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryParser.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryParser.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryParser.java Mon Aug 27 05:56:01 2007
@@ -41,17 +41,19 @@
*
* @param statement the query statement.
* @param language the language of the query statement.
+ * @param factory the query node factory.
* @return the root node of the generated query tree.
* @throws InvalidQueryException if an error occurs while parsing the
* statement.
*/
public static QueryRootNode parse(String statement,
String language,
- NamespaceResolver resolver)
+ NamespaceResolver resolver,
+ QueryNodeFactory factory)
throws InvalidQueryException {
QueryTreeBuilder builder = QueryTreeBuilderRegistry.getQueryTreeBuilder(language);
- return builder.createQueryTree(statement, resolver);
+ return builder.createQueryTree(statement, resolver, factory);
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryRootNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryRootNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryRootNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryRootNode.java Mon Aug 27 05:56:01 2007
@@ -45,7 +45,7 @@
/**
* Creates a new <code>QueryRootNode</code> instance.
*/
- public QueryRootNode() {
+ protected QueryRootNode() {
super(null);
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryTreeBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryTreeBuilder.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryTreeBuilder.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryTreeBuilder.java Mon Aug 27 05:56:01 2007
@@ -26,15 +26,19 @@
public interface QueryTreeBuilder {
/**
- * Creates a <code>QueryNode</code> tree from a statement.
+ * Creates a <code>QueryNode</code> tree from a statement using the passed
+ * query node factory.
*
* @param statement the statement.
* @param resolver the namespace resolver to use.
+ * @param factory the query node factory to use.
* @return the <code>QueryNode</code> tree for the statement.
* @throws javax.jcr.query.InvalidQueryException
* if the statement is malformed.
*/
- QueryRootNode createQueryTree(String statement, NamespaceResolver resolver)
+ QueryRootNode createQueryTree(String statement,
+ NamespaceResolver resolver,
+ QueryNodeFactory factory)
throws InvalidQueryException;
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/RelationQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/RelationQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/RelationQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/RelationQueryNode.java Mon Aug 27 05:56:01 2007
@@ -92,77 +92,9 @@
*
* @param parent the parent node for this query node.
*/
- public RelationQueryNode(QueryNode parent, int operation) {
+ protected RelationQueryNode(QueryNode parent, int operation) {
super(parent);
this.operation = operation;
- }
-
- /**
- * Creates a new <code>RelationQueryNode</code> with a <code>long</code>
- * <code>value</code> and an <code>operation</code> type.
- *
- * @param parent the parent node for this query node.
- * @param relPath the relative path to a property.
- * @param value a property value
- * @param operation the type of the relation.
- */
- public RelationQueryNode(QueryNode parent, Path relPath, long value, int operation) {
- super(parent);
- this.relPath = relPath;
- this.valueLong = value;
- this.operation = operation;
- this.type = TYPE_LONG;
- }
-
- /**
- * Creates a new <code>RelationQueryNode</code> with a <code>double</code>
- * <code>value</code> and an <code>operation</code> type.
- *
- * @param parent the parent node for this query node.
- * @param relPath the relative path to a property.
- * @param value a property value
- * @param operation the type of the relation.
- */
- public RelationQueryNode(QueryNode parent, Path relPath, double value, int operation) {
- super(parent);
- this.relPath = relPath;
- this.valueDouble = value;
- this.operation = operation;
- this.type = TYPE_DOUBLE;
- }
-
- /**
- * Creates a new <code>RelationQueryNode</code> with a <code>Date</code>
- * <code>value</code> and an <code>operation</code> type.
- *
- * @param parent the parent node for this query node.
- * @param relPath the relative path to a property.
- * @param value a property value
- * @param operation the type of the relation.
- */
- public RelationQueryNode(QueryNode parent, Path relPath, Date value, int operation) {
- super(parent);
- this.relPath = relPath;
- this.valueDate = value;
- this.operation = operation;
- this.type = TYPE_DATE;
- }
-
- /**
- * Creates a new <code>RelationQueryNode</code> with a <code>String</code>
- * <code>value</code> and an <code>operation</code> type.
- *
- * @param parent the parent node for this query node.
- * @param relPath the relative path to a property.
- * @param value a property value
- * @param operation the type of the relation.
- */
- public RelationQueryNode(QueryNode parent, Path relPath, String value, int operation) {
- super(parent);
- this.relPath = relPath;
- this.valueString = value;
- this.operation = operation;
- this.type = TYPE_STRING;
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/TextsearchQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/TextsearchQueryNode.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/TextsearchQueryNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/TextsearchQueryNode.java Mon Aug 27 05:56:01 2007
@@ -52,27 +52,11 @@
* @param parent the parent node of this query node.
* @param query the textsearch statement.
*/
- public TextsearchQueryNode(QueryNode parent, String query) {
- this(parent, query, null, false);
- }
-
- /**
- * Creates a new <code>TextsearchQueryNode</code> with a <code>parent</code>
- * and a textsearch <code>query</code> statement. The scope of the query is
- * the property or node referenced by <code>relPath</code>.
- *
- * @param parent the parent node of this query node.
- * @param query the textsearch statement.
- * @param relPath scope of the fulltext search. If <code>null</code> the
- * context node is searched.
- * @param isProperty if <code>relPath</code> references a property or a
- * node.
- */
- public TextsearchQueryNode(QueryNode parent, String query, Path relPath, boolean isProperty) {
+ protected TextsearchQueryNode(QueryNode parent, String query) {
super(parent);
this.query = query;
- this.relPath = relPath;
- this.propertyRef = isProperty;
+ this.relPath = null;
+ this.propertyRef = false;
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java Mon Aug 27 05:56:01 2007
@@ -30,6 +30,7 @@
import org.apache.jackrabbit.core.query.QueryParser;
import org.apache.jackrabbit.core.query.QueryRootNode;
import org.apache.jackrabbit.core.query.AndQueryNode;
+import org.apache.jackrabbit.core.query.QueryNodeFactory;
import org.apache.jackrabbit.name.QName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,14 +57,7 @@
/**
* Represents a query that selects all nodes. E.g. in XPath: //*
*/
- protected static final QueryRootNode ALL_NODES = new QueryRootNode();
-
- static {
- PathQueryNode pathNode = new PathQueryNode(ALL_NODES);
- pathNode.addPathStep(new LocationStepQueryNode(pathNode, null, true));
- pathNode.setAbsolute(true);
- ALL_NODES.setLocationNode(pathNode);
- }
+ protected final QueryRootNode allNodesQueryNode;
/**
* The root node of the query tree
@@ -105,6 +99,7 @@
* @param propReg the property type registry.
* @param statement the query statement.
* @param language the syntax of the query statement.
+ * @param factory the query node factory.
* @throws InvalidQueryException if the query statement is invalid according
* to the specified <code>language</code>.
*/
@@ -113,14 +108,26 @@
SearchIndex index,
PropertyTypeRegistry propReg,
String statement,
- String language) throws InvalidQueryException {
+ String language,
+ QueryNodeFactory factory) throws InvalidQueryException {
this.session = session;
this.itemMgr = itemMgr;
this.index = index;
this.propReg = propReg;
// parse query according to language
- // build query tree
- this.root = QueryParser.parse(statement, language, session.getNamespaceResolver());
+ // build query tree using the passed factory
+ this.root = QueryParser.parse(statement, language,
+ session.getNamespaceResolver(), factory);
+
+ allNodesQueryNode = factory.createQueryRootNode();
+ PathQueryNode pathNode = factory.createPathQueryNode(allNodesQueryNode);
+ LocationStepQueryNode lsNode = factory.createLocationStepQueryNode(pathNode);
+ lsNode.setNameTest(null);
+ lsNode.setIncludeDescendants(true);
+ pathNode.addPathStep(lsNode);
+ pathNode.setAbsolute(true);
+ allNodesQueryNode.setLocationNode(pathNode);
+
}
/**
@@ -137,7 +144,7 @@
}
// check for special query
- if (ALL_NODES.equals(root)) {
+ if (allNodesQueryNode.equals(root)) {
return new WorkspaceTraversalResult(session,
new QName[] { QName.JCR_PRIMARYTYPE, QName.JCR_PATH, QName.JCR_SCORE },
session.getNamespaceResolver());
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java Mon Aug 27 05:56:01 2007
@@ -21,6 +21,7 @@
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.NodeIdIterator;
import org.apache.jackrabbit.core.query.AbstractQueryHandler;
+import org.apache.jackrabbit.core.query.DefaultQueryNodeFactory;
import org.apache.jackrabbit.core.query.ExecutableQuery;
import org.apache.jackrabbit.core.query.QueryHandlerContext;
import org.apache.jackrabbit.core.query.QueryHandler;
@@ -59,6 +60,7 @@
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.File;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
@@ -74,6 +76,27 @@
*/
public class SearchIndex extends AbstractQueryHandler {
+ public static final List VALID_SYSTEM_INDEX_NODE_TYPE_NAMES
+ = Collections.unmodifiableList(Arrays.asList(new QName[]{
+ QName.NT_CHILDNODEDEFINITION,
+ QName.NT_FROZENNODE,
+ QName.NT_NODETYPE,
+ QName.NT_PROPERTYDEFINITION,
+ QName.NT_VERSION,
+ QName.NT_VERSIONEDCHILD,
+ QName.NT_VERSIONHISTORY,
+ QName.NT_VERSIONLABELS,
+ QName.REP_NODETYPES,
+ QName.REP_SYSTEM,
+ QName.REP_VERSIONSTORAGE,
+ // Supertypes
+ QName.NT_BASE,
+ QName.MIX_REFERENCEABLE
+ }));
+
+ private static final DefaultQueryNodeFactory DEFAULT_QUERY_NODE_FACTORY = new DefaultQueryNodeFactory(
+ VALID_SYSTEM_INDEX_NODE_TYPE_NAMES);
+
/** The logger instance for this class */
private static final Logger log = LoggerFactory.getLogger(SearchIndex.class);
@@ -492,9 +515,17 @@
String language)
throws InvalidQueryException {
QueryImpl query = new QueryImpl(session, itemMgr, this,
- getContext().getPropertyTypeRegistry(), statement, language);
+ getContext().getPropertyTypeRegistry(), statement, language, getQueryNodeFactory());
query.setRespectDocumentOrder(documentOrder);
return query;
+ }
+
+ /**
+ * This method returns the QueryNodeFactory used to parse Queries. This method
+ * may be overridden to provide a customized QueryNodeFactory
+ */
+ protected DefaultQueryNodeFactory getQueryNodeFactory() {
+ return DEFAULT_QUERY_NODE_FACTORY;
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/JCRSQLQueryBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/JCRSQLQueryBuilder.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/JCRSQLQueryBuilder.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/JCRSQLQueryBuilder.java Mon Aug 27 05:56:01 2007
@@ -30,6 +30,7 @@
import org.apache.jackrabbit.core.query.RelationQueryNode;
import org.apache.jackrabbit.core.query.TextsearchQueryNode;
import org.apache.jackrabbit.core.query.PropertyFunctionQueryNode;
+import org.apache.jackrabbit.core.query.QueryNodeFactory;
import org.apache.jackrabbit.name.NameException;
import org.apache.jackrabbit.name.NamespaceResolver;
import org.apache.jackrabbit.name.QName;
@@ -74,7 +75,6 @@
*/
private static Map parsers = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.WEAK);
-
/**
* The root node of the sql query syntax tree
*/
@@ -93,7 +93,7 @@
/**
* Query node to gather the constraints defined in the WHERE clause
*/
- private final AndQueryNode constraintNode = new AndQueryNode(null);
+ private final AndQueryNode constraintNode;
/**
* The QName of the node type in the from clause.
@@ -106,26 +106,39 @@
private final List pathConstraints = new ArrayList();
/**
+ * The query node factory.
+ */
+ private final QueryNodeFactory factory;
+
+ /**
* Creates a new <code>JCRSQLQueryBuilder</code>.
*
* @param statement the root node of the SQL syntax tree.
* @param resolver a namespace resolver to use for names in the
* <code>statement</code>.
+ * @param factory the query node factory.
*/
- private JCRSQLQueryBuilder(ASTQuery statement, NamespaceResolver resolver) {
+ private JCRSQLQueryBuilder(ASTQuery statement,
+ NamespaceResolver resolver,
+ QueryNodeFactory factory) {
this.stmt = statement;
this.resolver = resolver;
+ this.factory = factory;
+ this.constraintNode = factory.createAndQueryNode(null);
}
/**
- * Creates a <code>QueryNode</code> tree from a SQL <code>statement</code>.
+ * Creates a <code>QueryNode</code> tree from a SQL <code>statement</code>
+ * using the passed query node <code>factory</code>.
*
* @param statement the SQL statement.
* @param resolver the namespace resolver to use.
* @return the <code>QueryNode</code> tree.
* @throws InvalidQueryException if <code>statement</code> is malformed.
*/
- public static QueryRootNode createQuery(String statement, NamespaceResolver resolver)
+ public static QueryRootNode createQuery(String statement,
+ NamespaceResolver resolver,
+ QueryNodeFactory factory)
throws InvalidQueryException {
try {
// get parser
@@ -143,7 +156,7 @@
// guard against concurrent use within same session
synchronized (parser) {
parser.ReInit(new StringReader(statement));
- builder = new JCRSQLQueryBuilder(parser.Query(), resolver);
+ builder = new JCRSQLQueryBuilder(parser.Query(), resolver, factory);
}
return builder.getRootNode();
} catch (ParseException e) {
@@ -191,8 +204,8 @@
}
public Object visit(ASTQuery node, Object data) {
- root = new QueryRootNode();
- root.setLocationNode(new PathQueryNode(root));
+ root = factory.createQueryRootNode();
+ root.setLocationNode(factory.createPathQueryNode(root));
// pass to select, from, where, ...
node.childrenAccept(this, root);
@@ -201,7 +214,10 @@
PathQueryNode pathNode = root.getLocationNode();
pathNode.setAbsolute(true);
if (pathConstraints.size() == 0) {
- pathNode.addPathStep(new LocationStepQueryNode(pathNode, null, true));
+ LocationStepQueryNode step = factory.createLocationStepQueryNode(pathNode);
+ step.setNameTest(null);
+ step.setIncludeDescendants(true);
+ pathNode.addPathStep(step);
} else {
try {
while (pathConstraints.size() > 1) {
@@ -231,7 +247,9 @@
MergingPathQueryNode path = (MergingPathQueryNode) pathConstraints.get(0);
LocationStepQueryNode[] steps = path.getPathSteps();
for (int i = 0; i < steps.length; i++) {
- LocationStepQueryNode step = new LocationStepQueryNode(pathNode, steps[i].getNameTest(), steps[i].getIncludeDescendants());
+ LocationStepQueryNode step = factory.createLocationStepQueryNode(pathNode);
+ step.setNameTest(steps[i].getNameTest());
+ step.setIncludeDescendants(steps[i].getIncludeDescendants());
step.setIndex(steps[i].getIndex());
pathNode.addPathStep(step);
}
@@ -247,7 +265,7 @@
// add node type constraint
LocationStepQueryNode[] steps = pathNode.getPathSteps();
NodeTypeQueryNode nodeType
- = new NodeTypeQueryNode(steps[steps.length - 1], nodeTypeName);
+ = factory.createNodeTypeQueryNode(steps[steps.length - 1], nodeTypeName);
steps[steps.length - 1].addPredicate(nodeType);
}
@@ -351,7 +369,7 @@
}
if (type == QueryConstants.OPERATION_BETWEEN) {
- AndQueryNode between = new AndQueryNode(parent);
+ AndQueryNode between = factory.createAndQueryNode(parent);
RelationQueryNode rel = createRelationQueryNode(between,
identifier, QueryConstants.OPERATION_GE_GENERAL, (ASTLiteral) node.children[1]);
node.childrenAccept(this, rel);
@@ -389,7 +407,7 @@
identifier, type, pattern);
node.childrenAccept(this, predicateNode);
} else if (type == QueryConstants.OPERATION_IN) {
- OrQueryNode in = new OrQueryNode(parent);
+ OrQueryNode in = factory.createOrQueryNode(parent);
for (int i = 1; i < node.children.length; i++) {
RelationQueryNode rel = createRelationQueryNode(in,
identifier, QueryConstants.OPERATION_EQ_VALUE, (ASTLiteral) node.children[i]);
@@ -424,7 +442,7 @@
public Object visit(ASTOrExpression node, Object data) {
NAryQueryNode parent = (NAryQueryNode) data;
- OrQueryNode orQuery = new OrQueryNode(parent);
+ OrQueryNode orQuery = factory.createOrQueryNode(parent);
// pass to operands
node.childrenAccept(this, orQuery);
@@ -436,7 +454,7 @@
public Object visit(ASTAndExpression node, Object data) {
NAryQueryNode parent = (NAryQueryNode) data;
- AndQueryNode andQuery = new AndQueryNode(parent);
+ AndQueryNode andQuery = factory.createAndQueryNode(parent);
// pass to operands
node.childrenAccept(this, andQuery);
@@ -446,7 +464,7 @@
public Object visit(ASTNotExpression node, Object data) {
NAryQueryNode parent = (NAryQueryNode) data;
- NotQueryNode notQuery = new NotQueryNode(parent);
+ NotQueryNode notQuery = factory.createNotQueryNode(parent);
// pass to operand
node.childrenAccept(this, notQuery);
@@ -474,7 +492,7 @@
public Object visit(ASTOrderByClause node, Object data) {
QueryRootNode root = (QueryRootNode) data;
- OrderQueryNode order = new OrderQueryNode(root);
+ OrderQueryNode order = factory.createOrderQueryNode(root);
root.setOrderNode(order);
node.childrenAccept(this, order);
return root;
@@ -521,7 +539,10 @@
builder.addLast(node.getPropertyName());
relPath = builder.getPath();
}
- parent.addOperand(new TextsearchQueryNode(parent, node.getQuery(), relPath, true));
+ TextsearchQueryNode tsNode = factory.createTextsearchQueryNode(parent, node.getQuery());
+ tsNode.setRelativePath(relPath);
+ tsNode.setReferencesProperty(true);
+ parent.addOperand(tsNode);
} catch (MalformedPathException e) {
// path is always valid
}
@@ -534,7 +555,7 @@
String msg = "LOWER() function is only supported for String literal";
throw new IllegalArgumentException(msg);
}
- parent.addOperand(new PropertyFunctionQueryNode(parent, PropertyFunctionQueryNode.LOWER_CASE));
+ parent.addOperand(factory.createPropertyFunctionQueryNode(parent, PropertyFunctionQueryNode.LOWER_CASE));
return parent;
}
@@ -544,7 +565,7 @@
String msg = "UPPER() function is only supported for String literal";
throw new IllegalArgumentException(msg);
}
- parent.addOperand(new PropertyFunctionQueryNode(parent, PropertyFunctionQueryNode.UPPER_CASE));
+ parent.addOperand(factory.createPropertyFunctionQueryNode(parent, PropertyFunctionQueryNode.UPPER_CASE));
return parent;
}
@@ -585,18 +606,28 @@
if (literal.getType() == QueryConstants.TYPE_DATE) {
SimpleDateFormat format = new SimpleDateFormat(DATE_PATTERN);
Date date = format.parse(stringValue);
- node = new RelationQueryNode(parent, relPath, date, operationType);
+ node = factory.createRelationQueryNode(parent, operationType);
+ node.setRelativePath(relPath);
+ node.setDateValue(date);
} else if (literal.getType() == QueryConstants.TYPE_DOUBLE) {
double d = Double.parseDouble(stringValue);
- node = new RelationQueryNode(parent, relPath, d, operationType);
+ node = factory.createRelationQueryNode(parent, operationType);
+ node.setRelativePath(relPath);
+ node.setDoubleValue(d);
} else if (literal.getType() == QueryConstants.TYPE_LONG) {
long l = Long.parseLong(stringValue);
- node = new RelationQueryNode(parent, relPath, l, operationType);
+ node = factory.createRelationQueryNode(parent, operationType);
+ node.setRelativePath(relPath);
+ node.setLongValue(l);
} else if (literal.getType() == QueryConstants.TYPE_STRING) {
- node = new RelationQueryNode(parent, relPath, stringValue, operationType);
+ node = factory.createRelationQueryNode(parent, operationType);
+ node.setRelativePath(relPath);
+ node.setStringValue(stringValue);
} else if (literal.getType() == QueryConstants.TYPE_TIMESTAMP) {
Calendar c = ISO8601.parse(stringValue);
- node = new RelationQueryNode(parent, relPath, c.getTime(), operationType);
+ node = factory.createRelationQueryNode(parent, operationType);
+ node.setRelativePath(relPath);
+ node.setDateValue(c.getTime());
}
} catch (java.text.ParseException e) {
throw new IllegalArgumentException(e.toString());
@@ -620,11 +651,12 @@
* @param operation the type of the parent node
*/
private void createPathQuery(String path, int operation) {
- MergingPathQueryNode pathNode = new MergingPathQueryNode(operation);
+ MergingPathQueryNode pathNode = new MergingPathQueryNode(operation,
+ factory.createPathQueryNode(null).getValidJcrSystemNodeTypeNames());
pathNode.setAbsolute(true);
if (path.equals("/")) {
- pathNode.addPathStep(new LocationStepQueryNode(pathNode));
+ pathNode.addPathStep(factory.createLocationStepQueryNode(pathNode));
pathConstraints.add(pathNode);
return;
}
@@ -635,13 +667,13 @@
if (names[i].length() == 0) {
if (i == 0) {
// root
- pathNode.addPathStep(new LocationStepQueryNode(pathNode));
+ pathNode.addPathStep(factory.createLocationStepQueryNode(pathNode));
} else {
// descendant '//' -> invalid path
// todo throw or ignore?
// we currently do not throw and add location step for an
// empty name (which is basically the root node)
- pathNode.addPathStep(new LocationStepQueryNode(pathNode));
+ pathNode.addPathStep(factory.createLocationStepQueryNode(pathNode));
}
} else {
int idx = names[i].indexOf('[');
@@ -686,7 +718,9 @@
}
// if name test is % this means also search descendants
boolean descendant = name == null;
- LocationStepQueryNode step = new LocationStepQueryNode(pathNode, qName, descendant);
+ LocationStepQueryNode step = factory.createLocationStepQueryNode(pathNode);
+ step.setNameTest(qName);
+ step.setIncludeDescendants(descendant);
if (index > 0) {
step.setIndex(index);
}
@@ -779,9 +813,11 @@
* {@link org.apache.jackrabbit.core.query.QueryNode#TYPE_NOT}.
*
* @param operation the operation type of the parent node.
+ * @param validJcrSystemNodeTypeNames names of valid node types under
+ * /jcr:system.
*/
- MergingPathQueryNode(int operation) {
- super(null);
+ MergingPathQueryNode(int operation, List validJcrSystemNodeTypeNames) {
+ super(null, validJcrSystemNodeTypeNames);
if (operation != QueryNode.TYPE_OR && operation != QueryNode.TYPE_AND && operation != QueryNode.TYPE_NOT) {
throw new IllegalArgumentException("operation");
}
@@ -883,7 +919,8 @@
*/
private MergingPathQueryNode[] doOrMerge(MergingPathQueryNode[] nodes) {
// compact this
- MergingPathQueryNode compacted = new MergingPathQueryNode(QueryNode.TYPE_OR);
+ MergingPathQueryNode compacted = new MergingPathQueryNode(
+ QueryNode.TYPE_OR, getValidJcrSystemNodeTypeNames());
for (Iterator it = operands.iterator(); it.hasNext();) {
LocationStepQueryNode step = (LocationStepQueryNode) it.next();
if (step.getIncludeDescendants() && step.getNameTest() == null) {
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/QueryBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/QueryBuilder.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/QueryBuilder.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/sql/QueryBuilder.java Mon Aug 27 05:56:01 2007
@@ -18,6 +18,7 @@
import org.apache.jackrabbit.core.query.QueryTreeBuilder;
import org.apache.jackrabbit.core.query.QueryRootNode;
+import org.apache.jackrabbit.core.query.QueryNodeFactory;
import org.apache.jackrabbit.name.NamespaceResolver;
import javax.jcr.query.InvalidQueryException;
@@ -32,9 +33,10 @@
* @inheritDoc
*/
public QueryRootNode createQueryTree(String statement,
- NamespaceResolver resolver)
+ NamespaceResolver resolver,
+ QueryNodeFactory factory)
throws InvalidQueryException {
- return JCRSQLQueryBuilder.createQuery(statement, resolver);
+ return JCRSQLQueryBuilder.createQuery(statement, resolver, factory);
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryBuilder.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryBuilder.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/QueryBuilder.java Mon Aug 27 05:56:01 2007
@@ -18,6 +18,7 @@
import org.apache.jackrabbit.core.query.QueryTreeBuilder;
import org.apache.jackrabbit.core.query.QueryRootNode;
+import org.apache.jackrabbit.core.query.QueryNodeFactory;
import org.apache.jackrabbit.name.NamespaceResolver;
import javax.jcr.query.InvalidQueryException;
@@ -32,9 +33,10 @@
* @inheritDoc
*/
public QueryRootNode createQueryTree(String statement,
- NamespaceResolver resolver)
+ NamespaceResolver resolver,
+ QueryNodeFactory factory)
throws InvalidQueryException {
- return XPathQueryBuilder.createQuery(statement, resolver);
+ return XPathQueryBuilder.createQuery(statement, resolver, factory);
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/xpath/XPathQueryBuilder.java Mon Aug 27 05:56:01 2007
@@ -16,13 +16,11 @@
*/
package org.apache.jackrabbit.core.query.xpath;
-import org.apache.jackrabbit.core.query.AndQueryNode;
import org.apache.jackrabbit.core.query.DerefQueryNode;
import org.apache.jackrabbit.core.query.LocationStepQueryNode;
import org.apache.jackrabbit.core.query.NAryQueryNode;
import org.apache.jackrabbit.core.query.NodeTypeQueryNode;
import org.apache.jackrabbit.core.query.NotQueryNode;
-import org.apache.jackrabbit.core.query.OrQueryNode;
import org.apache.jackrabbit.core.query.OrderQueryNode;
import org.apache.jackrabbit.core.query.PathQueryNode;
import org.apache.jackrabbit.core.query.QueryConstants;
@@ -32,6 +30,7 @@
import org.apache.jackrabbit.core.query.TextsearchQueryNode;
import org.apache.jackrabbit.core.query.PropertyFunctionQueryNode;
import org.apache.jackrabbit.core.query.DefaultQueryNodeVisitor;
+import org.apache.jackrabbit.core.query.QueryNodeFactory;
import org.apache.jackrabbit.name.NameException;
import org.apache.jackrabbit.name.NamespaceResolver;
import org.apache.jackrabbit.name.NoPrefixDeclaredException;
@@ -223,7 +222,7 @@
/**
* The root <code>QueryNode</code>
*/
- private final QueryRootNode root = new QueryRootNode();
+ private final QueryRootNode root;
/**
* The {@link NamespaceResolver} in use
@@ -241,15 +240,25 @@
private Path.PathBuilder tmpRelPath;
/**
+ * The query node factory.
+ */
+ private final QueryNodeFactory factory;
+
+ /**
* Creates a new <code>XPathQueryBuilder</code> instance.
*
* @param statement the XPath statement.
* @param resolver the namespace resolver to use.
+ * @param factory the query node factory.
* @throws InvalidQueryException if the XPath statement is malformed.
*/
- private XPathQueryBuilder(String statement, NamespaceResolver resolver)
+ private XPathQueryBuilder(String statement,
+ NamespaceResolver resolver,
+ QueryNodeFactory factory)
throws InvalidQueryException {
this.resolver = resolver;
+ this.factory = factory;
+ this.root = factory.createQueryRootNode();
try {
// create an XQuery statement because we're actually using an
// XQuery parser.
@@ -291,17 +300,20 @@
}
/**
- * Creates a <code>QueryNode</code> tree from a XPath statement.
+ * Creates a <code>QueryNode</code> tree from a XPath statement using the
+ * passed query node <code>factory</code>.
*
* @param statement the XPath statement.
* @param resolver the namespace resolver to use.
+ * @param factory the query node factory.
* @return the <code>QueryNode</code> tree for the XPath statement.
* @throws InvalidQueryException if the XPath statement is malformed.
*/
public static QueryRootNode createQuery(String statement,
- NamespaceResolver resolver)
+ NamespaceResolver resolver,
+ QueryNodeFactory factory)
throws InvalidQueryException {
- return new XPathQueryBuilder(statement, resolver).getRootNode();
+ return new XPathQueryBuilder(statement, resolver, factory).getRootNode();
}
/**
@@ -365,7 +377,7 @@
} else if (queryNode.getType() == QueryNode.TYPE_NOT) {
// is null expression
RelationQueryNode isNull
- = new RelationQueryNode(queryNode,
+ = factory.createRelationQueryNode(queryNode,
RelationQueryNode.OPERATION_NULL);
applyRelativePath(isNull);
node.childrenAccept(this, isNull);
@@ -376,7 +388,7 @@
} else {
// not null expression
RelationQueryNode notNull =
- new RelationQueryNode(queryNode,
+ factory.createRelationQueryNode(queryNode,
RelationQueryNode.OPERATION_NOT_NULL);
applyRelativePath(notNull);
node.childrenAccept(this, notNull);
@@ -390,7 +402,7 @@
node.childrenAccept(this, queryNode);
} else {
// step within a predicate
- RelationQueryNode tmp = new RelationQueryNode(
+ RelationQueryNode tmp = factory.createRelationQueryNode(
null, RelationQueryNode.OPERATION_NOT_NULL);
node.childrenAccept(this, tmp);
if (tmpRelPath == null) {
@@ -434,7 +446,7 @@
String ntName = ((SimpleNode) node.jjtGetChild(0)).getValue();
try {
QName nt = NameFormat.parse(ntName, resolver);
- NodeTypeQueryNode nodeType = new NodeTypeQueryNode(loc, nt);
+ NodeTypeQueryNode nodeType = factory.createNodeTypeQueryNode(loc, nt);
loc.addPredicate(nodeType);
} catch (NameException e) {
exceptions.add(new InvalidQueryException("Not a valid name: " + ntName));
@@ -443,14 +455,14 @@
break;
case JJTOREXPR:
NAryQueryNode parent = (NAryQueryNode) queryNode;
- QueryNode orQueryNode = new OrQueryNode(parent);
+ QueryNode orQueryNode = factory.createOrQueryNode(parent);
parent.addOperand(orQueryNode);
// traverse
node.childrenAccept(this, orQueryNode);
break;
case JJTANDEXPR:
parent = (NAryQueryNode) queryNode;
- QueryNode andQueryNode = new AndQueryNode(parent);
+ QueryNode andQueryNode = factory.createAndQueryNode(parent);
parent.addOperand(andQueryNode);
// traverse
node.childrenAccept(this, andQueryNode);
@@ -486,7 +498,7 @@
queryNode = createFunction(node, queryNode);
break;
case JJTORDERBYCLAUSE:
- root.setOrderNode(new OrderQueryNode(root));
+ root.setOrderNode(factory.createOrderQueryNode(root));
queryNode = root.getOrderNode();
node.childrenAccept(this, queryNode);
break;
@@ -561,7 +573,9 @@
for (int i = 0; i < p.jjtGetNumChildren(); i++) {
SimpleNode c = (SimpleNode) p.jjtGetChild(i);
if (c == node) {
- queryNode = new LocationStepQueryNode(parent, null, descendant);
+ queryNode = factory.createLocationStepQueryNode(parent);
+ queryNode.setNameTest(null);
+ queryNode.setIncludeDescendants(descendant);
parent.addOperand(queryNode);
break;
}
@@ -670,7 +684,7 @@
exceptions.add(new InvalidQueryException("Unsupported ComparisonExpr type:" + node.getValue()));
}
- final RelationQueryNode rqn = new RelationQueryNode(queryNode, type);
+ final RelationQueryNode rqn = factory.createRelationQueryNode(queryNode, type);
// traverse
node.childrenAccept(this, rqn);
@@ -699,7 +713,7 @@
* @return the path qurey node
*/
private PathQueryNode createPathQueryNode(SimpleNode node) {
- root.setLocationNode(new PathQueryNode(root));
+ root.setLocationNode(factory.createPathQueryNode(root));
node.childrenAccept(this, root.getLocationNode());
return root.getLocationNode();
}
@@ -746,7 +760,7 @@
if (NameFormat.format(FN_NOT, resolver).equals(fName)
|| NameFormat.format(FN_NOT_10, resolver).equals(fName)) {
if (queryNode instanceof NAryQueryNode) {
- QueryNode not = new NotQueryNode(queryNode);
+ QueryNode not = factory.createNotQueryNode(queryNode);
((NAryQueryNode) queryNode).addOperand(not);
// @todo is this needed?
queryNode = not;
@@ -791,7 +805,7 @@
if (queryNode instanceof NAryQueryNode) {
SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0);
if (literal.getId() == JJTSTRINGLITERAL) {
- TextsearchQueryNode contains = new TextsearchQueryNode(
+ TextsearchQueryNode contains = factory.createTextsearchQueryNode(
queryNode, unescapeQuotes(literal.getValue()));
// assign property name
SimpleNode path = (SimpleNode) node.jjtGetChild(1);
@@ -809,7 +823,8 @@
// check number of arguments
if (node.jjtGetNumChildren() == 3) {
if (queryNode instanceof NAryQueryNode) {
- RelationQueryNode like = new RelationQueryNode(queryNode, RelationQueryNode.OPERATION_LIKE);
+ RelationQueryNode like = factory.createRelationQueryNode(
+ queryNode, RelationQueryNode.OPERATION_LIKE);
((NAryQueryNode) queryNode).addOperand(like);
// assign property name
@@ -889,7 +904,7 @@
}
if (queryNode.getType() == QueryNode.TYPE_PATH) {
PathQueryNode pathNode = (PathQueryNode) queryNode;
- DerefQueryNode derefNode = new DerefQueryNode(pathNode, null, false);
+ DerefQueryNode derefNode = factory.createDerefQueryNode(pathNode, null, false);
// assign property name
node.jjtGetChild(1).jjtAccept(this, derefNode);
@@ -944,7 +959,8 @@
if (node.jjtGetNumChildren() == 2) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode relNode = (RelationQueryNode) queryNode;
- relNode.addOperand(new PropertyFunctionQueryNode(relNode, PropertyFunctionQueryNode.LOWER_CASE));
+ relNode.addOperand(factory.createPropertyFunctionQueryNode(
+ relNode, PropertyFunctionQueryNode.LOWER_CASE));
// get property name
node.jjtGetChild(1).jjtAccept(this, relNode);
} else {
@@ -957,7 +973,8 @@
if (node.jjtGetNumChildren() == 2) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode relNode = (RelationQueryNode) queryNode;
- relNode.addOperand(new PropertyFunctionQueryNode(relNode, PropertyFunctionQueryNode.UPPER_CASE));
+ relNode.addOperand(factory.createPropertyFunctionQueryNode(
+ relNode, PropertyFunctionQueryNode.UPPER_CASE));
// get property name
node.jjtGetChild(1).jjtAccept(this, relNode);
} else {
@@ -970,7 +987,7 @@
if (node.jjtGetNumChildren() == 3) {
if (queryNode instanceof NAryQueryNode) {
NAryQueryNode parent = (NAryQueryNode) queryNode;
- RelationQueryNode rel = new RelationQueryNode(
+ RelationQueryNode rel = factory.createRelationQueryNode(
parent, RelationQueryNode.OPERATION_SIMILAR);
parent.addOperand(rel);
// assign path
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/PathQueryNodeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/PathQueryNodeTest.java?rev=570095&r1=570094&r2=570095&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/PathQueryNodeTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/PathQueryNodeTest.java Mon Aug 27 05:56:01 2007
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.core.query;
+import java.util.Arrays;
+
import junit.framework.TestCase;
import org.apache.jackrabbit.core.query.xpath.XPathQueryBuilder;
@@ -24,44 +26,59 @@
public class PathQueryNodeTest extends TestCase {
+ private static final DefaultQueryNodeFactory QUERY_NODE_FACTORY = new DefaultQueryNodeFactory(
+ Arrays.asList(new QName[] { QName.NT_NODETYPE }));
+
private static final NamespaceResolver JCR_RESOLVER = new NamespaceResolver() {
public String getJCRName(QName qName) {
- return this.getPrefix(qName.getNamespaceURI()) + ":"
- + qName.getLocalName();
+ throw new UnsupportedOperationException();
}
public String getPrefix(String uri) {
- return QName.NS_JCR_PREFIX;
+ throw new UnsupportedOperationException();
}
public QName getQName(String jcrName) {
- return new QName(QName.NS_JCR_URI,
- jcrName.substring(jcrName.indexOf(':')));
+ throw new UnsupportedOperationException();
}
public String getURI(String prefix) {
- return QName.NS_JCR_URI;
+ if (QName.NS_JCR_PREFIX.equals(prefix))
+ return QName.NS_JCR_URI;
+ if (QName.NS_NT_PREFIX.equals(prefix))
+ return QName.NS_NT_URI;
+ return "";
}
};
public void testNeedsSystemTree() throws Exception {
- QueryRootNode queryRootNode = XPathQueryBuilder.createQuery("/jcr:root/*", JCR_RESOLVER);
+ QueryRootNode queryRootNode = XPathQueryBuilder.createQuery("/jcr:root/*", JCR_RESOLVER, QUERY_NODE_FACTORY);
assertTrue(queryRootNode.needsSystemTree());
- queryRootNode = XPathQueryBuilder.createQuery("/jcr:root/test/*", JCR_RESOLVER);
+ queryRootNode = XPathQueryBuilder.createQuery("/jcr:root/test/*", JCR_RESOLVER, QUERY_NODE_FACTORY);
assertFalse(queryRootNode.needsSystemTree());
- queryRootNode = XPathQueryBuilder.createQuery("*", JCR_RESOLVER);
+ queryRootNode = XPathQueryBuilder.createQuery("*", JCR_RESOLVER, QUERY_NODE_FACTORY);
assertTrue(queryRootNode.needsSystemTree());
- queryRootNode = XPathQueryBuilder.createQuery("jcr:system/*", JCR_RESOLVER);
+ queryRootNode = XPathQueryBuilder.createQuery("jcr:system/*", JCR_RESOLVER, QUERY_NODE_FACTORY);
assertTrue(queryRootNode.needsSystemTree());
- queryRootNode = XPathQueryBuilder.createQuery("test//*", JCR_RESOLVER);
+ queryRootNode = XPathQueryBuilder.createQuery("test//*", JCR_RESOLVER, QUERY_NODE_FACTORY);
assertFalse(queryRootNode.needsSystemTree());
- queryRootNode = XPathQueryBuilder.createQuery("//test/*", JCR_RESOLVER);
+ queryRootNode = XPathQueryBuilder.createQuery("//test/*", JCR_RESOLVER, QUERY_NODE_FACTORY);
assertTrue(queryRootNode.needsSystemTree());
}
+ public void testNeedsSystemTreeForAllNodesByNodeType() throws Exception {
+ QueryRootNode queryRootNode = XPathQueryBuilder.createQuery("//element(*, nt:resource)", JCR_RESOLVER, QUERY_NODE_FACTORY);
+ assertFalse(queryRootNode.needsSystemTree());
+
+ queryRootNode = XPathQueryBuilder.createQuery("//element(*, nt:resource)[@jcr:test = 'foo']", JCR_RESOLVER, QUERY_NODE_FACTORY);
+ assertFalse(queryRootNode.needsSystemTree());
+
+ queryRootNode = XPathQueryBuilder.createQuery("//element(*, nt:nodeType)", JCR_RESOLVER, QUERY_NODE_FACTORY);
+ assertTrue(queryRootNode.needsSystemTree());
+ }
}