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/03/25 10:51:13 UTC

svn commit: r758193 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/ main/java/org/apache/jackrabbit/core/query/ main/java/org/apache/jackrabbit/core/query/lucene/ test/java/org/apache/jackrabbit/core/query/

Author: mreutegg
Date: Wed Mar 25 09:51:03 2009
New Revision: 758193

URL: http://svn.apache.org/viewvc?rev=758193&view=rev
Log:
JCR-2010: Retrieve row path via hierarchy manager instead of node

Added:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderScoreNodeIterator.java
      - copied, changed from r756427, jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderNodeIteratorImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java   (with props)
Removed:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderNodeIteratorImpl.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIteratorImpl.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/RowIteratorImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIterator.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/QueryResultTest.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java?rev=758193&r1=758192&r2=758193&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java Wed Mar 25 09:51:03 2009
@@ -27,9 +27,9 @@
 import org.apache.jackrabbit.core.query.QueryHandlerContext;
 import org.apache.jackrabbit.core.query.QueryObjectModelImpl;
 import org.apache.jackrabbit.core.state.ItemStateException;
-import org.apache.jackrabbit.core.state.ItemStateManager;
 import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.core.state.NodeStateIterator;
+import org.apache.jackrabbit.core.state.SharedItemStateManager;
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
 import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
 import org.apache.jackrabbit.spi.commons.query.jsr283.qom.QueryObjectModel;
@@ -101,7 +101,7 @@
     /**
      * The shared item state manager instance for the workspace.
      */
-    private final ItemStateManager itemMgr;
+    private final SharedItemStateManager itemMgr;
 
     /**
      * The underlying persistence manager.
@@ -164,7 +164,7 @@
     public SearchManager(SearchConfig config,
                          final NamespaceRegistryImpl nsReg,
                          NodeTypeRegistry ntReg,
-                         ItemStateManager itemMgr,
+                         SharedItemStateManager itemMgr,
                          PersistenceManager pm,
                          NodeId rootNodeId,
                          SearchManager parentMgr,

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java?rev=758193&r1=758192&r2=758193&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryHandlerContext.java Wed Mar 25 09:51:03 2009
@@ -19,10 +19,11 @@
 import org.apache.jackrabbit.core.fs.FileSystem;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
 import org.apache.jackrabbit.core.state.ItemStateManager;
+import org.apache.jackrabbit.core.state.SharedItemStateManager;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.NamespaceRegistryImpl;
 import org.apache.jackrabbit.core.HierarchyManager;
-import org.apache.jackrabbit.core.HierarchyManagerImpl;
+import org.apache.jackrabbit.core.CachingHierarchyManager;
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
 
 /**
@@ -40,12 +41,12 @@
     /**
      * The persistent <code>ItemStateManager</code>
      */
-    private final ItemStateManager stateMgr;
+    private final SharedItemStateManager stateMgr;
 
     /**
      * The hierarchy manager on top of {@link #stateMgr}.
      */
-    private final HierarchyManager hmgr;
+    private final CachingHierarchyManager hmgr;
 
     /**
      * The underlying persistence manager.
@@ -101,7 +102,7 @@
      *                         excluded from indexing.
      */
     public QueryHandlerContext(FileSystem fs,
-                               ItemStateManager stateMgr,
+                               SharedItemStateManager stateMgr,
                                PersistenceManager pm,
                                NodeId rootId,
                                NodeTypeRegistry ntRegistry,
@@ -110,7 +111,8 @@
                                NodeId excludedNodeId) {
         this.fs = fs;
         this.stateMgr = stateMgr;
-        this.hmgr = new HierarchyManagerImpl(rootId, stateMgr);
+        this.hmgr = new CachingHierarchyManager(rootId, stateMgr);
+        this.stateMgr.addListener(hmgr);
         this.pm = pm;
         this.rootId = rootId;
         this.ntRegistry = ntRegistry;

Copied: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderScoreNodeIterator.java (from r756427, jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderNodeIteratorImpl.java)
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderScoreNodeIterator.java?p2=jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderScoreNodeIterator.java&p1=jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderNodeIteratorImpl.java&r1=756427&r2=758193&rev=758193&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderNodeIteratorImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocOrderScoreNodeIterator.java Wed Mar 25 09:51:03 2009
@@ -31,15 +31,15 @@
 import java.util.ArrayList;
 
 /**
- * Implements a NodeIterator that returns the nodes in document order.
+ * Implements a ScoreNodeIterator that returns the score nodes in document order.
  */
-class DocOrderNodeIteratorImpl implements ScoreNodeIterator {
+class DocOrderScoreNodeIterator implements ScoreNodeIterator {
 
     /** Logger instance for this class */
-    private static final Logger log = LoggerFactory.getLogger(DocOrderNodeIteratorImpl.class);
+    private static final Logger log = LoggerFactory.getLogger(DocOrderScoreNodeIterator.class);
 
     /** A node iterator with ordered nodes */
-    private NodeIteratorImpl orderedNodes;
+    private ScoreNodeIterator orderedNodes;
 
     /** Unordered list of {@link ScoreNode}[]s. */
     private final List scoreNodes;
@@ -53,7 +53,7 @@
     private final int selectorIndex;
 
     /**
-     * Creates a <code>DocOrderNodeIteratorImpl</code> that orders the nodes in
+     * Creates a <code>DocOrderScoreNodeIterator</code> that orders the nodes in
      * <code>scoreNodes</code> in document order.
      *
      * @param itemMgr       the item manager of the session executing the
@@ -63,7 +63,7 @@
      * @param selectorIndex apply document order on the score nodes with this
      *                      selectorIndex.
      */
-    DocOrderNodeIteratorImpl(ItemManager itemMgr,
+    DocOrderScoreNodeIterator(ItemManager itemMgr,
                              List scoreNodes,
                              int selectorIndex) {
         this.itemMgr = itemMgr;
@@ -75,22 +75,15 @@
      * {@inheritDoc}
      */
     public Object next() {
-        return nextNodeImpl();
+        return nextScoreNodes();
     }
 
     /**
      * {@inheritDoc}
      */
-    public Node nextNode() {
-        return nextNodeImpl();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public NodeImpl nextNodeImpl() {
+    public ScoreNode[] nextScoreNodes() {
         initOrderedIterator();
-        return orderedNodes.nextNodeImpl();
+        return orderedNodes.nextScoreNodes();
     }
 
     /**
@@ -144,22 +137,6 @@
         return orderedNodes.hasNext();
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    public float getScore() {
-        initOrderedIterator();
-        return orderedNodes.getScore();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public ScoreNode[] getScoreNodes() {
-        initOrderedIterator();
-        return orderedNodes.getScoreNodes();
-    }
-
     //------------------------< internal >--------------------------------------
 
     /**
@@ -286,7 +263,7 @@
         if (log.isDebugEnabled()) {
             log.debug("" + nodes.length + " node(s) ordered in " + (System.currentTimeMillis() - time) + " ms");
         }
-        orderedNodes = new NodeIteratorImpl(itemMgr, nodes, selectorIndex);
+        orderedNodes = new ScoreNodeIteratorImpl(nodes);
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIteratorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIteratorImpl.java?rev=758193&r1=758192&r2=758193&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIteratorImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIteratorImpl.java Wed Mar 25 09:51:03 2009
@@ -23,19 +23,21 @@
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
+import javax.jcr.NodeIterator;
+
 import java.util.NoSuchElementException;
 
 /**
  * Implements a {@link javax.jcr.NodeIterator} returned by
  * {@link javax.jcr.query.QueryResult#getNodes()}.
  */
-class NodeIteratorImpl implements ScoreNodeIterator {
+class NodeIteratorImpl implements NodeIterator {
 
     /** Logger instance for this class */
     private static final Logger log = LoggerFactory.getLogger(NodeIteratorImpl.class);
 
     /** The node ids of the nodes in the result set with their score value */
-    protected final ScoreNode[][] scoreNodes;
+    protected final ScoreNodeIterator scoreNodes;
 
     /** The index for the default selector withing {@link #scoreNodes} */
     private final int selectorIndex;
@@ -43,9 +45,6 @@
     /** ItemManager to turn UUIDs into Node instances */
     protected final ItemManager itemMgr;
 
-    /** Current position in the UUID array */
-    protected int pos = -1;
-
     /** Number of invalid nodes */
     protected int invalid = 0;
 
@@ -53,21 +52,25 @@
     private NodeImpl next;
 
     /**
+     * Whether this iterator had been initialized.
+     */
+    private boolean initialized;
+
+    /**
      * Creates a new <code>NodeIteratorImpl</code> instance.
      *
      * @param itemMgr       the <code>ItemManager</code> to turn UUIDs into
      *                      <code>Node</code> instances.
-     * @param scoreNodes    the node ids of the matching nodes.
+     * @param scoreNodes    iterator over score nodes.
      * @param selectorIndex the index for the default selector within
      *                      <code>scoreNodes</code>.
      */
     NodeIteratorImpl(ItemManager itemMgr,
-                     ScoreNode[][] scoreNodes,
+                     ScoreNodeIterator scoreNodes,
                      int selectorIndex) {
         this.itemMgr = itemMgr;
         this.scoreNodes = scoreNodes;
         this.selectorIndex = selectorIndex;
-        fetchNext();
     }
 
     /**
@@ -77,7 +80,13 @@
      *   <code>Node</code>s.
      */
     public Node nextNode() throws NoSuchElementException {
-        return nextNodeImpl();
+        initialize();
+        if (next == null) {
+            throw new NoSuchElementException();
+        }
+        NodeImpl n = next;
+        fetchNext();
+        return n;
     }
 
     /**
@@ -87,41 +96,20 @@
      *   <code>Node</code>s.
      */
     public Object next() throws NoSuchElementException {
+        initialize();
         return nextNode();
     }
 
     /**
-     * Returns the next <code>Node</code> in the result set.
-     *
-     * @return the next <code>Node</code> in the result set.
-     * @throws NoSuchElementException if iteration has no more <code>Node</code>s.
-     */
-    public NodeImpl nextNodeImpl() throws NoSuchElementException {
-        if (next == null) {
-            throw new NoSuchElementException();
-        }
-        NodeImpl n = next;
-        fetchNext();
-        return n;
-    }
-
-    /**
      * Skip a number of <code>Node</code>s in this iterator.
      * @param skipNum the non-negative number of <code>Node</code>s to skip
      * @throws NoSuchElementException
      *          if skipped past the last <code>Node</code> in this iterator.
      */
     public void skip(long skipNum) throws NoSuchElementException {
-        if (skipNum < 0) {
-            throw new IllegalArgumentException("skipNum must not be negative");
-        }
-        if ((pos + skipNum) > scoreNodes.length) {
-            throw new NoSuchElementException();
-        }
-        if (skipNum == 0) {
-            // do nothing
-        } else {
-            pos += skipNum - 1;
+        initialize();
+        if (skipNum > 0) {
+            scoreNodes.skip(skipNum - 1);
             fetchNext();
         }
     }
@@ -139,7 +127,12 @@
      * @return the number of node in this iterator.
      */
     public long getSize() {
-        return scoreNodes.length - invalid;
+        long size = scoreNodes.getSize();
+        if (size == -1) {
+            return size;
+        } else {
+            return size - invalid;
+        }
     }
 
     /**
@@ -147,7 +140,14 @@
      * @return the current position in this <code>NodeIterator</code>.
      */
     public long getPosition() {
-        return pos - invalid;
+        initialize();
+        long position = scoreNodes.getPosition() - invalid;
+        // scoreNode.getPosition() is one ahead
+        // if there is a prefetched node
+        if (next != null) {
+            position--;
+        }
+        return position;
     }
 
     /**
@@ -157,6 +157,7 @@
      *  available; <code>false</code> otherwise.
      */
     public boolean hasNext() {
+        initialize();
         return next != null;
     }
 
@@ -168,26 +169,6 @@
     }
 
     /**
-     * Returns the score of the node returned by {@link #nextNode()}. In other
-     * words, this method returns the score value of the next <code>Node</code>.
-     * @return the score of the node returned by {@link #nextNode()}.
-     * @throws NoSuchElementException if there is no next node.
-     */
-    public float getScore() throws NoSuchElementException {
-        if (!hasNext()) {
-            throw new NoSuchElementException();
-        }
-        return scoreNodes[pos][selectorIndex].getScore();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public ScoreNode[] getScoreNodes() {
-        return scoreNodes[pos];
-    }
-
-    /**
      * Clears {@link #next} and tries to fetch the next Node instance.
      * When this method returns {@link #next} refers to the next available
      * node instance in this iterator. If {@link #next} is null when this
@@ -196,17 +177,23 @@
     protected void fetchNext() {
         // reset
         next = null;
-        while (next == null && (pos + 1) < scoreNodes.length) {
+        while (next == null && scoreNodes.hasNext()) {
+            ScoreNode[] sn = scoreNodes.nextScoreNodes();
             try {
-                next = (NodeImpl) itemMgr.getItem(scoreNodes[pos + 1][selectorIndex].getNodeId());
+                next = (NodeImpl) itemMgr.getItem(sn[selectorIndex].getNodeId());
             } catch (RepositoryException e) {
                 log.warn("Exception retrieving Node with UUID: "
-                        + scoreNodes[pos + 1][selectorIndex].getNodeId() + ": " + e.toString());
+                        + sn[selectorIndex].getNodeId() + ": " + e.toString());
                 // try next
                 invalid++;
-                pos++;
             }
         }
-        pos++;
+    }
+
+    protected void initialize() {
+        if (!initialized) {
+            fetchNext();
+            initialized = true;
+        }
     }
 }

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=758193&r1=758192&r2=758193&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 Wed Mar 25 09:51:03 2009
@@ -17,7 +17,6 @@
 package org.apache.jackrabbit.core.query.lucene;
 
 import org.apache.jackrabbit.core.ItemManager;
-import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.security.AccessManager;
 import org.apache.jackrabbit.spi.Name;
@@ -28,7 +27,6 @@
 
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.NamespaceException;
-import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.query.QueryResult;
@@ -161,6 +159,8 @@
      *                        document order.
      * @param limit           the maximum result size
      * @param offset          the offset in the total result set
+     * @throws RepositoryException if an error occurs while reading from the
+     *                             repository.
      */
     public QueryResultImpl(SearchIndex index,
                            ItemManager itemMgr,
@@ -213,7 +213,7 @@
      * {@inheritDoc}
      */
     public NodeIterator getNodes() throws RepositoryException {
-        return getNodeIterator();
+        return new NodeIteratorImpl(itemMgr, getScoreNodes(), 0);
     }
 
     /**
@@ -227,8 +227,9 @@
                 throw new RepositoryException(e);
             }
         }
-        return new RowIteratorImpl(getNodeIterator(), selectProps,
-                queryImpl.getSelectorNames(), itemMgr, session,
+        return new RowIteratorImpl(getScoreNodes(), selectProps,
+                queryImpl.getSelectorNames(), itemMgr,
+                index.getContext().getHierarchyManager(), session,
                 excerptProvider, spellSuggestion);
     }
 
@@ -247,15 +248,15 @@
     //--------------------------------< internal >------------------------------
 
     /**
-     * Creates a node iterator over the result nodes.
+     * Creates a {@link ScoreNodeIterator} over the query result.
      *
-     * @return a node iterator over the result nodes.
+     * @return a {@link ScoreNodeIterator} over the query result.
      */
-    private ScoreNodeIterator getNodeIterator() {
+    private ScoreNodeIterator getScoreNodes() {
         if (docOrder) {
-            return new DocOrderNodeIteratorImpl(itemMgr, resultNodes, 0);
+            return new DocOrderScoreNodeIterator(itemMgr, resultNodes, 0);
         } else {
-            return new LazyScoreNodeIterator(0);
+            return new LazyScoreNodeIteratorImpl();
         }
     }
 
@@ -383,6 +384,8 @@
      * number may get smaller if nodes are found in the result set which the
      * current session has no permission to access. This method may return
      * <code>-1</code> if the total size is unknown.
+     *
+     * @return the total number of hits.
      */
     public int getTotalSize() {
         if (numResults == -1) {
@@ -392,60 +395,22 @@
         }
     }
 
-    private final class LazyScoreNodeIterator implements ScoreNodeIterator {
+    private final class LazyScoreNodeIteratorImpl implements ScoreNodeIterator {
 
         private int position = -1;
 
         private boolean initialized = false;
 
-        private NodeImpl next;
-
-        private final int selectorIndex;
-
-        private LazyScoreNodeIterator(int selectorIndex) {
-            this.selectorIndex = selectorIndex;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public float getScore() {
-            initialize();
-            if (!hasNext()) {
-                throw new NoSuchElementException();
-            }
-            return ((ScoreNode[]) resultNodes.get(position))[selectorIndex].getScore();
-        }
+        private ScoreNode[] next;
 
-        /**
-         * {@inheritDoc}
-         */
-        public ScoreNode[] getScoreNodes() {
-            initialize();
-            if (!hasNext()) {
-                throw new NoSuchElementException();
-            }
-            return (ScoreNode[]) resultNodes.get(position);
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public NodeImpl nextNodeImpl() {
+        public ScoreNode[] nextScoreNodes() {
             initialize();
             if (next == null) {
                 throw new NoSuchElementException();
             }
-            NodeImpl n = next;
+            ScoreNode[] sn = next;
             fetchNext();
-            return n;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public Node nextNode() {
-            return nextNodeImpl();
+            return sn;
         }
 
         /**
@@ -522,7 +487,7 @@
          * {@inheritDoc}
          */
         public Object next() {
-            return nextNodeImpl();
+            return nextScoreNodes();
         }
 
         /**
@@ -569,16 +534,7 @@
                         break;
                     }
                 }
-                ScoreNode[] sn = (ScoreNode[]) resultNodes.get(nextPos);
-                try {
-                    next = (NodeImpl) itemMgr.getItem(sn[selectorIndex].getNodeId());
-                } catch (RepositoryException e) {
-                    log.warn("Exception retrieving Node with UUID: "
-                            + sn[selectorIndex].getNodeId() + ": " + e.toString());
-                    // remove score node and try next
-                    resultNodes.remove(nextPos);
-                    invalid++;
-                }
+                next = (ScoreNode[]) resultNodes.get(nextPos);
             }
             position++;
         }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java?rev=758193&r1=758192&r2=758193&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java Wed Mar 25 09:51:03 2009
@@ -20,12 +20,16 @@
 import org.apache.jackrabbit.core.PropertyImpl;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.ItemManager;
+import org.apache.jackrabbit.core.HierarchyManager;
 import org.apache.jackrabbit.spi.commons.conversion.NameException;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QValueFactory;
+import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
-import org.apache.jackrabbit.value.ValueFactoryImpl;
+import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
+import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl;
 import org.apache.jackrabbit.util.ISO9075;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
@@ -37,7 +41,6 @@
 import javax.jcr.Value;
 import javax.jcr.PathNotFoundException;
 import javax.jcr.NamespaceException;
-import javax.jcr.ValueFactory;
 import javax.jcr.Node;
 import javax.jcr.query.Row;
 import javax.jcr.query.RowIterator;
@@ -61,9 +64,9 @@
     private static final Logger log = LoggerFactory.getLogger(RowIteratorImpl.class);
 
     /**
-     * The value factory.
+     * The QValue factory.
      */
-    private static final ValueFactory VALUE_FACTORY = ValueFactoryImpl.getInstance();
+    private static final QValueFactory QVALUE_FACTORY = QValueFactoryImpl.getInstance();
 
     /**
      * The name of the excerpt function without prefix but with left parenthesis.
@@ -85,7 +88,7 @@
     /**
      * Iterator over nodes, that constitute the result set.
      */
-    private final ScoreNodeIterator nodes;
+    private final ScoreNodeIterator scoreNodes;
 
     /**
      * Array of select property names
@@ -93,6 +96,11 @@
     private final Name[] properties;
 
     /**
+     * Set of select property <code>Name</code>s.
+     */
+    private Set propertySet;
+
+    /**
      * List of valid selector {@link Name}s.
      */
     private final List selectorNames = new ArrayList();
@@ -103,6 +111,11 @@
     private final ItemManager itemMgr;
 
     /**
+     * The hierarchy manager of the workspace.
+     */
+    private final HierarchyManager hmgr;
+
+    /**
      * The <code>NamePathResolver</code> of the user <code>Session</code>.
      */
     private final NamePathResolver resolver;
@@ -118,15 +131,21 @@
     private final SpellSuggestion spellSuggestion;
 
     /**
+     * A value factory for the session that executes the query.
+     */
+    private final ValueFactoryQImpl valueFactory;
+
+    /**
      * Creates a new <code>RowIteratorImpl</code> that iterates over the result
      * nodes.
      *
-     * @param nodes           a <code>ScoreNodeIterator</code> that contains the
+     * @param scoreNodes      a <code>ScoreNodeIterator</code> that contains the
      *                        nodes of the query result.
      * @param properties      <code>Name</code> of the select properties.
      * @param selectorNames   the selector names.
      * @param itemMgr         the item manager of the session that executes the
      *                        query.
+     * @param hmgr            the hierarchy manager of the workspace.
      * @param resolver        <code>NamespaceResolver</code> of the user
      *                        <code>Session</code>.
      * @param exProvider      the excerpt provider associated with the query
@@ -134,20 +153,23 @@
      * @param spellSuggestion the spell suggestion associated with the query
      *                        result or <code>null</code> if none is available.
      */
-    RowIteratorImpl(ScoreNodeIterator nodes,
+    RowIteratorImpl(ScoreNodeIterator scoreNodes,
                     Name[] properties,
                     Name[] selectorNames,
                     ItemManager itemMgr,
+                    HierarchyManager hmgr,
                     NamePathResolver resolver,
                     ExcerptProvider exProvider,
                     SpellSuggestion spellSuggestion) {
-        this.nodes = nodes;
+        this.scoreNodes = scoreNodes;
         this.properties = properties;
         this.selectorNames.addAll(Arrays.asList(selectorNames));
         this.itemMgr = itemMgr;
+        this.hmgr = hmgr;
         this.resolver = resolver;
         this.excerptProvider = exProvider;
         this.spellSuggestion = spellSuggestion;
+        this.valueFactory = new ValueFactoryQImpl(QVALUE_FACTORY, resolver);
     }
 
     /**
@@ -158,8 +180,7 @@
      *                                <code>Row</code>s.
      */
     public Row nextRow() throws NoSuchElementException {
-        return new RowImpl(nodes.getScore(),
-                nodes.getScoreNodes(), nodes.nextNodeImpl());
+        return new RowImpl(scoreNodes.nextScoreNodes());
     }
 
     /**
@@ -170,7 +191,7 @@
      *                                <code>Row</code> in this iterator.
      */
     public void skip(long skipNum) throws NoSuchElementException {
-        nodes.skip(skipNum);
+        scoreNodes.skip(skipNum);
     }
 
     /**
@@ -179,7 +200,7 @@
      * @return the number of <code>Row</code>s in this iterator.
      */
     public long getSize() {
-        return nodes.getSize();
+        return scoreNodes.getSize();
     }
 
     /**
@@ -193,7 +214,7 @@
      * @return the current position withing this iterator.
      */
     public long getPosition() {
-        return nodes.getPosition();
+        return scoreNodes.getPosition();
     }
 
     /**
@@ -211,7 +232,7 @@
      * @return <code>true</code> if the iterator has more elements.
      */
     public boolean hasNext() {
-        return nodes.hasNext();
+        return scoreNodes.hasNext();
     }
 
     /**
@@ -240,7 +261,7 @@
         /**
          * The underlying <code>Node</code> of this result row.
          */
-        private final NodeImpl node;
+        private NodeImpl node;
 
         /**
          * The score nodes associated with this row.
@@ -253,21 +274,13 @@
         private Value[] values;
 
         /**
-         * Set of select property <code>Name</code>s.
-         */
-        private Set propertySet;
-
-        /**
          * Creates a new <code>RowImpl</code> instance based on <code>node</code>.
          *
-         * @param score the score value for this result row
          * @param sn    the score nodes associated with this row.
-         * @param node  the underlying <code>Node</code> for this <code>Row</code>.
          */
-        RowImpl(float score, ScoreNode[] sn, NodeImpl node) {
-            this.score = score;
+        RowImpl(ScoreNode[] sn) {
             this.sn = sn;
-            this.node = node;
+            this.score = sn[0].getScore();
         }
 
         /**
@@ -283,11 +296,11 @@
             if (values == null) {
                 Value[] tmp = new Value[properties.length];
                 for (int i = 0; i < properties.length; i++) {
-                    if (node.hasProperty(properties[i])) {
-                        PropertyImpl prop = node.getProperty(properties[i]);
+                    if (getNodeImpl().hasProperty(properties[i])) {
+                        PropertyImpl prop = getNodeImpl().getProperty(properties[i]);
                         if (!prop.getDefinition().isMultiple()) {
                             if (prop.getDefinition().getRequiredType() == PropertyType.UNDEFINED) {
-                                tmp[i] = VALUE_FACTORY.createValue(prop.getString());
+                                tmp[i] = valueFactory.createValue(prop.getString());
                             } else {
                                 tmp[i] = prop.getValue();
                             }
@@ -299,9 +312,9 @@
                         // property not set or one of the following:
                         // jcr:path / jcr:score / rep:excerpt / rep:spellcheck
                         if (NameConstants.JCR_PATH.equals(properties[i])) {
-                            tmp[i] = VALUE_FACTORY.createValue(node.getPath(), PropertyType.PATH);
+                            tmp[i] = valueFactory.createValue(getNodeImpl().getPath(), PropertyType.PATH);
                         } else if (NameConstants.JCR_SCORE.equals(properties[i])) {
-                            tmp[i] = VALUE_FACTORY.createValue(Math.round(score * 1000f));
+                            tmp[i] = valueFactory.createValue(Math.round(score * 1000f));
                         } else if (isExcerptFunction(properties[i])) {
                             tmp[i] = getExcerpt();
                         } else if (isSpellCheckFunction(properties[i])) {
@@ -348,20 +361,21 @@
                         throw new ItemNotFoundException(propertyName);
                     }
                 }
-                if (node.hasProperty(prop)) {
-                    Property p = node.getProperty(prop);
+                if (NameConstants.JCR_PATH.equals(prop)) {
+                    QValue p = QVALUE_FACTORY.create(hmgr.getPath(sn[0].getNodeId()));
+                    return valueFactory.createValue(p);
+                } else if (getNodeImpl().hasProperty(prop)) {
+                    Property p = getNodeImpl().getProperty(prop);
                     if (p.getDefinition().getRequiredType() == PropertyType.UNDEFINED) {
-                        return VALUE_FACTORY.createValue(p.getString());
+                        return valueFactory.createValue(p.getString());
                     } else {
                         return p.getValue();
                     }
                 } else {
-                    // either jcr:score, jcr:path, rep:excerpt,
+                    // either jcr:score, rep:excerpt,
                     // rep:spellcheck or not set
-                    if (NameConstants.JCR_PATH.equals(prop)) {
-                        return VALUE_FACTORY.createValue(node.getPath(), PropertyType.PATH);
-                    } else if (NameConstants.JCR_SCORE.equals(prop)) {
-                        return VALUE_FACTORY.createValue(Math.round(score * 1000f));
+                    if (NameConstants.JCR_SCORE.equals(prop)) {
+                        return valueFactory.createValue(Math.round(score * 1000f));
                     } else if (isExcerptFunction(prop)) {
                         return getExcerpt();
                     } else if (isSpellCheckFunction(prop)) {
@@ -395,7 +409,7 @@
          */
         public Node getNode() throws RepositoryException {
             checkSingleSelector("Use getNode(String) instead.");
-            return node;
+            return getNodeImpl();
         }
 
         /**
@@ -430,7 +444,7 @@
          */
         public String getPath() throws RepositoryException {
             checkSingleSelector("Use getPath(String) instead.");
-            return node.getPath();
+            return resolver.getJCRPath(hmgr.getPath(sn[0].getNodeId()));
         }
 
         /**
@@ -510,6 +524,20 @@
         //-----------------------------< internal >-----------------------------
 
         /**
+         * Returns the node corresponding to this row.
+         *
+         * @return the node.
+         * @throws RepositoryException if an error occurs while retrieving the
+         *                             node. e.g. node does not exist anymore.
+         */
+        private NodeImpl getNodeImpl() throws RepositoryException {
+            if (node == null) {
+                node = (NodeImpl) itemMgr.getItem(sn[0].getNodeId());
+            }
+            return node;
+        }
+
+        /**
          * Checks if there is a single selector and otherwise throws a
          * RepositoryException.
          *
@@ -573,7 +601,7 @@
          *         created or an error occurs.
          */
         private Value getExcerpt() {
-            return createExcerpt(node.getNodeId());
+            return createExcerpt(sn[0].getNodeId());
         }
 
         /**
@@ -597,12 +625,12 @@
                     idx + EXCERPT_FUNC_LPAR.length(), end).trim();
             String decodedPath = ISO9075.decode(pathStr);
             try {
-                NodeImpl n = (NodeImpl) node.getNode(decodedPath);
+                NodeImpl n = (NodeImpl) getNodeImpl().getNode(decodedPath);
                 return createExcerpt(n.getNodeId());
             } catch (PathNotFoundException e) {
                 // does not exist or references a property
                 try {
-                    Property p = node.getProperty(decodedPath);
+                    Property p = getNode().getProperty(decodedPath);
                     return highlight(p.getValue().getString());
                 } catch (PathNotFoundException e1) {
                     // does not exist
@@ -627,7 +655,7 @@
                 time = System.currentTimeMillis() - time;
                 log.debug("Created excerpt in {} ms.", new Long(time));
                 if (excerpt != null) {
-                    return VALUE_FACTORY.createValue(excerpt);
+                    return valueFactory.createValue(excerpt);
                 } else {
                     return null;
                 }
@@ -652,7 +680,7 @@
                 text = hep.highlight(text);
                 time = System.currentTimeMillis() - time;
                 log.debug("Highlighted text in {} ms.", new Long(time));
-                return VALUE_FACTORY.createValue(text);
+                return valueFactory.createValue(text);
             } catch (IOException e) {
                 return null;
             }
@@ -686,7 +714,7 @@
                 }
             }
             if (v != null) {
-                return VALUE_FACTORY.createValue(v);
+                return valueFactory.createValue(v);
             } else {
                 return null;
             }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIterator.java?rev=758193&r1=758192&r2=758193&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIterator.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIterator.java Wed Mar 25 09:51:03 2009
@@ -16,45 +16,19 @@
  */
 package org.apache.jackrabbit.core.query.lucene;
 
-import org.apache.jackrabbit.core.NodeImpl;
-
-import javax.jcr.NodeIterator;
+import javax.jcr.RangeIterator;
 
 /**
- * Extends the {@link javax.jcr.NodeIterator} interface by adding a {@link
- * #getScore()} method that returns the score for the node that is returned by
- * {@link javax.jcr.NodeIterator#nextNode()}.
+ * A range iterator over {@link ScoreNode}[].
  */
-public interface ScoreNodeIterator extends NodeIterator {
-
-    /**
-     * Returns the score of the node returned by {@link #nextNode()}. In other
-     * words, this method returns the score value of the next
-     * <code>Node</code>.
-     *
-     * @return the score of the node returned by {@link #nextNode()}.
-     * @throws java.util.NoSuchElementException
-     *          if there is no next node.
-     */
-    float getScore();
+public interface ScoreNodeIterator extends RangeIterator {
 
     /**
-     * Returns the score nodes related to the node returned by
-     * {@link #nextNodeImpl()} but does not move the iterator forward.
+     * Returns the next score nodes.
      *
-     * @return the score nodes related to the {@link #nextNodeImpl()}.
+     * @return the next score nodes.
      * @throws java.util.NoSuchElementException
-     *          if there is no next node.
+     *          if there are no next score nodes.
      */
-    ScoreNode[] getScoreNodes();
-
-    /**
-     * Returns the next <code>Node</code> in the result set.
-     *
-     * @return the next <code>Node</code> in the result set.
-     * @throws java.util.NoSuchElementException
-     *          if iteration has no more <code>Node</code>s.
-     */
-    NodeImpl nextNodeImpl();
-
+    ScoreNode[] nextScoreNodes();
 }

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java?rev=758193&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java Wed Mar 25 09:51:03 2009
@@ -0,0 +1,42 @@
+/*
+ * 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.Collection;
+import java.util.Arrays;
+
+import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
+
+/**
+ * <code>ScoreNodeIteratorImpl</code> implements a {@link ScoreNodeIterator}
+ * over an array of {@link ScoreNode ScoreNode[]}.
+ */
+public class ScoreNodeIteratorImpl
+        extends RangeIteratorAdapter
+        implements ScoreNodeIterator {
+
+    public ScoreNodeIteratorImpl(ScoreNode[][] scoreNodes) {
+        super(Arrays.asList(scoreNodes));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ScoreNode[] nextScoreNodes() {
+        return (ScoreNode[]) next();
+    }
+}

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

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/QueryResultTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/QueryResultTest.java?rev=758193&r1=758192&r2=758193&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/QueryResultTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/QueryResultTest.java Wed Mar 25 09:51:03 2009
@@ -210,11 +210,11 @@
         QueryManager qm = superuser.getWorkspace().getQueryManager();
         String stmt = testPath + "/*[@" + propertyName1 + " > 1000]";
         QueryResult result = qm.createQuery(stmt, Query.XPATH).execute();
-        NodeIterator it = result.getNodes();
-        assertEquals("Wrong position", 0, it.getPosition());
+        assertEquals("Wrong position", 0, result.getNodes().getPosition());
+        assertEquals("Wrong position", 0, result.getRows().getPosition());
         stmt += " order by jcr:score()";
         result = qm.createQuery(stmt, Query.XPATH).execute();
-        it = result.getNodes();
-        assertEquals("Wrong position", 0, it.getPosition());
+        assertEquals("Wrong position", 0, result.getNodes().getPosition());
+        assertEquals("Wrong position", 0, result.getRows().getPosition());
     }
 }