Package org.apache.xindice.core.query

Source Code of org.apache.xindice.core.query.TextQueryResolver$TextQuery$ResultSet

/*
* 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.
*
* $Id: TextQueryResolver.java 577512 2007-09-20 02:27:54Z natalia $
*/

package org.apache.xindice.core.query;

import java.util.HashSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xindice.core.Collection;
import org.apache.xindice.core.data.Key;
import org.apache.xindice.core.data.NodeSet;
import org.apache.xindice.core.data.Entry;
import org.apache.xindice.core.DBException;
import org.apache.xindice.core.FaultCodes;
import org.apache.xindice.core.indexer.LuceneIndexer;
import org.apache.xindice.core.indexer.Indexer;
import org.apache.xindice.core.indexer.IndexMatch;
import org.apache.xindice.util.SimpleConfigurable;
import org.apache.xindice.util.XindiceRuntimeException;
import org.apache.xindice.xml.dom.DBDocument;
import org.apache.xindice.xml.NamespaceMap;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.analysis.Analyzer;

import org.w3c.dom.Node;

/**
* Query resolver for full text queries. Requires existing full text index
* to work.
*
* @see org.apache.xindice.core.indexer.LuceneIndexer
* @author Andy Armstrong
* @version $Revision: 577512 $, $Date: 2007-09-19 22:27:54 -0400 (Wed, 19 Sep 2007) $
*/
public class TextQueryResolver extends SimpleConfigurable implements QueryResolver {

  public final static String STYLE_FT = "Text";
  private static final Log log = LogFactory.getLog(TextQueryResolver.class);

  private class TextQuery implements Query {
    private Collection context;
    private String query;
    private Key keys[];
    private LuceneIndexer idx;
        private org.apache.lucene.search.Query compiledQuery;

        private TextQuery(Collection context, String query, Key[] keys) throws QueryException {
            this.context = context;
            this.keys = keys;
            this.query = query;

            try {
                idx = findIndex(context);
                if (null == idx) {
                    throw new QueryException(FaultCodes.QRY_STYLE_NOT_FOUND, "Could not find text indexer in this collection");
                }
                Analyzer an = idx.getAnalyzer();
                compiledQuery = new QueryParser("", an).parse(query);
            } catch (QueryException e) {
                throw e;
            } catch (DBException e) {
                throw new QueryException(FaultCodes.QRY_COMPILATION_ERROR, "Failed to compile the query due to database error", e);
            } catch (ParseException e) {
                throw new QueryException(FaultCodes.QRY_COMPILATION_ERROR, "Failed to compile the query", e);
            }
        }

    public String getQueryStyle() {
      return STYLE_FT;
    }

    public Collection getQueryContext() {
      return context;
    }

    public String getQueryString() {
      return query;
    }

    public NamespaceMap getNamespaceMap() {
      return null;
    }

    public Key[] getKeySet() {
      return keys;
    }

        /**
         * Executes compiled Lucene query against existing index.
         *
         * @return NodeSet that contains document element of all matching
         * documents
         * @throws QueryException
         */
        public NodeSet execute() throws QueryException {
      try {
        IndexMatch[] match = idx.queryMatches(compiledQuery);
                Key[] uniqueKeys = QueryEngine.getUniqueKeys(match);

                // convert keys filter to HashMap
                HashSet filter = null;
        if (keys != null) {
          filter = new HashSet(keys.length);
          for (int k = 0; k < keys.length; k++) {
            filter.add(keys[k]);
          }
        }

                Key rk[] = new Key[uniqueKeys.length];
                int rkused = 0;
        for (int i = 0; i < uniqueKeys.length; i++) {
                    if (filter == null || filter.contains(uniqueKeys[i])) {
                        rk[rkused++] = uniqueKeys[i];
                    }
                }

        return new ResultSet(rk, rkused);

      } catch (DBException e) {
                throw new ProcessingException("Error executing full text query: " + e.getMessage(), e);
      }
    }

        /**
         * ResultSet
         */
        private class ResultSet implements NodeSet {
            private Key[] keySet;

            private int keyPos = 0;
            private int keyLen;
            private Node nextNode;

            public ResultSet(Key[] keySet, int keyLen) {
                this.keySet = keySet;
                this.keyLen = keyLen;

                try {
                    prepareNextNode();
                } catch (Exception e) {
                    throw new XindiceRuntimeException(e);
                }
            }

            private void prepareNextNode() throws DBException {
                nextNode = null;

                while (nextNode == null && keyPos < keyLen) {
                    Entry entry = context.getEntry(keySet[keyPos++]);
                    if (entry == null || entry.getEntryType() != Entry.DOCUMENT) {
                        continue;
                    }

                    DBDocument d = (DBDocument) entry.getValue();
                    if (d != null) {
                        nextNode = d.getDocumentElement();
                    }
                }
            }

            public boolean hasMoreNodes() {
                return nextNode != null;
            }

            public Object getNextNode() {
                Node n = nextNode;

                try {
                    prepareNextNode();
                } catch (Exception e) {
                    throw new XindiceRuntimeException(e);
                }

                return n;
            }
        }
    }

    private LuceneIndexer findIndex(Collection c) throws DBException {
        return (LuceneIndexer) c.getIndexManager().getBestIndexer(Indexer.STYLE_FULLTEXT, null);
    }

  public void setQueryEngine(QueryEngine engine) {
    // do nothing
        // FIXME: not used
    }

  public String getQueryStyle() {
    return STYLE_FT;
  }

  public Query compileQuery(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException {
        if (log.isTraceEnabled()) {
            log.trace("Compiling query for collection " + context.getCanonicalName() + ", query = " + query);
        }

        return new TextQuery(context, query, keys);
  }

  public NodeSet query(Collection context, String query, NamespaceMap nsMap, Key[] keys) throws QueryException {
        if (log.isTraceEnabled()) {
            log.trace("Querying collection " + context.getCanonicalName() + ", query = " + query);
        }
        try {
            Query tq = new TextQuery(context, query, keys);
            return tq.execute();
        } catch (Exception e) {
            if (e instanceof QueryException) {
                throw (QueryException) e;
            } else {
                throw new ProcessingException("Failed to execute text query", e);
            }
        }
  }
}
TOP

Related Classes of org.apache.xindice.core.query.TextQueryResolver$TextQuery$ResultSet

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.