jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mreut...@apache.org
Subject svn commit: r744884 - in /jackrabbit/trunk/jackrabbit-spi-commons/src: main/java/org/apache/jackrabbit/spi/commons/query/ main/java/org/apache/jackrabbit/spi/commons/query/sql/ main/java/org/apache/jackrabbit/spi/commons/query/xpath/ test/java/org/apac...
Date Mon, 16 Feb 2009 10:39:23 GMT
Author: mreutegg
Date: Mon Feb 16 10:39:22 2009
New Revision: 744884

URL: http://svn.apache.org/viewvc?rev=744884&view=rev
Log:
JCR-800: Child Axis support in order by clause

Added:
    jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/
    jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/xpath/
    jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathOrderByTest.java
  (with props)
Modified:
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/OrderQueryNode.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/QueryTreeDump.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/QueryFormat.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/QueryFormat.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathQueryBuilder.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/DummyNamespaceResolver.java

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/OrderQueryNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/OrderQueryNode.java?rev=744884&r1=744883&r2=744884&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/OrderQueryNode.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/OrderQueryNode.java
Mon Feb 16 10:39:22 2009
@@ -22,6 +22,9 @@
 import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.commons.name.PathBuilder;
+import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
 
 /**
  * Implements a query node that defines the order of nodes according to the
@@ -59,8 +62,20 @@
      * @param property  the name of the property.
      * @param ascending if <code>true</code> values of this properties are
      *                  ordered ascending; descending if <code>false</code>.
+     * @deprecated use {@link #addOrderSpec(Path , boolean)} instead.
      */
     public void addOrderSpec(Name property, boolean ascending) {
+        addOrderSpec(createPath(property), ascending);
+    }
+
+    /**
+     * Adds an order specification to this query node.
+     *
+     * @param property  the relative path of the property.
+     * @param ascending if <code>true</code> values of this properties are
+     *                  ordered ascending; descending if <code>false</code>.
+     */
+    public void addOrderSpec(Path property, boolean ascending) {
         specs.add(new OrderSpec(property, ascending));
     }
 
@@ -124,9 +139,9 @@
     public static final class OrderSpec {
 
         /**
-         * The name of the property
+         * The relative path to of the property
          */
-        private final Name property;
+        private final Path property;
 
         /**
          * If <code>true</code> this property is orderd ascending
@@ -139,8 +154,20 @@
          * @param property  the name of the property.
          * @param ascending if <code>true</code> the property is ordered
          *                  ascending, otherwise descending.
+         * @deprecated use {@link OrderSpec#OrderSpec(Path, boolean)} instead.
          */
         public OrderSpec(Name property, boolean ascending) {
+            this(createPath(property), ascending);
+        }
+
+        /**
+         * Creates a new <code>OrderSpec</code> for <code>property</code>.
+         *
+         * @param property  the relative path of the property.
+         * @param ascending if <code>true</code> the property is ordered
+         *                  ascending, otherwise descending.
+         */
+        public OrderSpec(Path property, boolean ascending) {
             this.property = property;
             this.ascending = ascending;
         }
@@ -149,8 +176,18 @@
          * Returns the name of the property.
          *
          * @return the name of the property.
+         * @deprecated use {@link #getPropertyPath()} instead.
          */
         public Name getProperty() {
+            return property.getNameElement().getName();
+        }
+
+        /**
+         * Returns the relative path of the property.
+         *
+         * @return the relative path of the property.
+         */
+        public Path getPropertyPath() {
             return property;
         }
 
@@ -199,4 +236,22 @@
         return false;
     }
 
+    //--------------------------------< internal >------------------------------
+
+    /**
+     * Creates a path with a single element out of the given <code>name</code>.
+     *
+     * @param name the name to create the path from.
+     * @return a path with a single element.
+     */
+    private static Path createPath(Name name) {
+        try {
+            PathBuilder builder = new PathBuilder();
+            builder.addLast(name);
+            return builder.getPath();
+        } catch (MalformedPathException e) {
+            // never happens, we just added an element
+            throw new InternalError();
+        }
+    }
 }

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/QueryTreeDump.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/QueryTreeDump.java?rev=744884&r1=744883&r2=744884&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/QueryTreeDump.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/QueryTreeDump.java
Mon Feb 16 10:39:22 2009
@@ -210,16 +210,7 @@
         if (relPath == null) {
             buffer.append(relPath);
         } else {
-            Path.Element[] elements = relPath.getElements();
-            String slash = "";
-            for (int i = 0; i < elements.length; i++) {
-                buffer.append(slash);
-                slash = "/";
-                if (i == elements.length - 1) {
-                    buffer.append("@");
-                }
-                buffer.append(elements[i]);
-            }
+            appendPath(relPath, buffer);
         }
         buffer.append(" Type=").append(QueryConstants.TYPE_NAMES.getName(node.getValueType()));
         if (node.getValueType() == QueryConstants.TYPE_DATE) {
@@ -249,7 +240,8 @@
         OrderQueryNode.OrderSpec[] specs = node.getOrderSpecs();
         for (int i = 0; i < specs.length; i++) {
             buffer.append(PADDING, 0, indent);
-            buffer.append("  ").append(specs[i].getProperty());
+            buffer.append("  ");
+            appendPath(specs[i].getPropertyPath(), buffer);
             buffer.append(" asc=").append(specs[i].isAscending());
             buffer.append("\n");
         }
@@ -301,4 +293,21 @@
         }
         indent -= 2;
     }
+
+    /**
+     * Appends the relative path to the <code>buffer</code> using '/' as the
+     * delimiter for path elements.
+     *
+     * @param relPath a relative path.
+     * @param buffer the buffer where to append the path.
+     */
+    private static void appendPath(Path relPath, StringBuffer buffer) {
+        Path.Element[] elements = relPath.getElements();
+        String slash = "";
+        for (int i = 0; i < elements.length; i++) {
+            buffer.append(slash);
+            slash = "/";
+            buffer.append(elements[i]);
+        }
+    }
 }

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/QueryFormat.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/QueryFormat.java?rev=744884&r1=744883&r2=744884&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/QueryFormat.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/QueryFormat.java
Mon Feb 16 10:39:22 2009
@@ -484,7 +484,12 @@
                 String comma = "";
                 for (int i = 0; i < specs.length; i++) {
                     sb.append(comma).append(" ");
-                    appendName(specs[i].getProperty(), resolver, sb);
+                    Path propPath = specs[i].getPropertyPath();
+                    if (propPath.getLength() > 1) {
+                        exceptions.add(new InvalidQueryException("SQL does not support relative
paths in order by clause"));
+                        return sb;
+                    }
+                    appendName(propPath.getNameElement().getName(), resolver, sb);
                     if (!specs[i].isAscending()) {
                         sb.append(" DESC");
                     }

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/QueryFormat.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/QueryFormat.java?rev=744884&r1=744883&r2=744884&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/QueryFormat.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/QueryFormat.java
Mon Feb 16 10:39:22 2009
@@ -445,9 +445,21 @@
         try {
             for (int i = 0; i < specs.length; i++) {
                 sb.append(comma);
-                Name prop = encode(specs[i].getProperty());
-                sb.append(" @");
-                sb.append(resolver.getJCRName(prop));
+                Path propPath = specs[i].getPropertyPath();
+                Path.Element[] elements = propPath.getElements();
+                sb.append(" ");
+                String slash = "";
+                for (int j = 0; j < elements.length; j++) {
+                    sb.append(slash);
+                    slash = "/";
+                    Path.Element element = elements[j];
+                    Name name = encode(element.getName());
+                    if (j == elements.length - 1) {
+                        // last
+                        sb.append("@");
+                    }
+                    sb.append(resolver.getJCRName(name));
+                }
                 if (!specs[i].isAscending()) {
                     sb.append(" descending");
                 }

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathQueryBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathQueryBuilder.java?rev=744884&r1=744883&r2=744884&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathQueryBuilder.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathQueryBuilder.java
Mon Feb 16 10:39:22 2009
@@ -563,17 +563,32 @@
      * @param node a relation query node.
      */
     private void applyRelativePath(RelationQueryNode node) {
-        if (tmpRelPath != null) {
-            try {
-                Path relPath = tmpRelPath.getPath();
-                for (int i = 0; i < relPath.getLength(); i++) {
-                    node.addPathElement(relPath.getElements()[i]);
-                }
-            } catch (MalformedPathException e) {
-                // should never happen
+        Path relPath = getRelativePath();
+        if (relPath != null) {
+            for (int i = 0; i < relPath.getLength(); i++) {
+                node.addPathElement(relPath.getElements()[i]);
+            }
+        }
+    }
+
+    /**
+     * Returns {@link #tmpRelPath} or <code>null</code> if there is none set.
+     * When this method returns {@link #tmpRelPath} will have been set
+     * <code>null</code>.
+     *
+     * @return {@link #tmpRelPath}.
+     */
+    private Path getRelativePath() {
+        try {
+            if (tmpRelPath != null) {
+                return tmpRelPath.getPath();
             }
+        } catch (MalformedPathException e) {
+            // should never happen
+        } finally {
             tmpRelPath = null;
         }
+        return null;
     }
 
     /**
@@ -1099,8 +1114,14 @@
                 // cut off left parenthesis at end
                 propName = propName.substring(0, propName.length() - 1);
             }
+            PathBuilder builder = new PathBuilder();
             Name name = decode(resolver.getQName(propName));
-            spec = new OrderQueryNode.OrderSpec(name, true);
+            Path relPath = getRelativePath();
+            if (relPath != null) {
+                builder.addAll(relPath.getElements());
+            }
+            builder.addLast(name);
+            spec = new OrderQueryNode.OrderSpec(builder.getPath(), true);
             queryNode.addOrderSpec(spec);
         } catch (NameException e) {
             exceptions.add(new InvalidQueryException("Illegal name: " + child.getValue()));

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/DummyNamespaceResolver.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/DummyNamespaceResolver.java?rev=744884&r1=744883&r2=744884&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/DummyNamespaceResolver.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/conversion/DummyNamespaceResolver.java
Mon Feb 16 10:39:22 2009
@@ -25,7 +25,7 @@
  * maps each valid XML prefix string to the same string as the namespace URI
  * and vice versa.
  */
-class DummyNamespaceResolver implements NamespaceResolver {
+public class DummyNamespaceResolver implements NamespaceResolver {
 
     /**
      * Returns the given prefix.

Added: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathOrderByTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathOrderByTest.java?rev=744884&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathOrderByTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathOrderByTest.java
Mon Feb 16 10:39:22 2009
@@ -0,0 +1,100 @@
+/*
+ * 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.spi.commons.query.xpath;
+
+import java.util.Collections;
+
+import javax.jcr.query.Query;
+
+import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
+import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
+import org.apache.jackrabbit.spi.commons.conversion.DummyNamespaceResolver;
+import org.apache.jackrabbit.spi.commons.query.QueryNodeFactory;
+import org.apache.jackrabbit.spi.commons.query.DefaultQueryNodeFactory;
+import org.apache.jackrabbit.spi.commons.query.QueryRootNode;
+import org.apache.jackrabbit.spi.commons.query.QueryParser;
+import org.apache.jackrabbit.spi.commons.query.OrderQueryNode;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
+
+import junit.framework.TestCase;
+
+/**
+ * <code>XPathOrderByTest</code> performs various tests related to parsing an
+ * XPath statement with order by.
+ */
+public class XPathOrderByTest extends TestCase {
+
+    private static final NameResolver RESOLVER = new DefaultNamePathResolver(
+            new DummyNamespaceResolver());
+
+    private static final QueryNodeFactory FACTORY = new DefaultQueryNodeFactory(Collections.EMPTY_LIST);
+
+    public void testSimpleOrderBy() throws Exception {
+        String stmt = "//* order by @bar";
+        QueryRootNode root = QueryParser.parse(stmt, Query.XPATH, RESOLVER, FACTORY);
+        OrderQueryNode.OrderSpec[] specs = root.getOrderNode().getOrderSpecs();
+        assertEquals(1, specs.length);
+        assertTrue(specs[0].isAscending());
+        checkName(Name.NS_DEFAULT_URI, "bar", specs[0].getProperty());
+        Path propPath = specs[0].getPropertyPath();
+        assertEquals(1, propPath.getLength());
+        checkName(Name.NS_DEFAULT_URI, "bar", propPath.getNameElement().getName());
+    }
+
+    public void testAscending() throws Exception {
+        String stmt = "//* order by @bar ascending";
+        QueryRootNode root = QueryParser.parse(stmt, Query.XPATH, RESOLVER, FACTORY);
+        OrderQueryNode.OrderSpec[] specs = root.getOrderNode().getOrderSpecs();
+        assertEquals(1, specs.length);
+        assertTrue(specs[0].isAscending());
+    }
+
+    public void testDescending() throws Exception {
+        String stmt = "//* order by @bar descending";
+        QueryRootNode root = QueryParser.parse(stmt, Query.XPATH, RESOLVER, FACTORY);
+        OrderQueryNode.OrderSpec[] specs = root.getOrderNode().getOrderSpecs();
+        assertEquals(1, specs.length);
+        assertFalse(specs[0].isAscending());
+    }
+
+    public void testChildAxis() throws Exception {
+        String stmt = "//* order by foo_x0020_bar/@bar";
+        QueryRootNode root = QueryParser.parse(stmt, Query.XPATH, RESOLVER, FACTORY);
+        assertEquals(1, root.getOrderNode().getOrderSpecs().length);
+        OrderQueryNode.OrderSpec[] specs = root.getOrderNode().getOrderSpecs();
+        assertEquals(1, specs.length);
+        assertTrue(specs[0].isAscending());
+        checkName(Name.NS_DEFAULT_URI, "bar", specs[0].getProperty());
+        Path propPath = specs[0].getPropertyPath();
+        Path.Element[] elements = propPath.getElements();
+        assertEquals(2, elements.length);
+        checkName(Name.NS_DEFAULT_URI, "foo bar", elements[0].getName());
+        checkName(Name.NS_DEFAULT_URI, "bar", elements[1].getName());
+    }
+
+    public void testRoundTrip() throws Exception {
+        String stmt = "//* order by foo_x0020_bar/@bar";
+        QueryRootNode root = QueryParser.parse(stmt, Query.XPATH, RESOLVER, FACTORY);
+        assertEquals(stmt, QueryFormat.toString(root, RESOLVER));
+    }
+
+    private void checkName(String uri, String localName, Name name) {
+        assertEquals(uri, name.getNamespaceURI());
+        assertEquals(localName, name.getLocalName());
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/xpath/XPathOrderByTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message