jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mreut...@apache.org
Subject svn commit: r154258 - in incubator/jackrabbit/trunk/src: java/org/apache/jackrabbit/core/search/lucene/ java/org/apache/jackrabbit/core/search/sql/ test/org/apache/jackrabbit/test/search/
Date Fri, 18 Feb 2005 11:15:05 GMT
Author: mreutegg
Date: Fri Feb 18 03:15:01 2005
New Revision: 154258

URL: http://svn.apache.org/viewcvs?view=rev&rev=154258
Log:
JIRA issue: JCR-49
jcr:path LIKE '/foo/%' now selects descendants of /foo

Added:
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SQLPathTest.java
  (with props)
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/XPathAxisTest.java
  (with props)
Modified:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/AbstractQueryTest.java
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java?view=diff&r1=154257&r2=154258
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java
Fri Feb 18 03:15:01 2005
@@ -48,6 +48,12 @@
     /** The sub query to filter */
     private final Query subQuery;
 
+    /**
+     * If <code>true</code> this query acts on the descendant-or-self axis.
+     * If <code>false</code> this query acts on the descendant axis.
+     */
+    private final boolean includeSelf;
+
     /** The scorer of the sub query to filter */
     private Scorer subScorer;
 
@@ -58,8 +64,22 @@
      * @param sub the sub query.
      */
     public DescendantSelfAxisQuery(Query context, Query sub) {
+        this(context, sub, true);
+    }
+
+    /**
+     * Creates a new <code>DescendantSelfAxisQuery</code> based on a
+     * <code>context</code> query and filtering the <code>sub</code>
query.
+     * @param context the context for this query.
+     * @param sub the sub query.
+     * @param includeSelf if <code>true</code> this query acts like a
+     * descendant-or-self axis. If <code>false</code> this query acts like
+     * a descendant axis.
+     */
+    public DescendantSelfAxisQuery(Query context, Query sub, boolean includeSelf) {
         this.contextQuery = context;
         this.subQuery = sub;
+        this.includeSelf = includeSelf;
     }
 
     /**
@@ -199,11 +219,16 @@
             calculateSubHits();
             nextDoc = subHits.nextSetBit(nextDoc + 1);
             while (nextDoc > -1) {
-                // check if nextDoc is really valid
-                String uuid = reader.document(nextDoc).get(FieldNames.UUID);
-                if (contextUUIDs.contains(uuid)) {
-                    return true;
+                // check if nextDoc is really valid against the context query
+
+                // check self if necessary
+                if (includeSelf) {
+                    String uuid = reader.document(nextDoc).get(FieldNames.UUID);
+                    if (contextUUIDs.contains(uuid)) {
+                        return true;
+                    }
                 }
+
                 // check if nextDoc is a descendant of one of the context nodes
                 String parentUUID = reader.document(nextDoc).get(FieldNames.PARENT);
                 while (parentUUID != null && !contextUUIDs.contains(parentUUID))
{

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java?view=diff&r1=154257&r2=154258
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
Fri Feb 18 03:15:01 2005
@@ -375,13 +375,14 @@
                 if (predicates.length > 0) {
                     // if we have a predicate attached, the condition acts as
                     // the sub query.
-                    Query subQuery = new DescendantSelfAxisQuery(context, andQuery);
+                    Query subQuery = new DescendantSelfAxisQuery(context, andQuery, false);
                     andQuery = new BooleanQuery();
                     andQuery.add(subQuery, true, false);
                 } else {
                     // @todo this will traverse the whole index, optimize!
                     Query subQuery = new MatchAllQuery(FieldNames.UUID);
-                    andQuery.add(new DescendantSelfAxisQuery(context, subQuery), true, false);
+                    context = new DescendantSelfAxisQuery(context, subQuery);
+                    andQuery.add(new ChildAxisQuery(context), true, false);
                 }
             }
         } else {

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java?view=diff&r1=154257&r2=154258
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
Fri Feb 18 03:15:01 2005
@@ -487,7 +487,9 @@
                     }
                 }
                 // @todo how to specify descendant-or-self?
-                LocationStepQueryNode step = new LocationStepQueryNode(pathNode, qName, false);
+                // if name test is % this means also search descendants
+                boolean descendant = name == null;
+                LocationStepQueryNode step = new LocationStepQueryNode(pathNode, qName, descendant);
                 if (index > 0) {
                     step.setIndex(index);
                 }

Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/AbstractQueryTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/AbstractQueryTest.java?view=diff&r1=154257&r2=154258
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/AbstractQueryTest.java
(original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/AbstractQueryTest.java
Fri Feb 18 03:15:01 2005
@@ -18,10 +18,18 @@
 
 import org.apache.jackrabbit.test.AbstractJCRTest;
 
-import javax.jcr.*;
 import javax.jcr.query.QueryResult;
 import javax.jcr.query.RowIterator;
-import javax.jcr.query.Row;
+import javax.jcr.query.Query;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Node;
+import javax.jcr.Value;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
 
 /**
  * Abstract base class for query test cases.
@@ -86,4 +94,68 @@
         assertEquals("Wrong property count.", properties, count);
     }
 
+    /**
+     * Returns the nodes in <code>it</code> as an array of Nodes.
+     * @param it the NodeIterator.
+     * @return the elements of the iterator as an array of Nodes.
+     */
+    protected Node[] toArray(NodeIterator it) {
+        List nodes = new ArrayList();
+        while (it.hasNext()) {
+            nodes.add(it.nextNode());
+        }
+        return (Node[]) nodes.toArray(new Node[nodes.size()]);
+    }
+
+    /**
+     * Executes the <code>xpath</code> query and checks the results against
+     * the specified <code>nodes</code>.
+     * @param xpath the xpath query.
+     * @param nodes the expected result nodes.
+     */
+    protected void executeXPathQuery(String xpath, Node[] nodes)
+            throws RepositoryException {
+        QueryResult res = superuser.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH).execute();
+        checkResult(res, nodes);
+    }
+
+    /**
+     * Executes the <code>sql</code> query and checks the results against
+     * the specified <code>nodes</code>.
+     * @param sql the sql query.
+     * @param nodes the expected result nodes.
+     */
+    protected void executeSQLQuery(String sql, Node[] nodes)
+            throws RepositoryException {
+        QueryResult res = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL).execute();
+        checkResult(res, nodes);
+    }
+
+    /**
+     * Checks if the result set contains exactly the <code>nodes</code>.
+     * @param result the query result.
+     * @param nodes the expected nodes in the result set.
+     */
+    protected void checkResult(QueryResult result, Node[] nodes)
+            throws RepositoryException {
+        // collect paths
+        Set expectedPaths = new HashSet();
+        for (int i = 0; i < nodes.length; i++) {
+            expectedPaths.add(nodes[i].getPath());
+        }
+        Set resultPaths = new HashSet();
+        for (NodeIterator it = result.getNodes(); it.hasNext();) {
+            resultPaths.add(it.nextNode().getPath());
+        }
+        // check if all expected are in result
+        for (Iterator it = expectedPaths.iterator(); it.hasNext();) {
+            String path = (String) it.next();
+            assertTrue(path + " is not part of the result set", resultPaths.contains(path));
+        }
+        // check result does not contain more than expected
+        for (Iterator it = resultPaths.iterator(); it.hasNext();) {
+            String path = (String) it.next();
+            assertTrue(path + " is not expected to be part of the result set", expectedPaths.contains(path));
+        }
+    }
 }

Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SQLPathTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SQLPathTest.java?view=auto&rev=154258
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SQLPathTest.java
(added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SQLPathTest.java
Fri Feb 18 03:15:01 2005
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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.test.search;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * Tests path predicates in SQL queries.
+ */
+public class SQLPathTest extends AbstractQueryTest {
+
+    private Node n1;
+    private Node n2;
+    private Node n11;
+    private Node n12;
+    private Node n21;
+    private Node n22;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        n1 = testRootNode.addNode("node1");
+        n2 = testRootNode.addNode("node2");
+        n11 = n1.addNode("node11");
+        n12 = n1.addNode("node12");
+        n21 = n2.addNode("node21");
+        n22 = n2.addNode("node22");
+        testRootNode.save();
+    }
+
+    public void testDescendantTestRoot() throws RepositoryException {
+        String sql = getStatement(testRoot + "/%");
+        executeSQLQuery(sql, new Node[]{n1, n11, n12, n2, n21, n22});
+    }
+
+    public void testDescendantSubNode() throws RepositoryException {
+        String sql = getStatement(testRoot + "/node1/%");
+        executeSQLQuery(sql, new Node[]{n11, n12});
+    }
+
+    public void testDescendantLeaf() throws RepositoryException {
+        String sql = getStatement(testRoot + "/node1/node11/%");
+        executeSQLQuery(sql, new Node[0]);
+    }
+
+    public void testDescendantSelfTestRoot() throws RepositoryException {
+        String sql = getStatement(testRoot + "/%");
+        sql += " OR jcr:path = '" + testRoot + "'";
+        executeSQLQuery(sql, new Node[]{testRootNode, n1, n11, n12, n2, n21, n22});
+    }
+
+    //-----------------------------< internal >---------------------------------
+
+    /**
+     * Creates a SQL statement with a path predicate.
+     * @param path the path
+     * @return the SQL statement.
+     */
+    private String getStatement(String path) {
+        return "SELECT * FROM nt:base WHERE jcr:path LIKE '" + path + "'";
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SQLPathTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java?view=diff&r1=154257&r2=154258
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java Fri
Feb 18 03:15:01 2005
@@ -41,6 +41,8 @@
         suite.addTestSuite(SelectClauseTest.class);
         suite.addTestSuite(SQLTest.class);
         suite.addTestSuite(OrderByTest.class);
+        suite.addTestSuite(XPathAxisTest.class);
+        suite.addTestSuite(SQLPathTest.class);
 
         return suite;
     }

Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/XPathAxisTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/XPathAxisTest.java?view=auto&rev=154258
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/XPathAxisTest.java
(added)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/XPathAxisTest.java
Fri Feb 18 03:15:01 2005
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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.test.search;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Node;
+
+/**
+ * Tests the various XPath axis.
+ */
+public class XPathAxisTest extends AbstractQueryTest {
+
+    private Node n1;
+    private Node n2;
+    private Node n11;
+    private Node n12;
+    private Node n21;
+    private Node n22;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        n1 = testRootNode.addNode("node1");
+        n2 = testRootNode.addNode("node2");
+        n11 = n1.addNode("node11");
+        n12 = n1.addNode("node12");
+        n21 = n2.addNode("node21");
+        n22 = n2.addNode("node22");
+        testRootNode.save();
+    }
+
+    public void testChildAxisRoot() throws RepositoryException {
+        String xpath = "/*";
+        executeXPathQuery(xpath, new Node[]{superuser.getRootNode()});
+    }
+
+    public void testChildAxisJCRRoot() throws RepositoryException {
+        String xpath = "/jcr:root/*";
+        Node[] nodes = toArray(superuser.getRootNode().getNodes());
+        executeXPathQuery(xpath, nodes);
+    }
+
+    public void testChildAxisTestRoot() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "/*";
+        executeXPathQuery(xpath, new Node[]{n1, n2});
+    }
+
+    public void testChildAxisTestRootRelative() throws RepositoryException {
+        String xpath = testPath + "/*";
+        executeXPathQuery(xpath, new Node[]{n1, n2});
+    }
+
+    public void testChildAxisLeaf() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "/node1/node11/*";
+        executeXPathQuery(xpath, new Node[0]);
+    }
+
+    public void testChildAxisLeafRelative() throws RepositoryException {
+        String xpath = testPath + "/node1/node11/*";
+        executeXPathQuery(xpath, new Node[0]);
+    }
+
+    public void testDescendantAxisTestRoot() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "//*";
+        executeXPathQuery(xpath, new Node[]{n1, n11, n12, n2, n21, n22});
+    }
+
+    public void testDescendantAxisTestRootRelative() throws RepositoryException {
+        String xpath = testPath + "//*";
+        executeXPathQuery(xpath, new Node[]{n1, n11, n12, n2, n21, n22});
+    }
+
+    public void testDescendantAxisLeaf() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "node1/node11//*";
+        executeXPathQuery(xpath, new Node[0]);
+    }
+
+    public void testDescendantAxisLeafRelative() throws RepositoryException {
+        String xpath = testPath + "node1/node11//*";
+        executeXPathQuery(xpath, new Node[0]);
+    }
+
+    public void testDescendantSelfAxisTestRoot1() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "//node1";
+        executeXPathQuery(xpath, new Node[]{n1});
+    }
+
+    public void testDescendantSelfAxisTestRoot1Relative() throws RepositoryException {
+        String xpath = testPath + "//node1";
+        executeXPathQuery(xpath, new Node[]{n1});
+    }
+
+    public void testDescendantSelfAxisAndChild() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "//node1/*";
+        executeXPathQuery(xpath, new Node[]{n11, n12});
+    }
+
+    public void testDescendantSelfAxisAndChildRelative() throws RepositoryException {
+        String xpath = testPath + "//node1/*";
+        executeXPathQuery(xpath, new Node[]{n11, n12});
+    }
+
+    public void testChildAndDescendantSelfAxis() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "/*//*";
+        executeXPathQuery(xpath, new Node[]{n11, n12, n21, n22});
+    }
+
+    public void testChildAndDescendantSelfAxisRelative() throws RepositoryException {
+        String xpath = testPath + "/*//*";
+        executeXPathQuery(xpath, new Node[]{n11, n12, n21, n22});
+    }
+
+    public void testChildChildAxis() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "/*/*";
+        executeXPathQuery(xpath, new Node[]{n11, n12, n21, n22});
+    }
+
+    public void testChildChildAxisRelative() throws RepositoryException {
+        String xpath = testPath + "/*/*";
+        executeXPathQuery(xpath, new Node[]{n11, n12, n21, n22});
+    }
+
+    public void testChildAndNodeTestAxis() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "/*/node11";
+        executeXPathQuery(xpath, new Node[]{n11});
+    }
+
+    public void testChildAndNodeTestAxisRelative() throws RepositoryException {
+        String xpath = testPath + "/*/node11";
+        executeXPathQuery(xpath, new Node[]{n11});
+    }
+
+    public void testDescendantSelfAxisTestRoot2() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "//node11";
+        executeXPathQuery(xpath, new Node[]{n11});
+    }
+
+    public void testDescendantSelfAxisTestRoot2Relative() throws RepositoryException {
+        String xpath = testPath + "//node11";
+        executeXPathQuery(xpath, new Node[]{n11});
+    }
+
+    public void testDescendantSelfAxisNonDesc() throws RepositoryException {
+        String xpath = "/jcr:root" + testRoot + "/node1//node22";
+        executeXPathQuery(xpath, new Node[0]);
+    }
+
+    public void testDescendantSelfAxisRelativeTestPath() throws RepositoryException {
+        String xpath = testPath;
+        executeXPathQuery(xpath, new Node[]{testRootNode});
+    }
+
+    public void testExactRelative() throws RepositoryException {
+        String xpath = testPath + "/node1";
+        executeXPathQuery(xpath, new Node[]{n1});
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/XPathAxisTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message