blob: 165313dc5bbe1a2a3596c77d3f789871152671c8 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. 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. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
/* Created on Jul 18, 2003 */
package org.apache.roller.weblogger.business.search.operations;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopFieldDocs;
import org.apache.roller.weblogger.business.search.FieldConstants;
import org.apache.roller.weblogger.business.search.IndexManager;
import org.apache.roller.weblogger.business.search.IndexManagerImpl;
import org.apache.roller.weblogger.business.search.IndexUtil;
/**
* An operation that searches the index.
*
* @author Mindaugas Idzelis (min@idzelis.com)
*/
public class SearchOperation extends ReadFromIndexOperation {
// ~ Static fields/initializers
// =============================================
private static Log mLogger = LogFactory.getFactory().getInstance(
SearchOperation.class);
private static final String[] SEARCH_FIELDS = new String[] {
FieldConstants.CONTENT, FieldConstants.TITLE,
FieldConstants.C_CONTENT };
private static final Sort SORTER = new Sort(new SortField(
FieldConstants.PUBLISHED, SortField.Type.STRING, true));
// ~ Instance fields
// ========================================================
private IndexSearcher searcher;
private TopFieldDocs searchresults;
private String term;
private String websiteHandle;
private String category;
private String locale;
private String parseError;
// ~ Constructors
// ===========================================================
/**
* Create a new operation that searches the index.
*/
public SearchOperation(IndexManager mgr) {
// TODO: finish moving IndexManager to backend, so this cast is not
// needed
super((IndexManagerImpl) mgr);
}
// ~ Methods
// ================================================================
public void setTerm(String term) {
this.term = term;
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
@Override
public void doRun() {
final int docLimit = 500;
searchresults = null;
searcher = null;
try {
IndexReader reader = manager.getSharedIndexReader();
searcher = new IndexSearcher(reader);
MultiFieldQueryParser multiParser = new MultiFieldQueryParser(
SEARCH_FIELDS, IndexManagerImpl.getAnalyzer());
// Make it an AND by default. Comment this out for an or (default)
multiParser.setDefaultOperator(MultiFieldQueryParser.Operator.AND);
// Create a query object out of our term
Query query = multiParser.parse(term);
Term tUsername = IndexUtil.getTerm(FieldConstants.WEBSITE_HANDLE,
websiteHandle);
if (tUsername != null) {
query = new BooleanQuery.Builder()
.add(query, BooleanClause.Occur.MUST)
.add(new TermQuery(tUsername), BooleanClause.Occur.MUST)
.build();
}
if (category != null) {
Term tCategory = new Term(FieldConstants.CATEGORY, category.toLowerCase());
query = new BooleanQuery.Builder()
.add(query, BooleanClause.Occur.MUST)
.add(new TermQuery(tCategory), BooleanClause.Occur.MUST)
.build();
}
Term tLocale = IndexUtil.getTerm(FieldConstants.LOCALE, locale);
if (tLocale != null) {
query = new BooleanQuery.Builder()
.add(query, BooleanClause.Occur.MUST)
.add(new TermQuery(tLocale), BooleanClause.Occur.MUST)
.build();
}
searchresults = searcher.search(query, docLimit, SORTER);
} catch (IOException e) {
mLogger.error("Error searching index", e);
parseError = e.getMessage();
} catch (ParseException e) {
// who cares?
parseError = e.getMessage();
}
// don't need to close the reader, since we didn't do any writing!
}
/**
* Gets the searcher.
*
* @return the searcher
*/
public IndexSearcher getSearcher() {
return searcher;
}
/**
* Sets the searcher.
*
* @param searcher
* the new searcher
*/
public void setSearcher(IndexSearcher searcher) {
this.searcher = searcher;
}
/**
* Gets the results.
*
* @return the results
*/
public TopFieldDocs getResults() {
return searchresults;
}
/**
* Gets the results count.
*
* @return the results count
*/
public int getResultsCount() {
if (searchresults == null) {
return -1;
}
return (int) searchresults.totalHits.value;
}
/**
* Gets the parses the error.
*
* @return the parses the error
*/
public String getParseError() {
return parseError;
}
/**
* Sets the website handle.
*
* @param websiteHandle
* the new website handle
*/
public void setWebsiteHandle(String websiteHandle) {
this.websiteHandle = websiteHandle;
}
/**
* Sets the category.
*
* @param category
* the new category
*/
public void setCategory(String category) {
this.category = category;
}
/**
* Sets the locale.
*
* @param locale
* the new locale
*/
public void setLocale(String locale) {
this.locale = locale;
}
}