jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mreut...@apache.org
Subject svn commit: r782644 - in /jackrabbit/trunk: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbi...
Date Mon, 08 Jun 2009 14:25:27 GMT
Author: mreutegg
Date: Mon Jun  8 14:25:26 2009
New Revision: 782644

URL: http://svn.apache.org/viewvc?rev=782644&view=rev
Log:
JCR-2076: JSR 283: Joins
- orderings (work in progress)

Added:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractScoreDocComparator.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LengthSortComparator.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LowerCaseSortComparator.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/UpperCaseSortComparator.java   (with props)
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/Order.java   (with props)
Removed:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ComparableBoolean.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.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/QueryObjectModelImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.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/lucene/SharedFieldCache.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractOrderByTest.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/OrderingImpl.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java Mon Jun  8 14:25:26 2009
@@ -24,6 +24,8 @@
 
 import javax.jcr.Value;
 import javax.jcr.RepositoryException;
+import javax.jcr.query.qom.QueryObjectModelFactory;
+
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Map;
@@ -65,12 +67,12 @@
     /**
      * Set<Name>, where Name is a variable name in the query statement.
      */
-    private final Set variableNames = new HashSet();
+    private final Set<Name> variableNames = new HashSet<Name>();
 
     /**
      * Binding of variable name to value. Maps {@link Name} to {@link Value}.
      */
-    private final Map bindValues = new HashMap();
+    private final Map<Name, Value> bindValues = new HashMap<Name, Value>();
 
 
     /**
@@ -150,11 +152,20 @@
      * @return an unmodifieable map, which contains the variable names and their
      *         respective value.
      */
-    protected Map getBindVariableValues() {
+    protected Map<Name, Value> getBindVariableValues() {
         return Collections.unmodifiableMap(bindValues);
     }
 
     /**
+     * @return the query object model factory.
+     * @throws RepositoryException if an error occurs.
+     */
+    protected QueryObjectModelFactory getQOMFactory()
+            throws RepositoryException {
+        return session.getWorkspace().getQueryManager().getQOMFactory();
+    }
+
+    /**
      * Returns <code>true</code> if this query node needs items under
      * /jcr:system to be queried.
      *

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractScoreDocComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractScoreDocComparator.java?rev=782644&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractScoreDocComparator.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractScoreDocComparator.java Mon Jun  8 14:25:26 2009
@@ -0,0 +1,124 @@
+/*
+ * 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.lucene;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.io.IOException;
+
+import org.apache.lucene.search.ScoreDocComparator;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.index.IndexReader;
+
+/**
+ * Abstract base class of {@link ScoreDocComparator} implementations.
+ */
+abstract class AbstractScoreDocComparator implements ScoreDocComparator {
+
+    /**
+     * The index readers.
+     */
+    protected final List<IndexReader> readers = new ArrayList<IndexReader>();
+
+    /**
+     * The document number starts for the {@link #readers}.
+     */
+    protected final int[] starts;
+
+    public AbstractScoreDocComparator(IndexReader reader)
+            throws IOException {
+        getIndexReaders(readers, reader);
+
+        int maxDoc = 0;
+        this.starts = new int[readers.size() + 1];
+
+        for (int i = 0; i < readers.size(); i++) {
+            IndexReader r = readers.get(i);
+            starts[i] = maxDoc;
+            maxDoc += r.maxDoc();
+        }
+        starts[readers.size()] = maxDoc;
+    }
+
+    /**
+     * Compares sort values of <code>i</code> and <code>j</code>. If the
+     * sort values have differing types, then the sort order is defined on
+     * the type itself by calling <code>compareTo()</code> on the respective
+     * type class names.
+     *
+     * @param i first score doc.
+     * @param j second score doc.
+     * @return a negative integer if <code>i</code> should come before
+     *         <code>j</code><br> a positive integer if <code>i</code>
+     *         should come after <code>j</code><br> <code>0</code> if they
+     *         are equal
+     */
+    public int compare(ScoreDoc i, ScoreDoc j) {
+        return Util.compare(sortValue(i), sortValue(j));
+    }
+
+    public int sortType() {
+        return SortField.CUSTOM;
+    }
+
+    /**
+     * Returns the reader index for document <code>n</code>.
+     *
+     * @param n document number.
+     * @return the reader index.
+     */
+    protected int readerIndex(int n) {
+        int lo = 0;
+        int hi = readers.size() - 1;
+
+        while (hi >= lo) {
+            int mid = (lo + hi) >> 1;
+            int midValue = starts[mid];
+            if (n < midValue) {
+                hi = mid - 1;
+            } else if (n > midValue) {
+                lo = mid + 1;
+            } else {
+                while (mid + 1 < readers.size() && starts[mid + 1] == midValue) {
+                    mid++;
+                }
+                return mid;
+            }
+        }
+        return hi;
+    }
+
+    /**
+     * Checks if <code>reader</code> is of type {@link MultiIndexReader} and if
+     * that's the case calls this method recursively for each reader within the
+     * multi index reader; otherwise the reader is simply added to the list.
+     *
+     * @param readers the list of index readers.
+     * @param reader  the reader to check.
+     */
+    private static void getIndexReaders(List<IndexReader> readers,
+                                        IndexReader reader) {
+        if (reader instanceof MultiIndexReader) {
+            for (IndexReader r : ((MultiIndexReader) reader).getIndexReaders()) {
+                getIndexReaders(readers, r);
+            }
+        } else {
+            readers.add(reader);
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractScoreDocComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java Mon Jun  8 14:25:26 2009
@@ -84,6 +84,16 @@
                 } while (next != null && !constraint.evaluate(next, getSelectorNames(), searcher));
                 return next;
             }
+
+            public int getSize() {
+                return -1;
+            }
+
+            public void skip(int n) throws IOException {
+                while (n-- > 0) {
+                    nextScoreNodes();
+                }
+            }
         };
     }
 }

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LengthSortComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LengthSortComparator.java?rev=782644&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LengthSortComparator.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LengthSortComparator.java Mon Jun  8 14:25:26 2009
@@ -0,0 +1,76 @@
+/*
+ * 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.lucene;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.SortComparatorSource;
+import org.apache.lucene.search.ScoreDocComparator;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.index.IndexReader;
+
+/**
+ * <code>LengthSortComparator</code> implements a sort comparator source that
+ * sorts on the length of property values.
+ */
+public class LengthSortComparator implements SortComparatorSource {
+
+    private static final long serialVersionUID = 2513564768671391632L;
+
+    /**
+     * Creates a new comparator.
+     *
+     * @param reader    the current index reader.
+     * @param fieldname the name of the property to sort on. This is the string
+     *                  representation of {@link org.apache.jackrabbit.spi.Name
+     *                  Name}.
+     * @return the score doc comparator.
+     * @throws IOException if an error occurs while reading from the index.
+     */
+    public ScoreDocComparator newComparator(IndexReader reader,
+                                            String fieldname)
+            throws IOException {
+        return new Comparator(reader, fieldname);
+    }
+
+    private final class Comparator extends AbstractScoreDocComparator {
+
+        /**
+         * The term look ups of the index segments.
+         */
+        protected final SharedFieldCache.ValueIndex[] indexes;
+
+        public Comparator(IndexReader reader,
+                          String propertyName) throws IOException {
+            super(reader);
+            this.indexes = new SharedFieldCache.ValueIndex[readers.size()];
+
+            String namedLength = FieldNames.createNamedLength(propertyName, 0);
+            for (int i = 0; i < readers.size(); i++) {
+                IndexReader r = readers.get(i);
+                indexes[i] = SharedFieldCache.INSTANCE.getValueIndex(
+                        r, FieldNames.PROPERTY_LENGTHS,
+                        namedLength, LengthSortComparator.this);
+            }
+        }
+
+        public Comparable sortValue(ScoreDoc i) {
+            int idx = readerIndex(i.doc);
+            return indexes[idx].getValue(i.doc - starts[idx]);
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LengthSortComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LowerCaseSortComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LowerCaseSortComparator.java?rev=782644&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LowerCaseSortComparator.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LowerCaseSortComparator.java Mon Jun  8 14:25:26 2009
@@ -0,0 +1,86 @@
+/*
+ * 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.lucene;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.ScoreDocComparator;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortComparatorSource;
+import org.apache.lucene.index.IndexReader;
+
+/**
+ * <code>LowerCaseSortComparator</code> implements a sort comparator that
+ * compares the lower-cased string values of a base sort comparator.
+ */
+public class LowerCaseSortComparator implements SortComparatorSource {
+
+    private static final long serialVersionUID = 5396206509020979445L;
+
+    /**
+     * The base sort comparator.
+     */
+    private final SortComparatorSource base;
+
+    /**
+     * Creates a new lower case sort comparator.
+     *
+     * @param base the base sort comparator source.
+     */
+    public LowerCaseSortComparator(SortComparatorSource base) {
+        this.base = base;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ScoreDocComparator newComparator(IndexReader reader,
+                                            String fieldname)
+            throws IOException {
+        return new Comparator(base.newComparator(reader, fieldname));
+    }
+
+    private static final class Comparator implements ScoreDocComparator {
+
+        private ScoreDocComparator base;
+
+        private Comparator(ScoreDocComparator base) {
+            this.base = base;
+        }
+
+        /**
+         * @see Util#compare(Comparable, Comparable)
+         */
+        public int compare(ScoreDoc i, ScoreDoc j) {
+            return Util.compare(sortValue(i), sortValue(j));
+        }
+
+        public Comparable sortValue(ScoreDoc i) {
+            Comparable c = base.sortValue(i);
+            if (c != null) {
+                return c.toString().toLowerCase();
+            } else {
+                return null;
+            }
+        }
+
+        public int sortType() {
+            return SortField.CUSTOM;
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LowerCaseSortComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java Mon Jun  8 14:25:26 2009
@@ -23,8 +23,8 @@
 import org.apache.jackrabbit.core.ItemManager;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.security.AccessManager;
-import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl;
 
 /**
  * <code>MultiColumnQueryResult</code> implements a query result that executes
@@ -37,6 +37,11 @@
      */
     private final MultiColumnQuery query;
 
+    /**
+     * The order specifier for each of the order properties.
+     */
+    protected final OrderingImpl[] orderings;
+
     public MultiColumnQueryResult(SearchIndex index,
                                   ItemManager itemMgr,
                                   SessionImpl session,
@@ -45,14 +50,14 @@
                                   MultiColumnQuery query,
                                   SpellSuggestion spellSuggestion,
                                   ColumnImpl[] columns,
-                                  Path[] orderProps,
-                                  boolean[] orderSpecs,
+                                  OrderingImpl[] orderings,
                                   boolean documentOrder,
                                   long offset,
                                   long limit) throws RepositoryException {
         super(index, itemMgr, session, accessMgr, queryImpl, spellSuggestion,
-                columns, orderProps, orderSpecs, documentOrder, offset, limit);
+                columns, documentOrder, offset, limit);
         this.query = query;
+        this.orderings = orderings;
         // if document order is requested get all results right away
         getResults(docOrder ? Integer.MAX_VALUE : index.getResultFetchSize());
     }
@@ -62,8 +67,7 @@
      */
     protected MultiColumnQueryHits executeQuery(long resultFetchHint)
             throws IOException {
-        return index.executeQuery(session, query, orderProps,
-                orderSpecs, resultFetchHint);
+        return index.executeQuery(session, query, orderings, resultFetchHint);
     }
 
     /**

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=782644&r1=782643&r2=782644&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 Jun  8 14:25:26 2009
@@ -133,7 +133,8 @@
                 session, session.getAccessManager(),
                 this, query, new SpellSuggestion(index.getSpellChecker(), root),
                 getColumns(), orderProperties, ascSpecs,
-                getRespectDocumentOrder(), offset, limit);
+                orderProperties.length == 0 && getRespectDocumentOrder(),
+                offset, limit);
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java Mon Jun  8 14:25:26 2009
@@ -20,11 +20,8 @@
 import java.util.ArrayList;
 
 import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.nodetype.PropertyDefinition;
 import javax.jcr.query.QueryResult;
-import javax.jcr.query.qom.PropertyValue;
-import javax.jcr.query.qom.QueryObjectModelConstants;
 import javax.jcr.query.qom.QueryObjectModelFactory;
 
 import org.apache.jackrabbit.core.ItemManager;
@@ -35,14 +32,12 @@
 import org.apache.jackrabbit.core.query.PropertyTypeRegistry;
 import org.apache.jackrabbit.core.query.lucene.constraint.Constraint;
 import org.apache.jackrabbit.core.query.lucene.constraint.ConstraintBuilder;
-import org.apache.jackrabbit.spi.Path;
-import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.BindVariableValueImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.DefaultTraversingQOMTreeVisitor;
-import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelTree;
 import org.apache.jackrabbit.spi.commons.query.qom.SelectorImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl;
 
 /**
  * <code>QueryObjectModelImpl</code>...
@@ -118,7 +113,7 @@
         // expand columns without name
         for (ColumnImpl column : qomTree.getColumns()) {
             if (column.getColumnName() == null) {
-                QueryObjectModelFactory qomFactory = session.getWorkspace().getQueryManager().getQOMFactory();
+                QueryObjectModelFactory qomFactory = getQOMFactory();
                 NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
                 SelectorImpl selector = qomTree.getSelector(column.getSelectorQName());
                 NodeTypeImpl nt = ntMgr.getNodeType(selector.getNodeTypeQName());
@@ -135,27 +130,12 @@
             }
         }
         OrderingImpl[] orderings = qomTree.getOrderings();
-        // TODO: there are many kinds of DynamicOperand that can be ordered by
-        Path[] orderProps = new Path[orderings.length];
-        boolean[] orderSpecs = new boolean[orderings.length];
-        for (int i = 0; i < orderings.length; i++) {
-            orderSpecs[i] = 
-                QueryObjectModelConstants.JCR_ORDER_ASCENDING.equals(
-                        orderings[i].getOrder());
-            if (orderings[i].getOperand() instanceof PropertyValue) {
-                PropertyValue pv = (PropertyValue) orderings[i].getOperand();
-                orderProps[i] = PathFactoryImpl.getInstance().create(pv.getPropertyName());
-            } else {
-                throw new UnsupportedRepositoryOperationException("order by with" +
-                        orderings[i].getOperand() + " not yet implemented");
-            }
-        }
         return new MultiColumnQueryResult(index, itemMgr,
                 session, session.getAccessManager(),
                 // TODO: spell suggestion missing
                 this, query, null, columns.toArray(new ColumnImpl[columns.size()]),
-                orderProps, orderSpecs,
-                getRespectDocumentOrder(), offset, limit);
+                orderings, orderings.length == 0 && getRespectDocumentOrder(),
+                offset, limit);
     }
 
     //--------------------------< internal >------------------------------------

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java Mon Jun  8 14:25:26 2009
@@ -20,7 +20,6 @@
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.security.AccessManager;
 import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -83,16 +82,6 @@
     protected final Map<String, ColumnImpl> columns = new LinkedHashMap<String, ColumnImpl>();
 
     /**
-     * The relative paths of properties to use for ordering the result set.
-     */
-    protected final Path[] orderProps;
-
-    /**
-     * The order specifier for each of the order properties.
-     */
-    protected final boolean[] orderSpecs;
-
-    /**
      * The result nodes including their score. This list is populated on a lazy
      * basis while a client iterates through the results.
      * <p/>
@@ -154,9 +143,6 @@
      * @param spellSuggestion the spell suggestion or <code>null</code> if none
      *                        is available.
      * @param columns         the select properties of the query.
-     * @param orderProps      the relative paths of the order properties.
-     * @param orderSpecs      the order specs, one for each order property
-     *                        name.
      * @param documentOrder   if <code>true</code> the result is returned in
      *                        document order.
      * @param limit           the maximum result size
@@ -173,8 +159,6 @@
                            AbstractQueryImpl queryImpl,
                            SpellSuggestion spellSuggestion,
                            ColumnImpl[] columns,
-                           Path[] orderProps,
-                           boolean[] orderSpecs,
                            boolean documentOrder,
                            long offset,
                            long limit) throws RepositoryException {
@@ -184,9 +168,7 @@
         this.accessMgr = accessMgr;
         this.queryImpl = queryImpl;
         this.spellSuggestion = spellSuggestion;
-        this.orderProps = orderProps;
-        this.orderSpecs = orderSpecs;
-        this.docOrder = orderProps.length == 0 && documentOrder;
+        this.docOrder = documentOrder;
         this.offset = offset;
         this.limit = limit;
         for (ColumnImpl column : columns) {
@@ -196,7 +178,6 @@
                 throw new IllegalArgumentException(msg);
             }
             this.columns.put(cn, column);
-
         }
     }
 

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=782644&r1=782643&r2=782644&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 Jun  8 14:25:26 2009
@@ -45,6 +45,17 @@
 import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
 import org.apache.jackrabbit.spi.commons.query.DefaultQueryNodeFactory;
 import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelTree;
+import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.QOMTreeVisitor;
+import org.apache.jackrabbit.spi.commons.query.qom.DefaultTraversingQOMTreeVisitor;
+import org.apache.jackrabbit.spi.commons.query.qom.LengthImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.LowerCaseImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.UpperCaseImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.FullTextSearchScoreImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.NodeLocalNameImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.NodeNameImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.PropertyValueImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.DynamicOperandImpl;
 import org.apache.jackrabbit.uuid.UUID;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -542,7 +553,7 @@
         if (!index.getIndexFormatVersion().equals(getIndexFormatVersion())) {
             log.warn("Using Version {} for reading. Please re-index version " +
                     "storage for optimal performance.",
-                    new Integer(getIndexFormatVersion().getVersion()));
+                    getIndexFormatVersion().getVersion());
         }
     }
 
@@ -773,23 +784,19 @@
      *
      * @param session         the session that executes the query.
      * @param query           the query.
-     * @param orderProps      name of the properties for sort order.
-     * @param orderSpecs      the order specs for the sort order properties.
-     *                        <code>true</code> indicates ascending order,
-     *                        <code>false</code> indicates descending.
+     * @param orderings       the order specs for the sort order.
      * @param resultFetchHint a hint on how many results should be fetched.
      * @return the query hits.
      * @throws IOException if an error occurs while searching the index.
      */
     public MultiColumnQueryHits executeQuery(SessionImpl session,
                                              MultiColumnQuery query,
-                                             Path[] orderProps,
-                                             boolean[] orderSpecs,
+                                             OrderingImpl[] orderings,
                                              long resultFetchHint)
             throws IOException {
         checkOpen();
 
-        Sort sort = new Sort(createSortFields(orderProps, orderSpecs));
+        Sort sort = new Sort(createSortFields(orderings));
 
         final IndexReader reader = getIndexReader();
         JackrabbitIndexSearcher searcher = new JackrabbitIndexSearcher(
@@ -991,6 +998,77 @@
     }
 
     /**
+     * Creates sort fields for the ordering specifications.
+     *
+     * @param orderings the ordering specifications.
+     * @return the sort fields.
+     */
+    protected SortField[] createSortFields(OrderingImpl[] orderings) {
+        List<SortField> sortFields = new ArrayList<SortField>();
+        for (final OrderingImpl ordering : orderings) {
+            QOMTreeVisitor visitor = new DefaultTraversingQOMTreeVisitor() {
+
+                public Object visit(LengthImpl node, Object data) throws Exception {
+                    PropertyValueImpl propValue = (PropertyValueImpl) node.getPropertyValue();
+                    return new SortField(propValue.getPropertyQName().toString(),
+                            new LengthSortComparator(),
+                            !ordering.isAscending());
+                }
+
+                public Object visit(LowerCaseImpl node, Object data)
+                        throws Exception {
+                    SortField sf = (SortField) super.visit(node, data);
+                    return new SortField(sf.getField(),
+                            new LowerCaseSortComparator(sf.getFactory()),
+                            sf.getReverse());
+                }
+
+                public Object visit(UpperCaseImpl node, Object data)
+                        throws Exception {
+                    SortField sf = (SortField) super.visit(node, data);
+                    return new SortField(sf.getField(),
+                            new UpperCaseSortComparator(sf.getFactory()),
+                            sf.getReverse());
+                }
+
+                public Object visit(FullTextSearchScoreImpl node, Object data)
+                        throws Exception {
+                    // TODO: selector ignored
+                    return new SortField(null, SortField.SCORE,
+                            ordering.isAscending());
+                }
+
+                public Object visit(NodeLocalNameImpl node, Object data) throws Exception {
+                    return new SortField(FieldNames.LOCAL_NAME,
+                           SortField.STRING, !ordering.isAscending());
+                }
+
+                public Object visit(NodeNameImpl node, Object data) throws Exception {
+                    return new SortField(FieldNames.LABEL,
+                           SortField.STRING, !ordering.isAscending());
+                }
+
+                public Object visit(PropertyValueImpl node, Object data)
+                        throws Exception {
+                    return new SortField(node.getPropertyQName().toString(),
+                            scs, !ordering.isAscending());
+                }
+
+                public Object visit(OrderingImpl node, Object data)
+                        throws Exception {
+                    return ((DynamicOperandImpl) node.getOperand()).accept(this, data);
+                }
+            };
+            try {
+                sortFields.add((SortField) ordering.accept(visitor, null));
+            } catch (Exception e) {
+                // TODO
+            }
+        }
+        return sortFields.toArray(new SortField[sortFields.size()]);
+    }
+
+    /**
      * Creates a lucene <code>Document</code> for a node state using the
      * namespace mappings <code>nsMappings</code>.
      *
@@ -1234,44 +1312,36 @@
             }
             try {
                 ItemStateManager ism = getContext().getItemStateManager();
-                for (int i = 0; i < aggregateRules.length; i++) {
+                for (AggregateRule aggregateRule : aggregateRules) {
                     boolean ruleMatched = false;
                     // node includes
-                    NodeState[] aggregates = aggregateRules[i].getAggregatedNodeStates(state);
+                    NodeState[] aggregates = aggregateRule.getAggregatedNodeStates(state);
                     if (aggregates != null) {
                         ruleMatched = true;
-                        for (int j = 0; j < aggregates.length; j++) {
-                            Document aDoc = createDocument(aggregates[j],
-                                    getNamespaceMappings(),
-                                    index.getIndexFormatVersion());
+                        for (NodeState aggregate : aggregates) {
+                            Document aDoc = createDocument(aggregate, getNamespaceMappings(), index.getIndexFormatVersion());
                             // transfer fields to doc if there are any
                             Fieldable[] fulltextFields = aDoc.getFieldables(FieldNames.FULLTEXT);
                             if (fulltextFields != null) {
-                                for (int k = 0; k < fulltextFields.length; k++) {
-                                    doc.add(fulltextFields[k]);
+                                for (Fieldable fulltextField : fulltextFields) {
+                                    doc.add(fulltextField);
                                 }
-                                doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID,
-                                        aggregates[j].getNodeId().getUUID().toString(),
-                                        Field.Store.NO,
-                                        Field.Index.NOT_ANALYZED_NO_NORMS));
+                                doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID, aggregate.getNodeId().getUUID().toString(), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
                             }
                         }
                     }
                     // property includes
-                    PropertyState[] propStates = aggregateRules[i].getAggregatedPropertyStates(state);
+                    PropertyState[] propStates = aggregateRule.getAggregatedPropertyStates(state);
                     if (propStates != null) {
                         ruleMatched = true;
-                        for (int j = 0; j < propStates.length; j++) {
-                            PropertyState propState = propStates[j];
-                            String namePrefix = FieldNames.createNamedValue(
-                                    getNamespaceMappings().translateName(propState.getName()), "");
+                        for (PropertyState propState : propStates) {
+                            String namePrefix = FieldNames.createNamedValue(getNamespaceMappings().translateName(propState.getName()), "");
                             NodeState parent = (NodeState) ism.getItemState(propState.getParentId());
                             Document aDoc = createDocument(parent, getNamespaceMappings(), getIndex().getIndexFormatVersion());
                             // find the right fields to transfer
                             Fieldable[] fields = aDoc.getFieldables(FieldNames.PROPERTIES);
                             Token t = new Token();
-                            for (int k = 0; k < fields.length; k++) {
-                                Fieldable field = fields[k];
+                            for (Fieldable field : fields) {
                                 // assume properties fields use SingleTokenStream
                                 t = field.tokenStreamValue().next(t);
                                 String value = new String(t.termBuffer(), 0, t.termLength());
@@ -1284,10 +1354,7 @@
                                     value = FieldNames.createNamedValue(path, value);
                                     t.setTermBuffer(value);
                                     doc.add(new Field(field.name(), new SingletonTokenStream(t)));
-                                    doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID,
-                                            parent.getNodeId().getUUID().toString(),
-                                            Field.Store.NO,
-                                            Field.Index.NOT_ANALYZED_NO_NORMS));
+                                    doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID, parent.getNodeId().getUUID().toString(), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
                                 }
                             }
                         }
@@ -1355,8 +1422,8 @@
                 return;
             }
             try {
-                for (int i = 0; i < aggregateRules.length; i++) {
-                    NodeState root = aggregateRules[i].getAggregateRoot(state);
+                for (AggregateRule aggregateRule : aggregateRules) {
+                    NodeState root = aggregateRule.getAggregateRoot(state);
                     if (root != null) {
                         map.put(root.getNodeId().getUUID(), root);
                     }
@@ -1477,8 +1544,8 @@
          * {@inheritDoc}
          */
         public void release() throws IOException {
-            for (int i = 0; i < subReaders.length; i++) {
-                subReaders[i].release();
+            for (CachingMultiIndexReader subReader : subReaders) {
+                subReader.release();
             }
         }
 
@@ -1522,8 +1589,8 @@
 
         public int hashCode() {
             int hash = 0;
-            for (int i = 0; i < subReaders.length; i++) {
-                hash = 31 * hash + subReaders[i].hashCode();
+            for (CachingMultiIndexReader subReader : subReaders) {
+                hash = 31 * hash + subReader.hashCode();
             }
             return hash;
         }
@@ -1532,8 +1599,7 @@
          * {@inheritDoc}
          */
         public ForeignSegmentDocId createDocId(UUID uuid) throws IOException {
-            for (int i = 0; i < subReaders.length; i++) {
-                CachingMultiIndexReader subReader = subReaders[i];
+            for (CachingMultiIndexReader subReader : subReaders) {
                 ForeignSegmentDocId doc = subReader.createDocId(uuid);
                 if (doc != null) {
                     return doc;

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java Mon Jun  8 14:25:26 2009
@@ -21,7 +21,7 @@
 import org.apache.lucene.index.TermEnum;
 import org.apache.lucene.index.TermPositions;
 import org.apache.lucene.index.TermDocs;
-import org.apache.lucene.search.SortComparator;
+import org.apache.lucene.search.SortComparatorSource;
 
 import java.io.IOException;
 import java.util.HashMap;
@@ -58,7 +58,7 @@
         /**
          * Values (Comparable) map indexed by document id.
          */
-        public final Map valuesMap;
+        public final Map<Integer, Comparable> valuesMap;
 
         /**
          * Boolean indicating whether the {@link #valuesMap} impl has to be used
@@ -86,17 +86,17 @@
 
         public Comparable getValue(int i) {
             if (sparse) {
-                return valuesMap == null ? null : (Comparable) valuesMap.get(new Integer(i));
+                return valuesMap == null ? null : valuesMap.get(i);
             } else {
                 return values[i];
             }
         }
 
-        private Map getValuesMap(Comparable[] values, int setValues) {
-            Map map = new HashMap(setValues);
+        private Map<Integer, Comparable> getValuesMap(Comparable[] values, int setValues) {
+            Map<Integer, Comparable> map = new HashMap<Integer, Comparable>(setValues);
             for (int i = 0; i < values.length && setValues > 0; i++) {
                 if (values[i] != null) {
-                    map.put(new Integer(i), values[i]);
+                    map.put(i, values[i]);
                     setValues--;
                 }
             }
@@ -121,7 +121,7 @@
     /**
      * The internal cache. Maps Entry to array of interpreted term values.
      */
-    private final Map cache = new WeakHashMap();
+    private final Map<IndexReader, Map<Key, ValueIndex>> cache = new WeakHashMap<IndexReader, Map<Key, ValueIndex>>();
 
     /**
      * Private constructor.
@@ -147,7 +147,7 @@
     public ValueIndex getValueIndex(IndexReader reader,
                                     String field,
                                     String prefix,
-                                    SortComparator comparator)
+                                    SortComparatorSource comparator)
             throws IOException {
 
         if (reader instanceof ReadOnlyIndexReader) {
@@ -225,27 +225,27 @@
      * See if a <code>ValueIndex</code> object is in the cache.
      */
     ValueIndex lookup(IndexReader reader, String field,
-                                  String prefix, SortComparator comparer) {
+                      String prefix, SortComparatorSource comparer) {
         Key key = new Key(field, prefix, comparer);
         synchronized (this) {
-            HashMap readerCache = (HashMap) cache.get(reader);
+            Map<Key, ValueIndex> readerCache = cache.get(reader);
             if (readerCache == null) {
                 return null;
             }
-            return (ValueIndex) readerCache.get(key);
+            return readerCache.get(key);
         }
     }
 
     /**
      * Put a <code>ValueIndex</code> <code>value</code> to cache.
      */
-    Object store(IndexReader reader, String field, String prefix,
-                 SortComparator comparer, ValueIndex value) {
+    ValueIndex store(IndexReader reader, String field, String prefix,
+                 SortComparatorSource comparer, ValueIndex value) {
         Key key = new Key(field, prefix, comparer);
         synchronized (this) {
-            HashMap readerCache = (HashMap) cache.get(reader);
+            Map<Key, ValueIndex> readerCache = cache.get(reader);
             if (readerCache == null) {
-                readerCache = new HashMap();
+                readerCache = new HashMap<Key, ValueIndex>();
                 cache.put(reader, readerCache);
             }
             return readerCache.put(key, value);
@@ -263,13 +263,13 @@
     private Comparable getValue(String value, int type) {
         switch (type) {
             case PropertyType.BOOLEAN:
-                return ComparableBoolean.valueOf(Boolean.valueOf(value).booleanValue());
+                return Boolean.valueOf(value);
             case PropertyType.DATE:
-                return new Long(DateField.stringToTime(value));
+                return DateField.stringToTime(value);
             case PropertyType.LONG:
-                return new Long(LongField.stringToLong(value));
+                return LongField.stringToLong(value);
             case PropertyType.DOUBLE:
-                return new Double(DoubleField.stringToDouble(value));
+                return DoubleField.stringToDouble(value);
             case PropertyType.DECIMAL:
                 return DecimalField.stringToDecimal(value);
             default:
@@ -285,12 +285,12 @@
 
         private final String field;
         private final String prefix;
-        private final SortComparator comparator;
+        private final SortComparatorSource comparator;
 
         /**
          * Creates <code>Key</code> for ValueIndex lookup.
          */
-        Key(String field, String prefix, SortComparator comparator) {
+        Key(String field, String prefix, SortComparatorSource comparator) {
             this.field = field.intern();
             this.prefix = prefix.intern();
             this.comparator = comparator;

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java Mon Jun  8 14:25:26 2009
@@ -17,14 +17,11 @@
 package org.apache.jackrabbit.core.query.lucene;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.ScoreDocComparator;
 import org.apache.lucene.search.SortComparator;
-import org.apache.lucene.search.SortField;
 import org.apache.lucene.document.Document;
 import org.apache.jackrabbit.core.state.ItemStateManager;
 import org.apache.jackrabbit.core.state.PropertyState;
@@ -45,6 +42,8 @@
  */
 public class SharedFieldSortComparator extends SortComparator {
 
+    private static final long serialVersionUID = 2609351820466200052L;
+
     /**
      * The name of the shared field in the lucene index.
      */
@@ -124,104 +123,6 @@
     }
 
     /**
-     * Checks if <code>reader</code> is of type {@link MultiIndexReader} and if
-     * that's the case calls this method recursively for each reader within the
-     * multi index reader; otherwise the reader is simply added to the list.
-     *
-     * @param readers the list of index readers.
-     * @param reader  the reader to check.
-     */
-    private static void getIndexReaders(List readers, IndexReader reader) {
-        if (reader instanceof MultiIndexReader) {
-            IndexReader[] r = ((MultiIndexReader) reader).getIndexReaders();
-            for (int i = 0; i < r.length; i++) {
-                getIndexReaders(readers, r[i]);
-            }
-        } else {
-            readers.add(reader);
-        }
-    }
-
-    /**
-     * Abstract base class of {@link ScoreDocComparator} implementations.
-     */
-    abstract class AbstractScoreDocComparator implements ScoreDocComparator {
-
-        /**
-         * The index readers.
-         */
-        protected final List readers = new ArrayList();
-
-        /**
-         * The document number starts for the {@link #readers}.
-         */
-        protected final int[] starts;
-
-        public AbstractScoreDocComparator(IndexReader reader)
-                throws IOException {
-            getIndexReaders(readers, reader);
-
-            int maxDoc = 0;
-            this.starts = new int[readers.size() + 1];
-
-            for (int i = 0; i < readers.size(); i++) {
-                IndexReader r = (IndexReader) readers.get(i);
-                starts[i] = maxDoc;
-                maxDoc += r.maxDoc();
-            }
-            starts[readers.size()] = maxDoc;
-        }
-
-        /**
-         * Compares sort values of <code>i</code> and <code>j</code>. If the
-         * sort values have differing types, then the sort order is defined on
-         * the type itself by calling <code>compareTo()</code> on the respective
-         * type class names.
-         *
-         * @param i first score doc.
-         * @param j second score doc.
-         * @return a negative integer if <code>i</code> should come before
-         *         <code>j</code><br> a positive integer if <code>i</code>
-         *         should come after <code>j</code><br> <code>0</code> if they
-         *         are equal
-         */
-        public int compare(ScoreDoc i, ScoreDoc j) {
-            return Util.compare(sortValue(i), sortValue(j));
-        }
-
-        public int sortType() {
-            return SortField.CUSTOM;
-        }
-
-        /**
-         * Returns the reader index for document <code>n</code>.
-         *
-         * @param n document number.
-         * @return the reader index.
-         */
-        protected int readerIndex(int n) {
-            int lo = 0;
-            int hi = readers.size() - 1;
-
-            while (hi >= lo) {
-                int mid = (lo + hi) >> 1;
-                int midValue = starts[mid];
-                if (n < midValue) {
-                    hi = mid - 1;
-                } else if (n > midValue) {
-                    lo = mid + 1;
-                } else {
-                    while (mid + 1 < readers.size() && starts[mid + 1] == midValue) {
-                        mid++;
-                    }
-                    return mid;
-                }
-            }
-            return hi;
-        }
-    }
-
-    /**
      * A score doc comparator that works for order by clauses with properties
      * directly on the result nodes.
      */
@@ -240,7 +141,7 @@
 
             String namedValue = FieldNames.createNamedValue(propertyName, "");
             for (int i = 0; i < readers.size(); i++) {
-                IndexReader r = (IndexReader) readers.get(i);
+                IndexReader r = readers.get(i);
                 indexes[i] = SharedFieldCache.INSTANCE.getValueIndex(r, field,
                         namedValue, SharedFieldSortComparator.this);
             }
@@ -283,7 +184,7 @@
         public Comparable sortValue(ScoreDoc i) {
             try {
                 int idx = readerIndex(i.doc);
-                IndexReader reader = (IndexReader) readers.get(idx);
+                IndexReader reader = readers.get(idx);
                 Document doc = reader.document(i.doc - starts[idx], FieldSelectors.UUID);
                 String uuid = doc.get(FieldNames.UUID);
                 Path path = hmgr.getPath(new NodeId(UUID.fromString(uuid)));
@@ -330,8 +231,8 @@
          * {@inheritDoc}
          */
         public Comparable sortValue(ScoreDoc i) {
-            for (int j = 0; j < comparators.length; j++) {
-                Comparable c = comparators[j].sortValue(i);
+            for (ScoreDocComparator comparator : comparators) {
+                Comparable c = comparator.sortValue(i);
                 if (c != null) {
                     return c;
                 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java Mon Jun  8 14:25:26 2009
@@ -23,8 +23,8 @@
 import org.apache.jackrabbit.core.ItemManager;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.security.AccessManager;
-import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl;
+import org.apache.jackrabbit.spi.Path;
 import org.apache.lucene.search.Query;
 
 /**
@@ -38,6 +38,16 @@
      */
     private final Query query;
 
+    /**
+     * The relative paths of properties to use for ordering the result set.
+     */
+    protected final Path[] orderProps;
+
+    /**
+     * The order specifier for each of the order properties.
+     */
+    protected final boolean[] orderSpecs;
+
     public SingleColumnQueryResult(SearchIndex index,
                                    ItemManager itemMgr,
                                    SessionImpl session,
@@ -52,8 +62,10 @@
                                    long offset,
                                    long limit) throws RepositoryException {
         super(index, itemMgr, session, accessMgr, queryImpl, spellSuggestion,
-                columns, orderProps, orderSpecs, documentOrder, offset, limit);
+                columns, documentOrder, offset, limit);
         this.query = query;
+        this.orderProps = orderProps;
+        this.orderSpecs = orderSpecs;
         // if document order is requested get all results right away
         getResults(docOrder ? Integer.MAX_VALUE : index.getResultFetchSize());
     }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java Mon Jun  8 14:25:26 2009
@@ -80,7 +80,7 @@
     /**
      * The score nodes.
      */
-    private final List scoreNodes = new ArrayList();
+    private final List<ScoreNode> scoreNodes = new ArrayList<ScoreNode>();
 
     /**
      * The total number of hits.
@@ -136,7 +136,7 @@
             this.numHits = Math.max(this.numHits, hitIndex * 2);
             getHits();
         }
-        return (ScoreNode) scoreNodes.get(hitIndex);
+        return scoreNodes.get(hitIndex);
     }
 
     /**
@@ -161,7 +161,7 @@
             NodeId id = new NodeId(UUID.fromString(uuid));
             scoreNodes.add(new ScoreNode(id, docs[i].score, docs[i].doc));
         }
-        log.debug("getHits() {}/{}", new Integer(scoreNodes.size()), new Integer(numHits));
+        log.debug("getHits() {}/{}", scoreNodes.size(), numHits);
         // double hits for next round
         numHits *= 2;
     }

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/UpperCaseSortComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/UpperCaseSortComparator.java?rev=782644&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/UpperCaseSortComparator.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/UpperCaseSortComparator.java Mon Jun  8 14:25:26 2009
@@ -0,0 +1,86 @@
+/*
+ * 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.lucene;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.ScoreDocComparator;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortComparatorSource;
+import org.apache.lucene.index.IndexReader;
+
+/**
+ * <code>UpperCaseSortComparator</code> implements a sort comparator that
+ * compares the upper-cased string values of a base sort comparator.
+ */
+public class UpperCaseSortComparator implements SortComparatorSource {
+
+    private static final long serialVersionUID = 2562371983498948119L;
+    
+    /**
+     * The base sort comparator.
+     */
+    private final SortComparatorSource base;
+
+    /**
+     * Creates a new upper case sort comparator.
+     *
+     * @param base the base sort comparator source.
+     */
+    public UpperCaseSortComparator(SortComparatorSource base) {
+        this.base = base;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ScoreDocComparator newComparator(IndexReader reader,
+                                            String fieldname)
+            throws IOException {
+        return new Comparator(base.newComparator(reader, fieldname));
+    }
+
+    private static final class Comparator implements ScoreDocComparator {
+
+        private ScoreDocComparator base;
+
+        private Comparator(ScoreDocComparator base) {
+            this.base = base;
+        }
+
+        /**
+         * @see Util#compare(Comparable, Comparable)
+         */
+        public int compare(ScoreDoc i, ScoreDoc j) {
+            return Util.compare(sortValue(i), sortValue(j));
+        }
+
+        public Comparable sortValue(ScoreDoc i) {
+            Comparable c = base.sortValue(i);
+            if (c != null) {
+                return c.toString().toUpperCase();
+            } else {
+                return null;
+            }
+        }
+
+        public int sortType() {
+            return SortField.CUSTOM;
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/UpperCaseSortComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java Mon Jun  8 14:25:26 2009
@@ -25,7 +25,6 @@
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
-import java.util.Iterator;
 import java.util.regex.Pattern;
 import java.io.IOException;
 
@@ -51,8 +50,8 @@
      * @param old the document to dispose.
      */
     public static void disposeDocument(Document old) {
-        for (Iterator it = old.getFields().iterator(); it.hasNext(); ) {
-            Fieldable f = (Fieldable) it.next();
+        for (Object o : old.getFields()) {
+            Fieldable f = (Fieldable) o;
             try {
                 if (f.readerValue() != null) {
                     f.readerValue().close();
@@ -75,8 +74,8 @@
      *         otherwise.
      */
     public static boolean isDocumentReady(Document doc) {
-        for (Iterator it = doc.getFields().iterator(); it.hasNext(); ) {
-            Fieldable f = (Fieldable) it.next();
+        for (Object o : doc.getFields()) {
+            Fieldable f = (Fieldable) o;
             if (f instanceof LazyTextExtractorField) {
                 LazyTextExtractorField field = (LazyTextExtractorField) f;
                 if (!field.isExtractorFinished()) {
@@ -145,13 +144,13 @@
             case PropertyType.BINARY:
                 return null;
             case PropertyType.BOOLEAN:
-                return ComparableBoolean.valueOf(value.getBoolean());
+                return value.getBoolean();
             case PropertyType.DATE:
-                return new Long(value.getDate().getTimeInMillis());
+                return value.getDate().getTimeInMillis();
             case PropertyType.DOUBLE:
-                return new Double(value.getDouble());
+                return value.getDouble();
             case PropertyType.LONG:
-                return new Long(value.getLong());
+                return value.getLong();
             case PropertyType.DECIMAL:
                 return value.getDecimal();
             case PropertyType.NAME:
@@ -183,13 +182,13 @@
             throws ValueFormatException, RepositoryException {
         switch (value.getType()) {
             case PropertyType.BOOLEAN:
-                return ComparableBoolean.valueOf(value.getBoolean());
+                return value.getBoolean();
             case PropertyType.DATE:
-                return new Long(value.getDate().getTimeInMillis());
+                return value.getDate().getTimeInMillis();
             case PropertyType.DOUBLE:
-                return new Double(value.getDouble());
+                return value.getDouble();
             case PropertyType.LONG:
-                return new Long(value.getLong());
+                return value.getLong();
             case PropertyType.DECIMAL:
                 return value.getDecimal();
             case PropertyType.NAME:
@@ -258,16 +257,16 @@
         Comparable c2;
         switch (v1.getType()) {
             case PropertyType.BOOLEAN:
-                c2 = ComparableBoolean.valueOf(v2.getBoolean());
+                c2 = v2.getBoolean();
                 break;
             case PropertyType.DATE:
-                c2 = new Long(v2.getDate().getTimeInMillis());
+                c2 = v2.getDate().getTimeInMillis();
                 break;
             case PropertyType.DOUBLE:
-                c2 = new Double(v2.getDouble());
+                c2 = v2.getDouble();
                 break;
             case PropertyType.LONG:
-                c2 = new Long(v2.getLong());
+                c2 = v2.getLong();
                 break;
             case PropertyType.DECIMAL:
                 c2 = v2.getDecimal();

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java Mon Jun  8 14:25:26 2009
@@ -80,7 +80,7 @@
      *                             constraint.
      */
     public static Constraint create(ConstraintImpl constraint,
-                                    Map bindVariableValues,
+                                    Map<Name, Value> bindVariableValues,
                                     SelectorImpl[] selectors,
                                     LuceneQueryFactory factory,
                                     ValueFactory vf)
@@ -103,7 +103,7 @@
         /**
          * The bind variables and their values.
          */
-        private final Map bindVariableValues;
+        private final Map<Name, Value> bindVariableValues;
 
         /**
          * The selectors of the query.
@@ -128,7 +128,7 @@
          * @param factory            the lucene query factory.
          * @param vf                 the value factory of the current session.
          */
-        Visitor(Map bindVariableValues,
+        Visitor(Map<Name, Value> bindVariableValues,
                 SelectorImpl[] selectors,
                 LuceneQueryFactory factory,
                 ValueFactory vf) {
@@ -333,9 +333,9 @@
                 // assume default selector
                 return selectors[0];
             }
-            for (int i = 0; i < selectors.length; i++) {
-                if (selectors[i].getSelectorQName().equals(name)) {
-                    return selectors[i];
+            for (SelectorImpl selector : selectors) {
+                if (selector.getSelectorQName().equals(name)) {
+                    return selector;
                 }
             }
             return null;

Modified: jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractOrderByTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractOrderByTest.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractOrderByTest.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractOrderByTest.java Mon Jun  8 14:25:26 2009
@@ -22,6 +22,11 @@
 import javax.jcr.Repository;
 import javax.jcr.query.Query;
 import javax.jcr.query.QueryResult;
+import javax.jcr.query.qom.QueryObjectModel;
+import javax.jcr.query.qom.QueryObjectModelFactory;
+import javax.jcr.query.qom.Ordering;
+import javax.jcr.query.qom.PropertyValue;
+
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.Arrays;
@@ -123,6 +128,10 @@
         result = q.execute();
         checkResultOrder(result, nodeNames);
 
+        q = createQOM(true);
+        result = q.execute();
+        checkResultOrder(result, nodeNames);
+
         // then check descending
         Collections.reverse(Arrays.asList(nodeNames));
 
@@ -135,6 +144,10 @@
         q = superuser.getWorkspace().getQueryManager().createQuery(xpath + " descending", Query.XPATH);
         result = q.execute();
         checkResultOrder(result, nodeNames);
+
+        q = createQOM(false);
+        result = q.execute();
+        checkResultOrder(result, nodeNames);
     }
 
     /**
@@ -157,4 +170,21 @@
         }
     }
 
+    protected QueryObjectModel createQOM(boolean ascending)
+            throws RepositoryException {
+        QueryObjectModelFactory qf = superuser.getWorkspace().getQueryManager().getQOMFactory();
+        PropertyValue pv = qf.propertyValue("s", propertyName1);
+        Ordering ordering;
+        if (ascending) {
+            ordering = qf.ascending(pv);
+        } else {
+            ordering = qf.descending(pv);
+        }
+        return qf.createQuery(
+                qf.selector(testNodeType, "s"),
+                qf.descendantNode("s", testRoot),
+                new Ordering[]{ordering},
+                null
+        );
+    }
 }

Added: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/Order.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/Order.java?rev=782644&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/Order.java (added)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/Order.java Mon Jun  8 14:25:26 2009
@@ -0,0 +1,64 @@
+/*
+ * 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.qom;
+
+import javax.jcr.query.qom.QueryObjectModelConstants;
+
+/**
+ * Enumeration of the JCR 2.0 query order.
+ *
+ * @since Apache Jackrabbit 2.0
+ */
+public enum Order {
+
+    ASCENDING(QueryObjectModelConstants.JCR_ORDER_ASCENDING),
+
+    DESCENDING(QueryObjectModelConstants.JCR_ORDER_DESCENDING);
+
+    /**
+     * JCR name of this order.
+     */
+    private final String name;
+
+    private Order(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the JCR name of this order.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Return the order with the given JCR name.
+     *
+     * @param name the JCR name of an order.
+     * @return the order with the given name.
+     * @throws IllegalArgumentException if <code>name</code> is not a known JCR
+     *                                  order name.
+     */
+    public static Order getOrderByName(String name) {
+        for (Order order : Order.values()) {
+            if (order.name.equals(name)) {
+                return order;
+            }
+        }
+        throw new IllegalArgumentException("Unknown order name: " + name);
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/Order.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/OrderingImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/OrderingImpl.java?rev=782644&r1=782643&r2=782644&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/OrderingImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/OrderingImpl.java Mon Jun  8 14:25:26 2009
@@ -40,14 +40,14 @@
     /**
      * The order.
      */
-    private final String order;
+    private final Order order;
 
     OrderingImpl(NamePathResolver resolver,
                  DynamicOperandImpl operand,
                  String order) {
         super(resolver);
         this.operand = operand;
-        this.order = order;
+        this.order = Order.getOrderByName(order);
     }
 
     /**
@@ -67,9 +67,16 @@
      *         </ul>
      */
     public String getOrder() {
-        return order;
+        return order.getName();
     }
 
+    /**
+     * @return <code>true</code> if this ordering is ascending. Returns
+     *         <code>false</code> if ordering is descending.
+     */
+    public boolean isAscending() {
+        return order == Order.ASCENDING;
+    }
 
     //------------------------< AbstractQOMNode >-------------------------------
 



Mime
View raw message