org.apache.jackrabbit.jcr2spi.query.NodeIteratorImpl Maven / Gradle / Ivy
/*
* 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.jcr2spi.query;
import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.RangeIterator;
import org.apache.jackrabbit.jcr2spi.ItemManager;
import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.QueryInfo;
import org.apache.jackrabbit.spi.QueryResultRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Implements a {@link javax.jcr.NodeIterator} returned by
* {@link javax.jcr.query.QueryResult#getNodes()}.
*/
public class NodeIteratorImpl implements ScoreNodeIterator {
/** Logger instance for this class */
private static final Logger log = LoggerFactory.getLogger(NodeIteratorImpl.class);
/** ItemManager to turn Ids into Node instances */
private final ItemManager itemMgr;
/** */
private final HierarchyManager hierarchyMgr;
/** The QueryResultRows */
private final RangeIterator rows;
/** Current position of this node iterator */
private int pos = -1;
/** Number of invalid nodes */
private int invalid = 0;
/** Id of the next Node */
private NodeId nextId;
/** Reference to the next node instance */
private Node next;
/** Score for the next node */
private double nextScore;
/**
* Creates a new NodeIteratorImpl
instance.
*
* @param itemMgr The ItemManager
to build Node
instances.
* @param hierarchyMgr The HierarchyManager
used to retrieve the
* HierarchyEntry objects from the ids returned by the query.
* @param queryInfo the query result.
*/
public NodeIteratorImpl(ItemManager itemMgr, HierarchyManager hierarchyMgr,
QueryInfo queryInfo) {
this.itemMgr = itemMgr;
this.hierarchyMgr = hierarchyMgr;
this.rows = queryInfo.getRows();
fetchNext();
}
//------------------------------------------------------< ScoreIterator >---
/**
* Returns the score of the node returned by {@link #nextNode()}. In other
* words, this method returns the score value of the next Node
.
*
* @return the score of the node returned by {@link #nextNode()}.
* @throws NoSuchElementException if there is no next node.
* @see ScoreNodeIterator#getScore()
*/
public double getScore() throws NoSuchElementException {
if (!hasNext()) {
throw new NoSuchElementException();
}
return nextScore;
}
//-------------------------------------------------------< NodeIterator >---
/**
* Returns the next Node
in the result set.
*
* @return the next Node
in the result set.
* @throws NoSuchElementException if iteration has no more Node
s.
* @see javax.jcr.NodeIterator#nextNode()
*/
public Node nextNode() throws NoSuchElementException {
if (next == null) {
throw new NoSuchElementException();
}
Node n = next;
fetchNext();
return n;
}
//------------------------------------------------------< RangeIterator >---
/**
* Skip a number of Node
s in this iterator.
*
* @param skipNum the non-negative number of Node
s to skip
* @throws NoSuchElementException if skipped past the last Node
* in this iterator.
* @see javax.jcr.NodeIterator#skip(long)
*/
public void skip(long skipNum) throws NoSuchElementException {
if (skipNum < 0) {
throw new IllegalArgumentException("skipNum must not be negative");
}
if (skipNum == 0) {
// do nothing
} else {
rows.skip(skipNum - 1);
pos += skipNum - 1;
fetchNext();
}
}
/**
* Returns the number of nodes in this iterator.
*
* 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.
* @see javax.jcr.RangeIterator#getSize()
*/
public long getSize() {
if (rows.getSize() != -1) {
return rows.getSize() - invalid;
} else {
return -1;
}
}
/**
* Returns the current position in this NodeIterator
.
*
* @return the current position in this NodeIterator
.
* @see javax.jcr.RangeIterator#getPosition()
*/
public long getPosition() {
return pos - invalid;
}
/**
* Returns the next Node
in the result set.
*
* @return the next Node
in the result set.
* @throws NoSuchElementException if iteration has no more Node
s.
* @see java.util.Iterator#next()
*/
public Object next() throws NoSuchElementException {
return nextNode();
}
/**
* Returns true
if there is another Node
* available; false
otherwise.
*
* @return true
if there is another Node
* available; false
otherwise.
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return next != null;
}
/**
* @throws UnsupportedOperationException always.
* @see Iterator#remove()
*/
public void remove() {
throw new UnsupportedOperationException("remove");
}
//------------------------------------------------------------< private >---
/**
* 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.
*/
private void fetchNext() {
// reset
next = null;
nextScore = 0;
while (next == null && rows.hasNext()) {
try {
QueryResultRow row = (QueryResultRow) rows.next();
nextId = row.getNodeId(null);
Item tmp = itemMgr.getItem(hierarchyMgr.getNodeEntry(nextId));
if (tmp.isNode()) {
next = (Node) tmp;
nextScore = row.getScore(null);
} else {
log.warn("Item with Id is not a Node: " + nextId);
// try next
invalid++;
pos++;
}
} catch (Exception e) {
log.warn("Exception retrieving Node with Id: " + nextId);
// try next
invalid++;
pos++;
}
}
pos++;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy