You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2009/06/12 12:30:44 UTC
svn commit: r784061 - in /jackrabbit/trunk:
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/
jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/
Author: mreutegg
Date: Fri Jun 12 10:30:44 2009
New Revision: 784061
URL: http://svn.apache.org/viewvc?rev=784061&view=rev
Log:
JCR-2076: JSR 283: QOM and SQL2
- orderings (work in progress)
Added:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Ordering.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedMultiColumnQueryHits.java (with props)
Modified:
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/JoinQuery.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.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/SearchIndex.java
jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractOrderByTest.java
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=784061&r1=784060&r2=784061&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 Fri Jun 12 10:30:44 2009
@@ -20,7 +20,6 @@
import java.util.Arrays;
import org.apache.jackrabbit.core.query.lucene.constraint.Constraint;
-import org.apache.lucene.search.Sort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,11 +61,11 @@
* {@inheritDoc}
*/
public MultiColumnQueryHits execute(final JackrabbitIndexSearcher searcher,
- Sort sort,
+ Ordering[] orderings,
long resultFetchHint)
throws IOException {
- return new FilterMultiColumnQueryHits(query.execute(
- searcher, sort, resultFetchHint)) {
+ MultiColumnQueryHits hits = new FilterMultiColumnQueryHits(query.execute(
+ searcher, orderings, resultFetchHint)) {
{
log.debug(Arrays.asList(getSelectorNames()).toString());
@@ -95,5 +94,11 @@
}
}
};
+ if (orderings.length > 0 && hits.getSelectorNames().length > 1) {
+ // subsequent ordering is only needed
+ // when there is more than one column
+ hits = new SortedMultiColumnQueryHits(hits, orderings, searcher.getIndexReader());
+ }
+ return hits;
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java?rev=784061&r1=784060&r2=784061&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java Fri Jun 12 10:30:44 2009
@@ -18,7 +18,6 @@
import java.io.IOException;
-import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortComparatorSource;
import org.apache.lucene.index.IndexReader;
import org.apache.jackrabbit.core.query.lucene.join.Join;
@@ -89,13 +88,13 @@
* {@inheritDoc}
*/
public MultiColumnQueryHits execute(JackrabbitIndexSearcher searcher,
- Sort sort,
+ Ordering[] orderings,
long resultFetchHint)
throws IOException {
IndexReader reader = searcher.getIndexReader();
HierarchyResolver resolver = (HierarchyResolver) reader;
- return Join.create(left.execute(searcher, sort, resultFetchHint),
- right.execute(searcher, sort, resultFetchHint),
+ return Join.create(left.execute(searcher, orderings, resultFetchHint),
+ right.execute(searcher, orderings, resultFetchHint),
joinType, joinCondition, reader, resolver, scs, hmgr);
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java?rev=784061&r1=784060&r2=784061&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java Fri Jun 12 10:30:44 2009
@@ -18,8 +18,6 @@
import java.io.IOException;
-import org.apache.lucene.search.Sort;
-
/**
* <code>MultiColumnQuery</code> defines an interface for a query that returns
* {@link MultiColumnQueryHits}.
@@ -30,13 +28,13 @@
* Executes this query and returns multi column query hits.
*
* @param searcher the index searcher.
- * @param sort the sort criteria.
+ * @param orderings the orderings.
* @param resultFetchHint the result fetch hint.
* @return the query hits.
* @throws IOException if an error occurs while executing the query.
*/
public MultiColumnQueryHits execute(JackrabbitIndexSearcher searcher,
- Sort sort,
+ Ordering[] orderings,
long resultFetchHint)
throws IOException;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java?rev=784061&r1=784060&r2=784061&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java Fri Jun 12 10:30:44 2009
@@ -19,6 +19,7 @@
import java.io.IOException;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.SortField;
import org.apache.lucene.search.Sort;
import org.apache.jackrabbit.spi.Name;
@@ -64,9 +65,13 @@
* {@inheritDoc}
*/
public MultiColumnQueryHits execute(JackrabbitIndexSearcher searcher,
- Sort sort,
+ Ordering[] orderings,
long resultFetchHint)
throws IOException {
- return searcher.execute(query, sort, resultFetchHint, selectorName);
+ SortField[] fields = new SortField[orderings.length];
+ for (int i = 0; i < orderings.length; i++) {
+ fields[i] = orderings[i].getSortField();
+ }
+ return searcher.execute(query, new Sort(fields), resultFetchHint, selectorName);
}
}
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=784061&r1=784060&r2=784061&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 Fri Jun 12 10:30:44 2009
@@ -40,7 +40,7 @@
/**
* The order specifier for each of the order properties.
*/
- protected final OrderingImpl[] orderings;
+ protected final Ordering[] orderings;
public MultiColumnQueryResult(SearchIndex index,
ItemManager itemMgr,
@@ -57,7 +57,7 @@
super(index, itemMgr, session, accessMgr, queryImpl, spellSuggestion,
columns, documentOrder, offset, limit);
this.query = query;
- this.orderings = orderings;
+ this.orderings = index.createOrderings(orderings);
// if document order is requested get all results right away
getResults(docOrder ? Integer.MAX_VALUE : index.getResultFetchSize());
}
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Ordering.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Ordering.java?rev=784061&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Ordering.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Ordering.java Fri Jun 12 10:30:44 2009
@@ -0,0 +1,157 @@
+/*
+ * 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 javax.jcr.RepositoryException;
+
+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.PropertyValueImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.LowerCaseImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.DynamicOperandImpl;
+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.Name;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortComparatorSource;
+
+/**
+ * <code>Ordering</code> implements a single ordering specification.
+ */
+public class Ordering {
+
+ /**
+ * The selector name where this ordering applies to.
+ */
+ private final Name selectorName;
+
+ /**
+ * The lucene sort field for this ordering.
+ */
+ private final SortField sort;
+
+ /**
+ * Private constructor.
+ *
+ * @param selectorName the selector name for this ordering.
+ * @param sort the lucene sort field for this ordering.
+ */
+ private Ordering(Name selectorName, SortField sort) {
+ this.selectorName = selectorName;
+ this.sort = sort;
+ }
+
+ /**
+ * @return the selector name where this ordering applies to.
+ */
+ public Name getSelectorName() {
+ return selectorName;
+ }
+
+ /**
+ * @return the lucene sort field for this ordering.
+ */
+ public SortField getSortField() {
+ return sort;
+ }
+
+ /**
+ * Creates an ordering from a JCR QOM ordering.
+ *
+ * @param ordering the JCR QOM ordering specification.
+ * @param scs the sort comparator source from the search index.
+ * @param nsMappings the index internal namespace mappings.
+ * @return an ordering.
+ * @throws RepositoryException if an error occurs while translating the JCR
+ * QOM ordering.
+ */
+ public static Ordering fromQOM(final OrderingImpl ordering,
+ final SortComparatorSource scs,
+ final NamespaceMappings nsMappings)
+ throws RepositoryException {
+ final Name[] selectorName = new Name[1];
+ QOMTreeVisitor visitor = new DefaultTraversingQOMTreeVisitor() {
+
+ public Object visit(LengthImpl node, Object data) throws Exception {
+ PropertyValueImpl propValue = (PropertyValueImpl) node.getPropertyValue();
+ selectorName[0] = propValue.getSelectorQName();
+ return new SortField(propValue.getPropertyQName().toString(),
+ new LengthSortComparator(nsMappings),
+ !ordering.isAscending());
+ }
+
+ public Object visit(LowerCaseImpl node, Object data)
+ throws Exception {
+ SortField sf = (SortField) ((DynamicOperandImpl) node.getOperand()).accept(this, data);
+ selectorName[0] = node.getSelectorQName();
+ return new SortField(sf.getField(),
+ new LowerCaseSortComparator(sf.getFactory()),
+ !ordering.isAscending());
+ }
+
+ public Object visit(UpperCaseImpl node, Object data)
+ throws Exception {
+ SortField sf = (SortField) ((DynamicOperandImpl) node.getOperand()).accept(this, data);
+ selectorName[0] = node.getSelectorQName();
+ return new SortField(sf.getField(),
+ new UpperCaseSortComparator(sf.getFactory()),
+ !ordering.isAscending());
+ }
+
+ public Object visit(FullTextSearchScoreImpl node, Object data)
+ throws Exception {
+ selectorName[0] = node.getSelectorQName();
+ return new SortField(null, SortField.SCORE,
+ ordering.isAscending());
+ }
+
+ public Object visit(NodeLocalNameImpl node, Object data) throws Exception {
+ selectorName[0] = node.getSelectorQName();
+ return new SortField(FieldNames.LOCAL_NAME,
+ SortField.STRING, !ordering.isAscending());
+ }
+
+ public Object visit(NodeNameImpl node, Object data) throws Exception {
+ selectorName[0] = node.getSelectorQName();
+ return new SortField(FieldNames.LABEL,
+ SortField.STRING, !ordering.isAscending());
+ }
+
+ public Object visit(PropertyValueImpl node, Object data)
+ throws Exception {
+ selectorName[0] = node.getSelectorQName();
+ 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 {
+ SortField field = (SortField) ordering.accept(visitor, null);
+ return new Ordering(selectorName[0], field);
+ } catch (Exception e) {
+ throw new RepositoryException(e);
+ }
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Ordering.java
------------------------------------------------------------------------------
svn:eol-style = native
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=784061&r1=784060&r2=784061&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 Fri Jun 12 10:30:44 2009
@@ -46,16 +46,6 @@
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;
@@ -791,19 +781,17 @@
*/
public MultiColumnQueryHits executeQuery(SessionImpl session,
MultiColumnQuery query,
- OrderingImpl[] orderings,
+ Ordering[] orderings,
long resultFetchHint)
throws IOException {
checkOpen();
- Sort sort = new Sort(createSortFields(orderings));
-
final IndexReader reader = getIndexReader();
JackrabbitIndexSearcher searcher = new JackrabbitIndexSearcher(
session, reader, getContext().getItemStateManager());
searcher.setSimilarity(getSimilarity());
return new FilterMultiColumnQueryHits(
- query.execute(searcher, sort, resultFetchHint)) {
+ query.execute(searcher, orderings, resultFetchHint)) {
public void close() throws IOException {
try {
super.close();
@@ -998,74 +986,19 @@
}
/**
- * Creates sort fields for the ordering specifications.
+ * Creates internal orderings for the QOM ordering specifications.
*
- * @param orderings the ordering specifications.
- * @return the sort fields.
+ * @param orderings the QOM ordering specifications.
+ * @return the internal orderings.
+ * @throws RepositoryException if an error occurs.
*/
- 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(nsMappings),
- !ordering.isAscending());
- }
-
- public Object visit(LowerCaseImpl node, Object data)
- throws Exception {
- SortField sf = (SortField) ((DynamicOperandImpl) node.getOperand()).accept(this, data);
- return new SortField(sf.getField(),
- new LowerCaseSortComparator(sf.getFactory()),
- !ordering.isAscending());
- }
-
- public Object visit(UpperCaseImpl node, Object data)
- throws Exception {
- SortField sf = (SortField) ((DynamicOperandImpl) node.getOperand()).accept(this, data);
- return new SortField(sf.getField(),
- new UpperCaseSortComparator(sf.getFactory()),
- !ordering.isAscending());
- }
-
- 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
- }
+ protected Ordering[] createOrderings(OrderingImpl[] orderings)
+ throws RepositoryException {
+ Ordering[] ords = new Ordering[orderings.length];
+ for (int i = 0; i < orderings.length; i++) {
+ ords[i] = Ordering.fromQOM(orderings[i], scs, nsMappings);
}
- return sortFields.toArray(new SortField[sortFields.size()]);
+ return ords;
}
/**
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedMultiColumnQueryHits.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedMultiColumnQueryHits.java?rev=784061&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedMultiColumnQueryHits.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedMultiColumnQueryHits.java Fri Jun 12 10:30:44 2009
@@ -0,0 +1,202 @@
+/*
+ * 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 java.util.List;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.ScoreDocComparator;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.jackrabbit.spi.Name;
+
+/**
+ * <code>SortedMultiColumnQueryHits</code> implements sorting of query hits
+ * based on {@link Ordering}s.
+ */
+public class SortedMultiColumnQueryHits extends FilterMultiColumnQueryHits {
+
+ /**
+ * Iterator over sorted ScoreNode[]s.
+ */
+ private final Iterator<ScoreNode[]> it;
+
+ /**
+ * Creates sorted query hits.
+ *
+ * @param hits the hits to sort.
+ * @param orderings the ordering specifications.
+ * @param reader the current index reader.
+ * @throws IOException if an error occurs while reading from the index.
+ */
+ public SortedMultiColumnQueryHits(MultiColumnQueryHits hits,
+ Ordering[] orderings,
+ IndexReader reader)
+ throws IOException {
+ super(hits);
+ List<ScoreNode[]> sortedHits = new ArrayList<ScoreNode[]>();
+ ScoreNode[] next;
+ while ((next = hits.nextScoreNodes()) != null) {
+ sortedHits.add(next);
+ }
+ try {
+ Collections.sort(sortedHits, new ScoreNodeComparator(
+ reader, orderings, hits.getSelectorNames()));
+ } catch (RuntimeException e) {
+ // might be thrown by ScoreNodeComparator#compare
+ throw Util.createIOException(e);
+ }
+ this.it = sortedHits.iterator();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ScoreNode[] nextScoreNodes() throws IOException {
+ if (it.hasNext()) {
+ return it.next();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void skip(int n) throws IOException {
+ while (n-- > 0) {
+ nextScoreNodes();
+ }
+ }
+
+ /**
+ * A comparator that compares ScoreNode[].
+ */
+ private static final class ScoreNodeComparator
+ implements Comparator<ScoreNode[]> {
+
+ /**
+ * The current index reader.
+ */
+ private final IndexReader reader;
+
+ /**
+ * The ordering specifications.
+ */
+ private final Ordering[] orderings;
+
+ /**
+ * The selector name index for each of the {@link #orderings}.
+ */
+ private final int[] idx;
+
+ /**
+ * The score doc comparator for each of the {@link #orderings}.
+ */
+ private final ScoreDocComparator[] comparators;
+
+ /**
+ * The reverse flag for each of the {@link #orderings}.
+ */
+ private final boolean[] isReverse;
+
+ /**
+ * Reusable ScoreDoc for use in {@link #compare(ScoreNode[], ScoreNode[])}.
+ */
+ private final ScoreDoc doc1 = new ScoreDoc(0, 1.0f);
+
+ /**
+ * Reusable ScoreDoc for use in {@link #compare(ScoreNode[], ScoreNode[])}.
+ */
+ private final ScoreDoc doc2 = new ScoreDoc(0, 1.0f);
+
+ /**
+ * Creates a new comparator.
+ *
+ * @param reader the current index reader.
+ * @param orderings the ordering specifications.
+ * @param selectorNames the selector names associated with the
+ * ScoreNode[] used in
+ * {@link #compare(ScoreNode[], ScoreNode[])}.
+ * @throws IOException if an error occurs while reading from the index.
+ */
+ private ScoreNodeComparator(IndexReader reader,
+ Ordering[] orderings,
+ Name[] selectorNames)
+ throws IOException {
+ this.reader = reader;
+ this.orderings = orderings;
+ List names = Arrays.asList(selectorNames);
+ this.idx = new int[orderings.length];
+ this.comparators = new ScoreDocComparator[orderings.length];
+ this.isReverse = new boolean[orderings.length];
+ for (int i = 0; i < orderings.length; i++) {
+ idx[i] = names.indexOf(orderings[i].getSelectorName());
+ SortField sf = orderings[i].getSortField();
+ if (sf.getFactory() != null) {
+ comparators[i] = sf.getFactory().newComparator(reader, sf.getField());
+ }
+ isReverse[i] = sf.getReverse();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compare(ScoreNode[] sn1, ScoreNode[] sn2) {
+ for (int i = 0; i < orderings.length; i++) {
+ int c;
+ int scoreNodeIndex = idx[i];
+ ScoreNode n1 = sn1[scoreNodeIndex];
+ ScoreNode n2 = sn2[scoreNodeIndex];
+ if (n1 == n2) {
+ continue;
+ } else if (n1 == null) {
+ c = -1;
+ } else if (n2 == null) {
+ c = 1;
+ } else if (comparators[i] != null) {
+ try {
+ doc1.doc = n1.getDoc(reader);
+ doc1.score = n1.getScore();
+ doc2.doc = n2.getDoc(reader);
+ doc2.score = n2.getScore();
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ c = comparators[i].compare(doc1, doc2);
+ } else {
+ // compare score
+ c = new Float(n1.getScore()).compareTo(n2.getScore());
+ }
+ if (c != 0) {
+ if (isReverse[i]) {
+ c = -c;
+ }
+ return c;
+ }
+ }
+ return 0;
+ }
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedMultiColumnQueryHits.java
------------------------------------------------------------------------------
svn:eol-style = native
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=784061&r1=784060&r2=784061&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 Fri Jun 12 10:30:44 2009
@@ -20,12 +20,10 @@
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Repository;
-import javax.jcr.Value;
import javax.jcr.ValueFactory;
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.DynamicOperand;