Package org.jboss.dna.jcr

Source Code of org.jboss.dna.jcr.RepositoryQueryManager$Disabled

/*
* 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.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.jcr.RepositoryException;
import javax.jcr.query.InvalidQueryException;
import org.jboss.dna.common.collection.Problems;
import org.jboss.dna.common.collection.SimpleProblems;
import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.common.text.TextEncoder;
import org.jboss.dna.common.text.UrlEncoder;
import org.jboss.dna.common.util.Logger;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
import org.jboss.dna.graph.observe.Changes;
import org.jboss.dna.graph.observe.Observable;
import org.jboss.dna.graph.observe.Observer;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.query.QueryContext;
import org.jboss.dna.graph.query.QueryEngine;
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.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.process.AbstractAccessComponent;
import org.jboss.dna.graph.query.process.ProcessingComponent;
import org.jboss.dna.graph.query.process.Processor;
import org.jboss.dna.graph.query.process.QueryProcessor;
import org.jboss.dna.graph.query.process.SelectComponent.Analyzer;
import org.jboss.dna.graph.query.validate.Schemata;
import org.jboss.dna.graph.request.AccessQueryRequest;
import org.jboss.dna.graph.request.InvalidWorkspaceException;
import org.jboss.dna.graph.request.processor.RequestProcessor;
import org.jboss.dna.graph.search.SearchEngine;
import org.jboss.dna.graph.search.SearchEngineIndexer;
import org.jboss.dna.graph.search.SearchEngineProcessor;
import org.jboss.dna.search.lucene.IndexRules;
import org.jboss.dna.search.lucene.LuceneConfiguration;
import org.jboss.dna.search.lucene.LuceneConfigurations;
import org.jboss.dna.search.lucene.LuceneSearchEngine;

/**
*
*/
abstract class RepositoryQueryManager {

    protected final String sourceName;

    RepositoryQueryManager( String sourceName ) {
        this.sourceName = sourceName;
    }

    public abstract QueryResults query( String workspaceName,
                                        QueryCommand query,
                                        Schemata schemata,
                                        PlanHints hints,
                                        Map<String, Object> variables ) throws InvalidQueryException;

    public abstract QueryResults search( String workspaceName,
                                         String searchExpression,
                                         int maxRowCount,
                                         int offset ) throws InvalidQueryException;

    /**
     * Crawl and index the content in the named workspace.
     *
     * @throws IllegalArgumentException if the workspace is null
     * @throws InvalidWorkspaceException if there is no workspace with the supplied name
     */
    public void reindexContent() {
        // do nothing by default
    }

    /**
     * Crawl and index the content in the named workspace.
     *
     * @param workspace the workspace
     * @throws IllegalArgumentException if the workspace is null
     * @throws InvalidWorkspaceException if there is no workspace with the supplied name
     */
    public void reindexContent( JcrWorkspace workspace ) {
        // do nothing by default
    }

    /**
     * Crawl and index the content starting at the supplied path in the named workspace, to the designated depth.
     *
     * @param workspace the workspace
     * @param path the path of the content to be indexed
     * @param depth the depth of the content to be indexed
     * @throws IllegalArgumentException if the workspace or path are null, or if the depth is less than 1
     * @throws InvalidWorkspaceException if there is no workspace with the supplied name
     */
    public void reindexContent( JcrWorkspace workspace,
                                String path,
                                int depth ) {
        // do nothing by default
    }

    static class PushDown extends RepositoryQueryManager {
        private final ExecutionContext context;
        private final RepositoryConnectionFactory connectionFactory;

        PushDown( String sourceName,
                  ExecutionContext context,
                  RepositoryConnectionFactory connectionFactory ) {
            super(sourceName);
            this.context = context;
            this.connectionFactory = connectionFactory;
        }

        private Graph workspaceGraph( String workspaceName ) {
            Graph graph = Graph.create(this.sourceName, connectionFactory, context);

            if (workspaceName != null) {
                graph.useWorkspace(workspaceName);
            }

            return graph;
        }

        @Override
        public QueryResults query( String workspaceName,
                                   QueryCommand query,
                                   Schemata schemata,
                                   PlanHints hints,
                                   Map<String, Object> variables ) {
            Graph.BuildQuery builder = workspaceGraph(workspaceName).query(query, schemata);
            if (variables != null) builder.using(variables);
            if (hints != null) builder.using(hints);
            return builder.execute();
        }

        @Override
        public QueryResults search( String workspaceName,
                                    String searchExpression,
                                    int maxRowCount,
                                    int offset ) {
            return workspaceGraph(workspaceName).search(searchExpression, maxRowCount, offset);
        }

    }

    static class Disabled extends RepositoryQueryManager {

        Disabled( String sourceName ) {
            super(sourceName);
        }

        /**
         * {@inheritDoc}
         *
         * @see org.jboss.dna.jcr.RepositoryQueryManager#query(java.lang.String, org.jboss.dna.graph.query.model.QueryCommand,
         *      org.jboss.dna.graph.query.validate.Schemata, org.jboss.dna.graph.query.plan.PlanHints, java.util.Map)
         */
        @Override
        public QueryResults query( String workspaceName,
                                   QueryCommand query,
                                   Schemata schemata,
                                   PlanHints hints,
                                   Map<String, Object> variables ) throws InvalidQueryException {
            throw new InvalidQueryException(JcrI18n.queryIsDisabledInRepository.text(this.sourceName));
        }

        /**
         * {@inheritDoc}
         *
         * @see org.jboss.dna.jcr.RepositoryQueryManager#search(java.lang.String, java.lang.String, int, int)
         */
        @Override
        public QueryResults search( String workspaceName,
                                    String searchExpression,
                                    int maxRowCount,
                                    int offset ) throws InvalidQueryException {
            throw new InvalidQueryException(JcrI18n.queryIsDisabledInRepository.text(this.sourceName));
        }
    }

    static class SelfContained extends RepositoryQueryManager {
        private final ExecutionContext context;
        private final String sourceName;
        private final LuceneConfiguration configuration;
        private final SearchEngine searchEngine;
        private final Observer searchObserver;
        private final ExecutorService service;
        private final QueryEngine queryEngine;
        private final RepositoryConnectionFactory connectionFactory;

        SelfContained( ExecutionContext context,
                       String nameOfSourceToBeSearchable,
                       RepositoryConnectionFactory connectionFactory,
                       Observable observable,
                       String indexDirectory,
                       boolean updateIndexesSynchronously ) throws RepositoryException {
            super(nameOfSourceToBeSearchable);

            this.context = context;
            this.sourceName = nameOfSourceToBeSearchable;
            this.connectionFactory = connectionFactory;
            // Define the configuration ...
            TextEncoder encoder = new UrlEncoder();
            if (indexDirectory != null) {
                File indexDir = new File(indexDirectory);
                if (indexDir.exists()) {
                    // The location does exist ...
                    if (!indexDir.isDirectory()) {
                        // The path is not a directory ...
                        I18n msg = JcrI18n.searchIndexDirectoryOptionSpecifiesFileNotDirectory;
                        throw new RepositoryException(msg.text(indexDirectory, sourceName));
                    }
                    if (!indexDir.canWrite()) {
                        // But we cannot write to it ...
                        I18n msg = JcrI18n.searchIndexDirectoryOptionSpecifiesDirectoryThatCannotBeWrittenTo;
                        throw new RepositoryException(msg.text(indexDirectory, sourceName));
                    }
                    if (!indexDir.canRead()) {
                        // But we cannot write to it ...
                        I18n msg = JcrI18n.searchIndexDirectoryOptionSpecifiesDirectoryThatCannotBeRead;
                        throw new RepositoryException(msg.text(indexDirectory, sourceName));
                    }
                    // The directory is usable
                } else {
                    // The location doesn't exist,so try to make it ...
                    if (!indexDir.mkdirs()) {
                        I18n msg = JcrI18n.searchIndexDirectoryOptionSpecifiesDirectoryThatCannotBeCreated;
                        throw new RepositoryException(msg.text(indexDirectory, sourceName));
                    }
                    // We successfully create the dirctory (or directories)
                }
                configuration = LuceneConfigurations.using(indexDir, encoder, encoder);
            } else {
                // Use in-memory as a fall-back ...
                configuration = LuceneConfigurations.inMemory();
            }
            assert configuration != null;

            // Set up the indexing rules ...
            IndexRules indexRules = null;

            // Set up the search engine ...
            org.apache.lucene.analysis.Analyzer analyzer = null;
            boolean verifyWorkspaces = false;
            searchEngine = new LuceneSearchEngine(nameOfSourceToBeSearchable, connectionFactory, verifyWorkspaces, configuration,
                                                  indexRules, analyzer);

            // Set up an original source observer to keep the index up to date ...
            if (updateIndexesSynchronously) {
                this.service = null;
                this.searchObserver = new Observer() {
                    @SuppressWarnings( "synthetic-access" )
                    public void notify( Changes changes ) {
                        if (changes.getSourceName().equals(sourceName)) {
                            process(changes);
                        }
                    }
                };
            } else {
                // It's asynchronous, so create a single-threaded executor and an observer that enqueues the results
                this.service = Executors.newCachedThreadPool();
                this.searchObserver = new Observer() {
                    @SuppressWarnings( "synthetic-access" )
                    public void notify( final Changes changes ) {
                        if (changes.getSourceName().equals(sourceName)) {
                            service.submit(new Runnable() {
                                public void run() {
                                    process(changes);
                                }
                            });
                        }
                    }
                };
            }
            observable.register(this.searchObserver);

            // Set up the query engine ...
            Planner planner = new CanonicalPlanner();
            Optimizer optimizer = new RuleBasedOptimizer();
            Processor processor = new QueryProcessor() {

                /**
                 * {@inheritDoc}
                 *
                 * @see org.jboss.dna.graph.query.process.QueryProcessor#createAccessComponent(org.jboss.dna.graph.query.model.QueryCommand,
                 *      org.jboss.dna.graph.query.QueryContext, org.jboss.dna.graph.query.plan.PlanNode,
                 *      org.jboss.dna.graph.query.QueryResults.Columns,
                 *      org.jboss.dna.graph.query.process.SelectComponent.Analyzer)
                 */
                @Override
                protected ProcessingComponent createAccessComponent( QueryCommand originalQuery,
                                                                     QueryContext context,
                                                                     PlanNode accessNode,
                                                                     Columns resultColumns,
                                                                     Analyzer analyzer ) {
                    return new AccessQueryProcessor((GraphQueryContext)context, resultColumns, accessNode);
                }
            };
            this.queryEngine = new QueryEngine(planner, optimizer, processor);

            // Index any existing content ...
            reindexContent();
        }

        protected void process( Changes changes ) {
            try {
                searchEngine.index(context, changes.getChangeRequests());
            } catch (RuntimeException e) {
                Logger.getLogger(getClass()).error(e, JcrI18n.errorUpdatingQueryIndexes, e.getLocalizedMessage());
            }
        }

        @Override
        public QueryResults query( String workspaceName,
                                   QueryCommand query,
                                   Schemata schemata,
                                   PlanHints hints,
                                   Map<String, Object> variables ) {
            TypeSystem typeSystem = context.getValueFactories().getTypeSystem();
            SearchEngineProcessor processor = searchEngine.createProcessor(context, null, true);
            try {
                QueryContext context = new GraphQueryContext(schemata, typeSystem, hints, new SimpleProblems(), variables,
                                                             processor, workspaceName);
                return queryEngine.execute(context, query);
            } finally {
                processor.close();
            }
        }

        @Override
        public QueryResults search( String workspaceName,
                                    String searchExpression,
                                    int maxRowCount,
                                    int offset ) {
            Graph graph = Graph.create(sourceName, connectionFactory, context);

            if (workspaceName != null) {
                graph.useWorkspace(workspaceName);
            }

            return graph.search(searchExpression, maxRowCount, offset);
        }

        /**
         * {@inheritDoc}
         *
         * @see org.jboss.dna.jcr.RepositoryQueryManager#reindexContent()
         */
        @Override
        public void reindexContent() {
            // Get the workspace names ...
            Set<String> workspaces = Graph.create(sourceName, connectionFactory, context).getWorkspaces();

            // Index the existing content (this obtains a connection and possibly locks the source) ...
            SearchEngineIndexer indexer = new SearchEngineIndexer(context, searchEngine, connectionFactory);
            try {
                for (String workspace : workspaces) {
                    indexer.index(workspace);
                }
            } finally {
                indexer.close();
            }

        }

        /**
         * {@inheritDoc}
         *
         * @see org.jboss.dna.jcr.RepositoryQueryManager#reindexContent(org.jboss.dna.jcr.JcrWorkspace)
         */
        @Override
        public void reindexContent( JcrWorkspace workspace ) {
            SearchEngineIndexer indexer = new SearchEngineIndexer(context, searchEngine, connectionFactory);
            try {
                indexer.index(workspace.getName());
            } finally {
                indexer.close();
            }
        }

        /**
         * {@inheritDoc}
         *
         * @see org.jboss.dna.jcr.RepositoryQueryManager#reindexContent(org.jboss.dna.jcr.JcrWorkspace, java.lang.String, int)
         */
        @Override
        public void reindexContent( JcrWorkspace workspace,
                                    String path,
                                    int depth ) {
            Path at = workspace.context().getValueFactories().getPathFactory().create(path);
            SearchEngineIndexer indexer = new SearchEngineIndexer(context, searchEngine, connectionFactory);
            try {
                indexer.index(workspace.getName(), at, depth);
            } finally {
                indexer.close();
            }
        }

        protected class GraphQueryContext extends QueryContext {
            private final RequestProcessor processor;
            private final String workspaceName;

            protected GraphQueryContext( Schemata schemata,
                                         TypeSystem typeSystem,
                                         PlanHints hints,
                                         Problems problems,
                                         Map<String, Object> variables,
                                         RequestProcessor processor,
                                         String workspaceName ) {
                super(schemata, typeSystem, hints, problems, variables);
                this.processor = processor;
                this.workspaceName = workspaceName;
            }

            /**
             * @return processor
             */
            public RequestProcessor getProcessor() {
                return processor;
            }

            /**
             * @return workspaceName
             */
            public String getWorkspaceName() {
                return workspaceName;
            }
        }

        protected static class AccessQueryProcessor extends AbstractAccessComponent {
            private final AccessQueryRequest accessRequest;

            protected AccessQueryProcessor( GraphQueryContext context,
                                            Columns columns,
                                            PlanNode accessNode ) {
                super(context, columns, accessNode);
                accessRequest = new AccessQueryRequest(context.getWorkspaceName(), sourceName, getColumns(), andedConstraints,
                                                       limit, context.getSchemata(), context.getVariables());
                context.getProcessor().process(accessRequest);
            }

            /**
             * Get the access query request.
             *
             * @return the access query request; never null
             */
            public AccessQueryRequest getAccessRequest() {
                return accessRequest;
            }

            /**
             * {@inheritDoc}
             *
             * @see org.jboss.dna.graph.query.process.ProcessingComponent#execute()
             */
            @Override
            public List<Object[]> execute() {
                if (accessRequest.getError() != null) {
                    I18n msg = GraphI18n.errorWhilePerformingQuery;
                    getContext().getProblems().addError(accessRequest.getError(),
                                                        msg,
                                                        accessNode.getString(),
                                                        accessRequest.workspace(),
                                                        sourceName,
                                                        accessRequest.getError().getLocalizedMessage());
                    return emptyTuples();
                }
                return accessRequest.getTuples();
            }

        }

    }
}
TOP

Related Classes of org.jboss.dna.jcr.RepositoryQueryManager$Disabled

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.