/*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* File: $Source: /cvsroot/slrp/common/com.ibm.adtech.indexer.lucene/src/com/ibm/adtech/indexer/lucene/LuceneQuery.java,v $
* Created by: Wing Yung ( <a href="mailto:wingyung@us.ibm.com">wingyung@us.ibm.com </a>)
* Created on: 10/11/2005
* Revision: $Id: LuceneQuery.java 169 2007-07-31 14:11:15Z mroy $
*
* Contributors:
* IBM Corporation - initial API and implementation
* Cambridge Semantics Incorporated - Fork to Anzo
*******************************************************************************/
package org.openanzo.indexer.lucene;
import java.util.Collection;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixFilter;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.util.Version;
import org.openanzo.exceptions.ExceptionConstants;
import org.openanzo.indexer.IQuery;
import org.openanzo.indexer.IndexerException;
/**
* Implementation of IQuery based on Lucene.
*
* @author Wing Yung ( <a href="mailto:wingyung@us.ibm.com">wingyung@us.ibm.com </a>)
*/
public class LuceneQuery implements IQuery {
//private static final Logger log = LoggerFactory.getLogger(LuceneQuery.class);
protected Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
private Query query = null;
protected Filter filter = null;
private Collection<Query> terms = null;
private String defaultField;
private QueryParser parser = null;
/**
* Initializes the query based on the queryStr
*
* @param queryStr
* query string, can use Lucene Query constructs
* @throws IndexerException
* {@link ExceptionConstants.INDEX#PARSE_EXCEPTION} if there was an exception parsing the query
*/
public void initialize(String queryStr) throws IndexerException {
try {
parser = new QueryParser(Version.LUCENE_CURRENT, defaultField, analyzer);
parser.setAllowLeadingWildcard(true);
query = parser.parse(queryStr);
} catch (ParseException e) {
throw new IndexerException(ExceptionConstants.INDEX.PARSE_EXCEPTION, e, queryStr);
}
}
/**
* Initializes the query based on the queryStr
*
* @param queryStr
* query string, can use Lucene Query constructs
* @throws IndexerException
* {@link ExceptionConstants.INDEX#PARSE_EXCEPTION} if there was an exception parsing the query
*/
private void initializeFiltered(String queryStr) throws IndexerException {
try {
BooleanQuery bq = new BooleanQuery();
parser = new QueryParser(Version.LUCENE_CURRENT, defaultField, analyzer);
parser.setAllowLeadingWildcard(true);
query = parser.parse(queryStr);
parseQuery(bq, query, BooleanClause.Occur.MUST);
for (Query term : terms) {
bq.add(term, BooleanClause.Occur.MUST);
}
if (bq.getClauses().length == 0 && filter != null) {
bq.add(new MatchAllDocsQuery(), BooleanClause.Occur.MUST);
}
query = bq;
} catch (ParseException ie) {
throw new IndexerException(ExceptionConstants.INDEX.PARSE_EXCEPTION, ie);
}
}
private void parseQuery(BooleanQuery destinationQuery, Query sourceQuery, BooleanClause.Occur occur) {
if (sourceQuery instanceof BooleanQuery) {
for (BooleanClause bc : ((BooleanQuery) query).getClauses()) {
parseQuery(destinationQuery, bc.getQuery(), occur);
}
} else if (sourceQuery instanceof PrefixQuery) {
PrefixQuery pq = (PrefixQuery) sourceQuery;
filter = new PrefixFilter(pq.getPrefix());
} else if (sourceQuery instanceof WildcardQuery) {
destinationQuery.add(new BooleanClause(sourceQuery, occur));
} else if (sourceQuery instanceof TermQuery) {
destinationQuery.add(new BooleanClause(sourceQuery, occur));
} else if (sourceQuery instanceof MultiTermQuery) {
destinationQuery.add(new BooleanClause(sourceQuery, occur));
} else if (sourceQuery instanceof PhraseQuery) {
destinationQuery.add(new BooleanClause(sourceQuery, occur));
}
}
/**
* Initializes a simple query. Sets the default field to search, along with the text to search. Note that text may contain other modifiers so that other
* fields are searched as well.
*
* @param defaultField
* default field to search in this query
* @param text
* text query to search for, can use Lucene Query constructs
*
*/
public void initialize(String defaultField, String text) throws IndexerException {
query = null;
this.defaultField = defaultField;
initialize(text);
}
/**
* Initializes a simple query. Sets the default field to search, along with the text to search. Note that text may contain other modifiers so that other
* fields are searched as well.
*
* @param defaultField
* default field to search in this query
* @param text
* text query to search for, can use Lucene Query constructs
* @param terms
* extra search terms for query
* @throws IndexerException
*/
public void initialize(String defaultField, String text, Collection<Query> terms) throws IndexerException {
query = null;
this.defaultField = defaultField;
this.terms = terms;
initializeFiltered(text);
}
/**
* Get the underlying Query object
*
* @return the underlying Query object
*/
public Query getQuery() {
return query;
}
/**
* Get the underlying Filter object.
*
* @return the underlying Filter object.
*/
public Filter getFilter() {
return filter;
}
/**
* Get extra search terms for query
*
* @return extra search terms for query
*/
public Collection<Query> getTerms() {
return terms;
}
}