All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jackrabbit.jcr2spi.query.RowIteratorImpl 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.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;

import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.RangeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;

import org.apache.jackrabbit.spi.QValue;
import org.apache.jackrabbit.spi.QueryInfo;
import org.apache.jackrabbit.spi.QueryResultRow;
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.commons.conversion.NameException;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.spi.commons.value.ValueFormat;
import org.apache.jackrabbit.jcr2spi.ItemManager;
import org.apache.jackrabbit.jcr2spi.hierarchy.HierarchyManager;

/**
 * Implements the {@link javax.jcr.query.RowIterator} interface returned by
 * a {@link javax.jcr.query.QueryResult}.
 */
class RowIteratorImpl implements RowIterator {

    /**
     * The result rows from the SPI implementation.
     */
    private final RangeIterator rows;

    /**
     * The column names.
     */
    private final String[] columnNames;

    /**
     * The NamePathResolver of the user Session.
     */
    private final NamePathResolver resolver;

    /**
     * The JCR value factory.
     */
    private final ValueFactory vFactory;

    /**
     * The item manager.
     */
    private final ItemManager itemMgr;

    /**
     * The hierarchy manager.
     */
    private final HierarchyManager hmgr;

    /**
     * Creates a new RowIteratorImpl that iterates over the result
     * nodes.
     *
     * @param queryInfo the query info.
     * @param resolver  NameResolver of the user
     *                  Session.
     * @param vFactory  the JCR value factory.
     * @param itemMgr   the item manager.
     * @param hmgr      the hierarchy manager.
     */
    RowIteratorImpl(QueryInfo queryInfo, NamePathResolver resolver,
                    ValueFactory vFactory, ItemManager itemMgr,
                    HierarchyManager hmgr) {
        this.rows = queryInfo.getRows();
        this.columnNames = queryInfo.getColumnNames();
        this.resolver = resolver;
        this.vFactory = vFactory;
        this.itemMgr = itemMgr;
        this.hmgr = hmgr;
    }

    //--------------------------------------------------------< RowIterator >---
    /**
     * Returns the next Row in the iteration.
     *
     * @return the next Row in the iteration.
     * @throws NoSuchElementException if iteration has no more Rows.
     * @see RowIterator#nextRow()
     */
    public Row nextRow() throws NoSuchElementException {
        return new RowImpl((QueryResultRow) rows.next());
    }

    //------------------------------------------------------< RangeIterator >---
    /**
     * Skip a number of Rows in this iterator.
     *
     * @param skipNum the non-negative number of Rows to skip
     * @throws NoSuchElementException if skipped past the last Row
     * in this iterator.
     * @see javax.jcr.RangeIterator#skip(long)
     */
    public void skip(long skipNum) throws NoSuchElementException {
        rows.skip(skipNum);
    }

    /**
     * Returns the number of Rows in this iterator.
     *
     * @return the number of Rows in this iterator.
     * @see RangeIterator#getSize()
     */
    public long getSize() {
        return rows.getSize();
    }

    /**
     * Returns the current position within this iterator. The number
     * returned is the 0-based index of the next Row in the iterator,
     * i.e. the one that will be returned on the subsequent next call.
     * 

* Note that this method does not check if there is a next element, * i.e. an empty iterator will always return 0. * * @return the current position withing this iterator. * @see RangeIterator#getPosition() */ public long getPosition() { return rows.getPosition(); } /** * @throws UnsupportedOperationException always. * @see Iterator#remove() */ public void remove() { throw new UnsupportedOperationException("remove"); } /** * Returns true if the iteration has more Rows. * (In other words, returns true if next would * return an Row rather than throwing an exception.) * * @return true if the iterator has more elements. * @see Iterator#hasNext() */ public boolean hasNext() { return rows.hasNext(); } /** * Returns the next Row in the iteration. * * @return the next Row in the iteration. * @throws NoSuchElementException if iteration has no more Rows. * @see Iterator#next() */ public Object next() throws NoSuchElementException { return nextRow(); } //---------------------< inner class RowImpl >------------------------------ /** * Implements the {@link javax.jcr.query.Row} interface, which represents * a row in the query result. */ class RowImpl implements Row { /** * The underlying QueryResultRow. */ private final QueryResultRow row; /** * Cached value array for returned by {@link #getValues()}. */ private Value[] values; /** * Map of select property names. Key: String, Value: * Integer, which refers to the array index in {@link #values}. */ private Map propertyMap; /** * Creates a new RowImpl instance based on a SPI result * row. * * @param row the underlying query result row */ private RowImpl(QueryResultRow row) { this.row = row; } //------------------------------------------------------------< Row >--- /** * Returns an array of all the values in the same order as the property * names (column names) returned by * {@link javax.jcr.query.QueryResult#getColumnNames()}. * * @return a Value array. * @throws RepositoryException if an error occurs while retrieving the * values from the Node. * @see Row#getValues() */ public Value[] getValues() throws RepositoryException { if (values == null) { QValue[] qVals = row.getValues(); Value[] tmp = new Value[qVals.length]; for (int i = 0; i < qVals.length; i++) { if (qVals[i] == null) { tmp[i] = null; } else { tmp[i] = ValueFormat.getJCRValue( qVals[i], resolver, vFactory); } } values = tmp; } // return a copy of the array Value[] ret = new Value[values.length]; System.arraycopy(values, 0, ret, 0, values.length); return ret; } /** * Returns the value of the indicated property in this Row. *

* If propertyName is not among the column names of the * query result table, an ItemNotFoundException is thrown. * * @return a Value * @throws ItemNotFoundException if propertyName is not * among the column names of the query result table. * @throws RepositoryException if propertyName is not a * valid property name. * @see Row#getValue(String) */ public Value getValue(String propertyName) throws ItemNotFoundException, RepositoryException { if (propertyMap == null) { // create the map first Map tmp = new HashMap(); for (int i = 0; i < columnNames.length; i++) { tmp.put(columnNames[i], i); } propertyMap = tmp; } try { Integer idx = propertyMap.get(propertyName); if (idx == null) { throw new ItemNotFoundException(propertyName); } // make sure values are there if (values == null) { getValues(); } return values[idx]; } catch (NameException e) { throw new RepositoryException(e.getMessage(), e); } } /** * @see Row#getNode() */ public Node getNode() throws RepositoryException { return getNode(row.getNodeId(null)); } /** * @see Row#getNode(String) */ public Node getNode(String selectorName) throws RepositoryException { return getNode(row.getNodeId(selectorName)); } /** * @see Row#getPath() */ public String getPath() throws RepositoryException { String path = null; Node n = getNode(); if (n != null) { path = n.getPath(); } return path; } /** * @see Row#getPath(String) */ public String getPath(String selectorName) throws RepositoryException { String path = null; Node n = getNode(selectorName); if (n != null) { path = n.getPath(); } return path; } /** * @see Row#getScore() */ public double getScore() throws RepositoryException { return row.getScore(null); } /** * @see Row#getScore(String) */ public double getScore(String selectorName) throws RepositoryException { return row.getScore(selectorName); } /** * Returns the node with the given id or null * if id is null. * * @param id a node id or null. * @return the node with the given id or null. * @throws RepositoryException if an error occurs while retrieving the * node. */ private Node getNode(NodeId id) throws RepositoryException { Node node = null; if (id != null) { node = (Node) itemMgr.getItem(hmgr.getNodeEntry(id)); } return node; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy