Package org.exoplatform.services.jcr.impl.core.query.lucene

Source Code of org.exoplatform.services.jcr.impl.core.query.lucene.NodeIteratorImpl

/*
* 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.exoplatform.services.jcr.impl.core.query.lucene;

import java.util.NoSuchElementException;

import javax.jcr.Node;
import javax.jcr.RepositoryException;

import org.exoplatform.services.log.Log;

import org.exoplatform.services.jcr.impl.core.NodeImpl;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
import org.exoplatform.services.log.ExoLogger;

/**
* Implements a {@link javax.jcr.NodeIterator} returned by
* {@link javax.jcr.query.QueryResult#getNodes()}.
*/
class NodeIteratorImpl
   implements TwoWayRangeIterator, ScoreNodeIterator
{

   /** Logger instance for this class */
   private static final Log log = ExoLogger.getLogger(NodeIteratorImpl.class);

   /** The node ids of the nodes in the result set with their score value */
   protected final ScoreNode[] scoreNodes;

   /** ItemManager to turn UUIDs into Node instances */
   protected final SessionDataManager itemMgr;

   /** Current position in the UUID array */
   protected int pos = -1;

   /** Number of invalid nodes */
   protected int invalid = 0;

   /** Reference to the next node instance */
   private NodeImpl next;

   /**
    * 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.
    */
   NodeIteratorImpl(SessionDataManager itemMgr, ScoreNode[] scoreNodes)
   {
      this.itemMgr = itemMgr;
      this.scoreNodes = scoreNodes;
      fetchNext();
   }

   /**
    * 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 Node nextNode() throws NoSuchElementException
   {
      return nextNodeImpl();
   }

   /**
    * 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 Object next() throws NoSuchElementException
   {
      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;
         fetchNext();
      }
   }

   public void skipBack(long skipNum)
   {

      if (skipNum < 0)
      {
         throw new IllegalArgumentException("skipNum must not be negative");
      }
      if ((pos - skipNum) < 0)
      {
         throw new NoSuchElementException();
      }
      if (skipNum > 0)
      {
         pos -= skipNum + 1;
         fetchNext();
      }
   }

   /**
    * Returns the number of nodes in this iterator. </p> Note: The number returned by this method may
    * differ from the number of nodes actually returned by calls to hasNext() / getNextNode()! This
    * is because this iterator works on a lazy instantiation basis and while iterating over the nodes
    * some of them might have been deleted in the meantime. Those will not be returned by
    * getNextNode(). As soon as an invalid node is detected, the size of this iterator is adjusted.
    *
    * @return the number of node in this iterator.
    */
   public long getSize()
   {
      return scoreNodes.length - invalid;
   }

   /**
    * Returns the current position in this <code>NodeIterator</code>.
    *
    * @return the current position in this <code>NodeIterator</code>.
    */
   public long getPosition()
   {
      return pos - invalid;
   }

   /**
    * Returns <code>true</code> if there is another <code>Node</code> available; <code>false</code>
    * otherwise.
    *
    * @return <code>true</code> if there is another <code>Node</code> available; <code>false</code>
    *         otherwise.
    */
   public boolean hasNext()
   {
      return next != null;
   }

   /**
    * @throws UnsupportedOperationException
    *           always.
    */
   public void remove()
   {
      throw new UnsupportedOperationException("remove");
   }

   /**
    * 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].getScore();
   }

   /**
    * 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 method returns, then there are no more valid element in this iterator.
    */
   protected void fetchNext()
   {
      // reset
      next = null;
      while (next == null && (pos + 1) < scoreNodes.length)
      {
         try
         {
            next = (NodeImpl) itemMgr.getItemByIdentifier(scoreNodes[pos + 1].getNodeId(), true);
            if (next == null)
            {
               invalid++;
               pos++;
            }
         }
         catch (RepositoryException e)
         {
            log.warn("Exception retrieving Node with UUID: " + scoreNodes[pos + 1].getNodeId() + ": " + e.toString());
            // try next
            invalid++;
            pos++;
         }
      }
      pos++;
   }
}
TOP

Related Classes of org.exoplatform.services.jcr.impl.core.query.lucene.NodeIteratorImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.