Package org.jboss.dna.graph.query

Source Code of org.jboss.dna.graph.query.QueryEngine

/*
* 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.graph.query;

import java.util.List;
import net.jcip.annotations.ThreadSafe;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.query.QueryResults.Statistics;
import org.jboss.dna.graph.query.model.Column;
import org.jboss.dna.graph.query.model.Constraint;
import org.jboss.dna.graph.query.model.QueryCommand;
import org.jboss.dna.graph.query.optimize.Optimizer;
import org.jboss.dna.graph.query.optimize.RuleBasedOptimizer;
import org.jboss.dna.graph.query.plan.CanonicalPlanner;
import org.jboss.dna.graph.query.plan.PlanHints;
import org.jboss.dna.graph.query.plan.PlanNode;
import org.jboss.dna.graph.query.plan.Planner;
import org.jboss.dna.graph.query.plan.PlanNode.Property;
import org.jboss.dna.graph.query.plan.PlanNode.Traversal;
import org.jboss.dna.graph.query.plan.PlanNode.Type;
import org.jboss.dna.graph.query.process.Processor;
import org.jboss.dna.graph.query.process.QueryResultColumns;
import org.jboss.dna.graph.query.validate.Schemata;

/**
* A query engine that is able to execute formal queries expressed in the Graph API's {@link QueryCommand Abstract Query Model}.
*/
@ThreadSafe
public class QueryEngine implements Queryable {

    private final Planner planner;
    private final Optimizer optimizer;
    private final Processor processor;

    /**
     * Create a new query engine given the {@link Planner planner}, {@link Optimizer optimizer}, {@link Processor processor}, and
     * {@link Schemata schemata}.
     *
     * @param planner the planner that should be used to generate canonical query plans for the queries; may be null if the
     *        {@link CanonicalPlanner} should be used
     * @param optimizer the optimizer that should be used to optimize the canonical query plan; may be null if the
     *        {@link RuleBasedOptimizer} should be used
     * @param processor the processor implementation that should be used to process the planned query and return the results
     * @throws IllegalArgumentException if the processor reference is null
     */
    public QueryEngine( Planner planner,
                        Optimizer optimizer,
                        Processor processor ) {
        CheckArg.isNotNull(processor, "processor");
        this.planner = planner != null ? planner : new CanonicalPlanner();
        this.optimizer = optimizer != null ? optimizer : new RuleBasedOptimizer();
        this.processor = processor;
    }

    /**
     * {@inheritDoc}
     *
     * @see org.jboss.dna.graph.query.Queryable#execute(org.jboss.dna.graph.query.QueryContext,
     *      org.jboss.dna.graph.query.model.QueryCommand)
     */
    public QueryResults execute( QueryContext context,
                                 QueryCommand query ) {
        CheckArg.isNotNull(context, "context");
        CheckArg.isNotNull(query, "query");

        // Create the canonical plan ...
        long start = System.nanoTime();
        PlanNode plan = planner.createPlan(context, query);
        long duration = System.nanoTime() - start;
        Statistics stats = new Statistics(duration);

        QueryResultColumns resultColumns = QueryResultColumns.empty();
        if (!context.getProblems().hasErrors()) {
            // Optimize the plan ...
            start = System.nanoTime();
            PlanNode optimizedPlan = optimizer.optimize(context, plan);
            duration = System.nanoTime() - start;
            stats = stats.withOptimizationTime(duration);

            // Find the query result columns ...
            start = System.nanoTime();
            resultColumns = determineQueryResultColumns(optimizedPlan, context.getHints());
            duration = System.nanoTime() - start;
            stats = stats.withOptimizationTime(duration);

            if (!context.getProblems().hasErrors()) {
                // Execute the plan ...
                try {
                    start = System.nanoTime();
                    return processor.execute(context, query, stats, optimizedPlan);
                } finally {
                    duration = System.nanoTime() - start;
                    stats = stats.withOptimizationTime(duration);
                }
            }
        }
        // There were problems somewhere ...
        return new org.jboss.dna.graph.query.process.QueryResults(resultColumns, stats, context.getProblems());
    }

    protected QueryResultColumns determineQueryResultColumns( PlanNode optimizedPlan,
                                                              PlanHints hints ) {
        // Look for which columns to include in the results; this will be defined by the highest PROJECT node ...
        PlanNode project = optimizedPlan.findAtOrBelow(Traversal.LEVEL_ORDER, Type.PROJECT);
        if (project != null) {
            List<Column> columns = project.getPropertyAsList(Property.PROJECT_COLUMNS, Column.class);
            // Determine whether to include the full-text search scores in the results ...
            boolean includeFullTextSearchScores = hints.hasFullTextSearch;
            if (!includeFullTextSearchScores) {
                for (PlanNode select : optimizedPlan.findAllAtOrBelow(Type.SELECT)) {
                    Constraint constraint = select.getProperty(Property.SELECT_CRITERIA, Constraint.class);
                    if (QueryResultColumns.includeFullTextScores(constraint)) {
                        includeFullTextSearchScores = true;
                        break;
                    }
                }
            }
            return new QueryResultColumns(columns, includeFullTextSearchScores);
        }
        return QueryResultColumns.empty();
    }

}
TOP

Related Classes of org.jboss.dna.graph.query.QueryEngine

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.