Package org.jboss.dna.jcr

Source Code of org.jboss.dna.jcr.JcrQueryManager$XPathQueryResultRowIterator

/*
* JBoss DNA (http://www.jboss.org/dna)
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.  Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
* See the AUTHORS.txt file in the distribution for a full listing of
* individual contributors.
*
* JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
* is licensed to you under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* JBoss DNA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.dna.jcr;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
import net.jcip.annotations.Immutable;
import net.jcip.annotations.NotThreadSafe;
import org.jboss.dna.common.collection.Problem;
import org.jboss.dna.common.collection.Problems;
import org.jboss.dna.common.collection.Problem.Status;
import org.jboss.dna.common.text.ParsingException;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.common.util.StringUtil;
import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.property.NamespaceRegistry;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.ValueFactories;
import org.jboss.dna.graph.query.QueryResults;
import org.jboss.dna.graph.query.QueryResults.Columns;
import org.jboss.dna.graph.query.model.QueryCommand;
import org.jboss.dna.graph.query.model.TypeSystem;
import org.jboss.dna.graph.query.parse.QueryParser;
import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.validate.Schemata;

/**
* Place-holder implementation of {@link QueryManager} interface.
*/
@Immutable
class JcrQueryManager implements QueryManager {

    public static final int MAXIMUM_RESULTS_FOR_FULL_TEXT_SEARCH_QUERIES = Integer.MAX_VALUE;

    private final JcrSession session;

    JcrQueryManager( JcrSession session ) {
        this.session = session;
    }

    /**
     * {@inheritDoc}
     *
     * @see javax.jcr.query.QueryManager#createQuery(java.lang.String, java.lang.String)
     */
    public Query createQuery( String statement,
                              String language ) throws InvalidQueryException {
        CheckArg.isNotNull(statement, "statement");
        CheckArg.isNotNull(language, "language");
        return createQuery(statement, language, null);
    }

    /**
     * Creates a new JCR {@link Query} by specifying the query expression itself, the language in which the query is stated, the
     * {@link QueryCommand} representation and, optionally, the node from which the query was loaded. The language must be a
     * string from among those returned by {@code QueryManager#getSupportedQueryLanguages()}.
     *
     * @param expression the original query expression as supplied by the client; may not be null
     * @param language the language obtained from the {@link QueryParser}; may not be null
     * @param storedAtPath the path at which this query was stored, or null if this is not a stored query
     * @return query the JCR query object; never null
     * @throws InvalidQueryException if expression is invalid or language is unsupported
     */
    public Query createQuery( String expression,
                              String language,
                              Path storedAtPath ) throws InvalidQueryException {
        // Look for a parser for the specified language ...
        QueryParser parser = session.repository().queryParsers().getParserFor(language);
        if (parser == null) {
            Set<String> languages = session.repository().queryParsers().getLanguages();
            throw new InvalidQueryException(JcrI18n.invalidQueryLanguage.text(language, languages));
        }
        if (parser.getLanguage().equals(FullTextSearchParser.LANGUAGE)) {
            // This is a full-text search ...
            return new JcrSearch(this.session, expression, parser.getLanguage(), storedAtPath);
        }
        TypeSystem typeSystem = session.executionContext.getValueFactories().getTypeSystem();
        try {
            // Parsing must be done now ...
            QueryCommand command = parser.parseQuery(expression, typeSystem);
            if (command == null) {
                // The query is not well-formed and cannot be parsed ...
                throw new InvalidQueryException(JcrI18n.queryCannotBeParsedUsingLanguage.text(language, expression));
            }
            PlanHints hints = new PlanHints();
            hints.showPlan = true;
            // If using XPath, we need to add a few hints ...
            if (Query.XPATH.equals(language)) {
                hints.hasFullTextSearch = true; // requires 'jcr:score' to exist
            }
            return new JcrQuery(this.session, expression, parser.getLanguage(), command, hints, storedAtPath);
        } catch (ParsingException e) {
            // The query is not well-formed and cannot be parsed ...
            String reason = e.getMessage();
            throw new InvalidQueryException(JcrI18n.queryCannotBeParsedUsingLanguage.text(language, expression, reason));
        } catch (org.jboss.dna.graph.query.parse.InvalidQueryException e) {
            // The query was parsed, but there is an error in the query
            String reason = e.getMessage();
            throw new InvalidQueryException(JcrI18n.queryInLanguageIsNotValid.text(language, expression, reason));
        }
    }

    /**
     * {@inheritDoc}
     *
     * @see javax.jcr.query.QueryManager#getQuery(javax.jcr.Node)
     */
    public Query getQuery( Node node ) throws InvalidQueryException, RepositoryException {
        AbstractJcrNode jcrNode = CheckArg.getInstanceOf(node, AbstractJcrNode.class, "node");

        // Check the type of the node ...
        JcrNodeType nodeType = jcrNode.getPrimaryNodeType();
        if (!nodeType.getInternalName().equals(JcrNtLexicon.QUERY)) {
            NamespaceRegistry registry = session.getExecutionContext().getNamespaceRegistry();
            throw new InvalidQueryException(JcrI18n.notStoredQuery.text(jcrNode.path().getString(registry)));
        }

        // These are both mandatory properties for nodes of nt:query
        String statement = jcrNode.getProperty(JcrLexicon.STATEMENT).getString();
        String language = jcrNode.getProperty(JcrLexicon.LANGUAGE).getString();

        return createQuery(statement, language, jcrNode.path());
    }

    /**
     * {@inheritDoc}
     *
     * @see javax.jcr.query.QueryManager#getSupportedQueryLanguages()
     */
    public String[] getSupportedQueryLanguages() {
        // Make a defensive copy ...
        Set<String> languages = session.repository().queryParsers().getLanguages();
        return languages.toArray(new String[languages.size()]);
    }

    @NotThreadSafe
    protected static abstract class AbstractQuery implements Query {
        protected final JcrSession session;
        protected final String language;
        protected final String statement;
        private Path storedAtPath;

        /**
         * Creates a new JCR {@link Query} by specifying the query statement itself, the language in which the query is stated,
         * the {@link QueryCommand} representation and, optionally, the node from which the query was loaded. The language must be
         * a string from among those returned by {@code QueryManager#getSupportedQueryLanguages()}.
         *
         * @param session the session that was used to create this query and that will be used to execute this query; may not be
         *        null
         * @param statement the original statement as supplied by the client; may not be null
         * @param language the language obtained from the {@link QueryParser}; may not be null
         * @param storedAtPath the path at which this query was stored, or null if this is not a stored query
         */
        protected AbstractQuery( JcrSession session,
                                 String statement,
                                 String language,
                                 Path storedAtPath ) {
            assert session != null;
            assert statement != null;
            assert language != null;
            this.session = session;
            this.language = language;
            this.statement = statement;
            this.storedAtPath = storedAtPath;
        }

        protected final JcrSession session() {
            return this.session;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Query#getLanguage()
         */
        public String getLanguage() {
            return language;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Query#getStatement()
         */
        public String getStatement() {
            return statement;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Query#getStoredQueryPath()
         */
        public String getStoredQueryPath() throws ItemNotFoundException {
            if (storedAtPath == null) {
                throw new ItemNotFoundException(JcrI18n.notStoredQuery.text());
            }
            return storedAtPath.getString(session.getExecutionContext().getNamespaceRegistry());
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Query#storeAsNode(java.lang.String)
         */
        public Node storeAsNode( String absPath ) throws PathNotFoundException, ConstraintViolationException, RepositoryException {
            NamespaceRegistry namespaces = this.session.namespaces();

            Path path;
            try {
                path = session.getExecutionContext().getValueFactories().getPathFactory().create(absPath);
            } catch (IllegalArgumentException iae) {
                throw new RepositoryException(JcrI18n.invalidPathParameter.text("absPath", absPath));
            }
            Path parentPath = path.getParent();

            Node parentNode = session.getNode(parentPath);
            Node queryNode = parentNode.addNode(path.relativeTo(parentPath).getString(namespaces),
                                                JcrNtLexicon.QUERY.getString(namespaces));

            queryNode.setProperty(JcrLexicon.LANGUAGE.getString(namespaces), this.language);
            queryNode.setProperty(JcrLexicon.STATEMENT.getString(namespaces), this.statement);

            this.storedAtPath = path;

            return queryNode;
        }

        protected void checkForProblems( Problems problems ) throws RepositoryException {
            if (problems.hasErrors()) {
                // Build a message with the problems ...
                StringBuilder msg = new StringBuilder();
                for (Problem problem : problems) {
                    if (problem.getStatus() != Status.ERROR) continue;
                    msg.append(problem.getMessageString()).append("\n");
                }
                throw new RepositoryException(msg.toString());
            }
        }
    }

    /**
     * Implementation of {@link Query} that represents a {@link QueryCommand} query.
     */
    @NotThreadSafe
    protected static class JcrQuery extends AbstractQuery {
        private final QueryCommand query;
        private final PlanHints hints;
        private final Map<String, Object> variables;

        /**
         * Creates a new JCR {@link Query} by specifying the query statement itself, the language in which the query is stated,
         * the {@link QueryCommand} representation and, optionally, the node from which the query was loaded. The language must be
         * a string from among those returned by {@code QueryManager#getSupportedQueryLanguages()}.
         *
         * @param session the session that was used to create this query and that will be used to execute this query; may not be
         *        null
         * @param statement the original statement as supplied by the client; may not be null
         * @param language the language obtained from the {@link QueryParser}; may not be null
         * @param query the parsed query representation; may not be null
         * @param hints any hints that are to be used; may be null if there are no hints
         * @param storedAtPath the path at which this query was stored, or null if this is not a stored query
         */
        protected JcrQuery( JcrSession session,
                            String statement,
                            String language,
                            QueryCommand query,
                            PlanHints hints,
                            Path storedAtPath ) {
            super(session, statement, language, storedAtPath);
            assert query != null;
            this.query = query;
            this.hints = hints;
            this.variables = null;
        }

        /**
         * Get the underlying and immutable Abstract Query Model representation of this query.
         *
         * @return the AQM representation; never null
         */
        public QueryCommand getAbstractQueryModel() {
            return query;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Query#execute()
         */
        public QueryResult execute() throws RepositoryException {
            // Submit immediately to the workspace graph ...
            Schemata schemata = session.workspace().nodeTypeManager().schemata();
            QueryResults result = session.repository().queryManager().query(session.workspace().getName(),
                                                                            query,
                                                                            schemata,
                                                                            hints,
                                                                            variables);
            checkForProblems(result.getProblems());
            if (Query.XPATH.equals(language)) {
                return new XPathQueryResult(session, result);
            }
            return new JcrQueryResult(session, result);
        }

        /**
         * {@inheritDoc}
         *
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return language + " -> " + statement + "\n" + StringUtil.createString(' ', Math.min(language.length() - 3, 0))
                   + "AQM -> " + query;
        }
    }

    @NotThreadSafe
    protected static class JcrSearch extends AbstractQuery {

        /**
         * Creates a new JCR {@link Query} by specifying the query statement itself, the language in which the query is stated,
         * the {@link QueryCommand} representation and, optionally, the node from which the query was loaded. The language must be
         * a string from among those returned by {@code QueryManager#getSupportedQueryLanguages()}.
         *
         * @param session the session that was used to create this query and that will be used to execute this query; may not be
         *        null
         * @param statement the original statement as supplied by the client; may not be null
         * @param language the language obtained from the {@link QueryParser}; may not be null
         * @param storedAtPath the path at which this query was stored, or null if this is not a stored query
         */
        protected JcrSearch( JcrSession session,
                             String statement,
                             String language,
                             Path storedAtPath ) {
            super(session, statement, language, storedAtPath);
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Query#execute()
         */
        public QueryResult execute() throws RepositoryException {
            // Submit immediately to the workspace graph ...
            QueryResults result = session.repository().queryManager().search(session.workspace().getName(),
                                                                             statement,
                                                                             MAXIMUM_RESULTS_FOR_FULL_TEXT_SEARCH_QUERIES,
                                                                             0);
            checkForProblems(result.getProblems());
            return new JcrQueryResult(session, result);
        }

        /**
         * {@inheritDoc}
         *
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return language + " -> " + statement;
        }
    }

    protected static final String JCR_SCORE_COLUMN_NAME = "jcr:score";
    protected static final String JCR_PATH_COLUMN_NAME = "jcr:path";

    /**
     * The results of a query. This is not thread-safe because it relies upon JcrSession, which is not thread-safe. Also, although
     * the results of a query never change, the objects returned by the iterators may vary if the session information changes.
     */
    @NotThreadSafe
    protected static class JcrQueryResult implements QueryResult {
        protected final JcrSession session;
        protected final QueryResults results;

        protected JcrQueryResult( JcrSession session,
                                  QueryResults graphResults ) {
            this.session = session;
            this.results = graphResults;
            assert this.session != null;
            assert this.results != null;
        }

        protected QueryResults results() {
            return results;
        }

        public List<String> getColumnNameList() {
            return results.getColumns().getColumnNames();
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.QueryResult#getColumnNames()
         */
        public String[] getColumnNames() /*throws RepositoryException*/{
            List<String> names = getColumnNameList();
            return names.toArray(new String[names.size()]); // make a defensive copy ...
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.QueryResult#getNodes()
         */
        public NodeIterator getNodes() throws RepositoryException {
            // Find all of the nodes in the results. We have to do this pre-emptively, since this
            // is the only method to throw RepositoryException ...
            final int numRows = results.getRowCount();
            if (numRows == 0) return new JcrEmptyNodeIterator();

            final List<AbstractJcrNode> nodes = new ArrayList<AbstractJcrNode>(numRows);
            final String selectorName = results.getColumns().getSelectorNames().get(0);
            final int locationIndex = results.getColumns().getLocationIndex(selectorName);
            for (Object[] tuple : results.getTuples()) {
                Location location = (Location)tuple[locationIndex];
                nodes.add(session.getNode(location.getPath()));
            }
            return new QueryResultNodeIterator(nodes);
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.QueryResult#getRows()
         */
        public RowIterator getRows() /*throws RepositoryException*/{
            // We can actually delay the loading of the nodes until the rows are accessed ...
            final int numRows = results.getRowCount();
            final List<Object[]> tuples = results.getTuples();
            return new QueryResultRowIterator(session, results.getColumns(), tuples.iterator(), numRows);
        }

        /**
         * Get a description of the query plan, if requested.
         *
         * @return the query plan, or null if the plan was not requested
         */
        public String getPlan() {
            return results.getPlan();
        }

        /**
         * {@inheritDoc}
         *
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return results.toString();
        }
    }

    /**
     * The {@link NodeIterator} implementation returned by the {@link JcrQueryResult}.
     *
     * @see JcrQueryResult#getNodes()
     */
    @NotThreadSafe
    protected static class QueryResultNodeIterator implements NodeIterator {
        private final Iterator<? extends Node> nodes;
        private final int size;
        private long position = 0L;

        protected QueryResultNodeIterator( List<? extends Node> nodes ) {
            this.nodes = nodes.iterator();
            this.size = nodes.size();
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.NodeIterator#nextNode()
         */
        public Node nextNode() {
            Node node = nodes.next();
            ++position;
            return node;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.RangeIterator#getPosition()
         */
        public long getPosition() {
            return position;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.RangeIterator#getSize()
         */
        public long getSize() {
            return size;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.RangeIterator#skip(long)
         */
        public void skip( long skipNum ) {
            for (long i = 0L; i != skipNum; ++i)
                nextNode();
        }

        /**
         * {@inheritDoc}
         *
         * @see java.util.Iterator#hasNext()
         */
        public boolean hasNext() {
            return nodes.hasNext();
        }

        /**
         * {@inheritDoc}
         *
         * @see java.util.Iterator#next()
         */
        public Object next() {
            return nextNode();
        }

        /**
         * {@inheritDoc}
         *
         * @see java.util.Iterator#remove()
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

    /**
     * The {@link RowIterator} implementation returned by the {@link JcrQueryResult}.
     *
     * @see JcrQueryResult#getRows()
     */
    @NotThreadSafe
    protected static class QueryResultRowIterator implements RowIterator {
        protected final List<String> columnNames;
        private final Iterator<Object[]> tuples;
        protected final int locationIndex;
        protected final int scoreIndex;
        protected final JcrSession session;
        private long position = 0L;
        private final long numRows;

        protected QueryResultRowIterator( JcrSession session,
                                          Columns columns,
                                          Iterator<Object[]> tuples,
                                          long numRows ) {
            this.tuples = tuples;
            this.columnNames = columns.getColumnNames();
            String selectorName = columns.getSelectorNames().get(0);
            this.locationIndex = columns.getLocationIndex(selectorName);
            this.scoreIndex = columns.getFullTextSearchScoreIndexFor(selectorName);
            this.session = session;
            this.numRows = numRows;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.RowIterator#nextRow()
         */
        public Row nextRow() {
            final Object[] tuple = tuples.next();
            ++position;
            return createRow(tuple);
        }

        protected Row createRow( final Object[] tuple ) {
            return new QueryResultRow(this, tuple);
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.RangeIterator#getPosition()
         */
        public long getPosition() {
            return position;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.RangeIterator#getSize()
         */
        public long getSize() {
            return numRows;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.RangeIterator#skip(long)
         */
        public void skip( long skipNum ) {
            for (long i = 0L; i != skipNum; ++i) {
                tuples.next();
            }
            position += skipNum;
        }

        /**
         * {@inheritDoc}
         *
         * @see java.util.Iterator#hasNext()
         */
        public boolean hasNext() {
            return tuples.hasNext();
        }

        /**
         * {@inheritDoc}
         *
         * @see java.util.Iterator#next()
         */
        public Object next() {
            return nextRow();
        }

        /**
         * {@inheritDoc}
         *
         * @see java.util.Iterator#remove()
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

    protected static class QueryResultRow implements Row {
        protected final QueryResultRowIterator iterator;
        protected final Object[] tuple;
        private Node node = null;
        private Value[] values = null;

        protected QueryResultRow( QueryResultRowIterator iterator,
                                  Object[] tuple ) {
            this.iterator = iterator;
            this.tuple = tuple;
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Row#getValue(java.lang.String)
         */
        public Value getValue( String columnName ) throws ItemNotFoundException, RepositoryException {
            return node().getProperty(columnName).getValue();
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Row#getValues()
         */
        public Value[] getValues() throws RepositoryException {
            if (values == null) {
                int i = 0;
                values = new Value[iterator.columnNames.size()];
                for (String columnName : iterator.columnNames) {
                    values[i++] = getValue(columnName);
                }
            }
            return values;
        }

        /**
         * Load the node. The properties are <i>always</i> fetched from the session to ensure that any modifications to the nodes
         * within session are always used.
         *
         * @return the node
         * @throws RepositoryException if the node could not be found
         */
        protected final Node node() throws RepositoryException {
            if (node == null) {
                Location location = (Location)tuple[iterator.locationIndex];
                node = iterator.session.getNode(location.getPath());
            }
            return node;
        }
    }

    protected static class XPathQueryResult extends JcrQueryResult {
        private final List<String> columnNames;

        protected XPathQueryResult( JcrSession session,
                                    QueryResults graphResults ) {
            super(session, graphResults);
            List<String> columnNames = new LinkedList<String>(graphResults.getColumns().getColumnNames());
            if (graphResults.getColumns().hasFullTextSearchScores() && !columnNames.contains(JCR_SCORE_COLUMN_NAME)) {
                columnNames.add(0, JCR_SCORE_COLUMN_NAME);
            }
            columnNames.add(0, JCR_PATH_COLUMN_NAME);
            this.columnNames = Collections.unmodifiableList(columnNames);
        }

        /**
         * {@inheritDoc}
         *
         * @see org.jboss.dna.jcr.JcrQueryManager.JcrQueryResult#getColumnNameList()
         */
        @Override
        public List<String> getColumnNameList() {
            return columnNames;
        }

        /**
         * {@inheritDoc}
         *
         * @see org.jboss.dna.jcr.JcrQueryManager.JcrQueryResult#getRows()
         */
        @Override
        public RowIterator getRows() {
            final int numRows = results.getRowCount();
            final List<Object[]> tuples = results.getTuples();
            return new XPathQueryResultRowIterator(session, results.getColumns(), tuples.iterator(), numRows);
        }
    }

    protected static class XPathQueryResultRowIterator extends QueryResultRowIterator {
        private final ValueFactories factories;
        private final SessionCache cache;

        protected XPathQueryResultRowIterator( JcrSession session,
                                               Columns columns,
                                               Iterator<Object[]> tuples,
                                               long numRows ) {
            super(session, columns, tuples, numRows);
            factories = session.executionContext.getValueFactories();
            cache = session.cache();
        }

        @Override
        protected Row createRow( final Object[] tuple ) {
            return new XPathQueryResultRow(this, tuple);
        }

        protected Value jcrPath( Path path ) {
            return new JcrValue(factories, cache, PropertyType.PATH, path);
        }

        protected Value jcrScore( Float score ) {
            return new JcrValue(factories, cache, PropertyType.DOUBLE, score);
        }
    }

    protected static class XPathQueryResultRow extends QueryResultRow {
        protected XPathQueryResultRow( XPathQueryResultRowIterator iterator,
                                       Object[] tuple ) {
            super(iterator, tuple);
        }

        /**
         * {@inheritDoc}
         *
         * @see javax.jcr.query.Row#getValue(java.lang.String)
         */
        @Override
        public Value getValue( String columnName ) throws ItemNotFoundException, RepositoryException {
            if (JCR_PATH_COLUMN_NAME.equals(columnName)) {
                Location location = (Location)tuple[iterator.locationIndex];
                return ((XPathQueryResultRowIterator)iterator).jcrPath(location.getPath());
            }
            if (JCR_SCORE_COLUMN_NAME.equals(columnName)) {
                Float score = (Float)tuple[iterator.scoreIndex];
                return ((XPathQueryResultRowIterator)iterator).jcrScore(score);
            }
            return super.getValue(columnName);
        }
    }
}
TOP

Related Classes of org.jboss.dna.jcr.JcrQueryManager$XPathQueryResultRowIterator

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.