/**
* License Agreement for OpenSearchServer
*
* Copyright (C) 2015 Emmanuel Keller / Jaeksoft
*
* http://www.open-search-server.com
*
* This file is part of OpenSearchServer.
*
* OpenSearchServer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenSearchServer 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenSearchServer.
* If not, see <http://www.gnu.org/licenses/>.
**/
package com.jaeksoft.searchlib.request;
import java.io.IOException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Version;
import com.jaeksoft.searchlib.SearchLibException;
import com.jaeksoft.searchlib.analysis.LanguageEnum;
import com.jaeksoft.searchlib.analysis.PerFieldAnalyzer;
import com.jaeksoft.searchlib.authentication.AuthManager;
import com.jaeksoft.searchlib.config.Config;
import com.jaeksoft.searchlib.function.expression.SyntaxError;
import com.jaeksoft.searchlib.index.ReaderAbstract;
import com.jaeksoft.searchlib.index.ReaderInterface;
import com.jaeksoft.searchlib.query.ParseException;
import com.jaeksoft.searchlib.result.AbstractResult;
import com.jaeksoft.searchlib.result.ResultSearchSingle;
import com.jaeksoft.searchlib.schema.Schema;
import com.jaeksoft.searchlib.schema.SchemaField;
public abstract class AbstractLocalSearchRequest extends AbstractSearchRequest
implements RequestInterfaces.ReturnedFieldInterface,
RequestInterfaces.FilterListInterface {
private transient Query boostedComplexQuery;
private transient Query notBoostedComplexQuery;
private transient Query snippetSimpleQuery;
protected transient PerFieldAnalyzer analyzer;
protected transient QueryParser queryParser;
private String queryParsed;
protected AbstractLocalSearchRequest(Config config, RequestTypeEnum type) {
super(config, type);
}
@Override
protected void setDefaultValues() {
super.setDefaultValues();
this.queryParser = null;
this.queryParsed = null;
this.snippetSimpleQuery = null;
this.boostedComplexQuery = null;
this.notBoostedComplexQuery = null;
this.analyzer = null;
this.queryParsed = null;
}
@Override
public void copyFrom(AbstractRequest request) {
super.copyFrom(request);
this.snippetSimpleQuery = null;
this.boostedComplexQuery = null;
this.notBoostedComplexQuery = null;
this.analyzer = null;
this.queryParsed = null;
}
@Override
protected void resetNoLock() {
super.resetNoLock();
this.queryParser = null;
this.queryParsed = null;
this.snippetSimpleQuery = null;
this.boostedComplexQuery = null;
this.notBoostedComplexQuery = null;
this.analyzer = null;
}
private PerFieldAnalyzer checkAnalyzer() throws SearchLibException {
if (analyzer == null)
analyzer = config.getSchema().getQueryPerFieldAnalyzer(lang);
return analyzer;
}
public PerFieldAnalyzer getAnalyzer() throws SearchLibException {
rwl.r.lock();
try {
if (analyzer != null)
return analyzer;
} finally {
rwl.r.unlock();
}
rwl.w.lock();
try {
checkAnalyzer();
return analyzer;
} finally {
rwl.w.unlock();
}
}
protected abstract Query newSnippetQuery(String queryString)
throws IOException, ParseException, SyntaxError, SearchLibException;
public Query getSnippetQuery() throws IOException, ParseException,
SyntaxError, SearchLibException {
rwl.r.lock();
try {
if (snippetSimpleQuery != null)
return snippetSimpleQuery;
} finally {
rwl.r.unlock();
}
rwl.w.lock();
try {
if (snippetSimpleQuery != null)
return snippetSimpleQuery;
getQueryParser();
checkAnalyzer();
snippetSimpleQuery = newSnippetQuery(queryString);
return snippetSimpleQuery;
} finally {
rwl.w.unlock();
}
}
protected abstract Query newComplexQuery(String queryString)
throws ParseException, SyntaxError, SearchLibException, IOException;
private Query newComplexQuery() throws ParseException, SearchLibException,
SyntaxError, IOException {
getQueryParser();
checkAnalyzer();
Query query = newComplexQuery(queryString);
if (query == null)
query = new BooleanQuery();
return query;
}
public Query getNotBoostedQuery() throws ParseException,
SearchLibException, SyntaxError, IOException {
rwl.r.lock();
try {
if (notBoostedComplexQuery != null)
return notBoostedComplexQuery;
} finally {
rwl.r.unlock();
}
rwl.w.lock();
try {
if (notBoostedComplexQuery != null)
return notBoostedComplexQuery;
notBoostedComplexQuery = newComplexQuery();
return notBoostedComplexQuery;
} finally {
rwl.w.unlock();
}
}
@Override
public Query getQuery() throws ParseException, SyntaxError,
SearchLibException, IOException {
rwl.r.lock();
try {
if (boostedComplexQuery != null)
return boostedComplexQuery;
} finally {
rwl.r.unlock();
}
rwl.w.lock();
try {
if (boostedComplexQuery != null)
return boostedComplexQuery;
boostedComplexQuery = newComplexQuery();
for (BoostQuery boostQuery : boostingQueries)
boostedComplexQuery = boostQuery.getNewQuery(
boostedComplexQuery, queryParser);
queryParsed = boostedComplexQuery.toString();
return boostedComplexQuery;
} finally {
rwl.w.unlock();
}
}
private QueryParser getQueryParser() throws ParseException,
SearchLibException {
if (queryParser != null)
return queryParser;
Schema schema = getConfig().getSchema();
SchemaField field = schema.getFieldList().getDefaultField();
if (field == null)
throw new SearchLibException(
"Please select a default field in the schema");
queryParser = new QueryParser(Version.LUCENE_36, field.getName(),
checkAnalyzer());
queryParser.setAllowLeadingWildcard(allowLeadingWildcard);
queryParser.setPhraseSlop(phraseSlop);
queryParser.setDefaultOperator(defaultOperator.lucop);
queryParser.setLowercaseExpandedTerms(false);
return queryParser;
}
public void setBoostedComplexQuery(Query query) {
rwl.w.lock();
try {
boostedComplexQuery = query;
} finally {
rwl.w.unlock();
}
}
final public String getQueryParsed() throws ParseException, SyntaxError,
SearchLibException, IOException {
getQuery();
rwl.r.lock();
try {
return queryParsed;
} finally {
rwl.r.unlock();
}
}
@Override
protected void setQueryStringNoLock(String q) {
super.setQueryStringNoLock(q);
boostedComplexQuery = null;
notBoostedComplexQuery = null;
snippetSimpleQuery = null;
}
@Override
protected void setLangNoLock(LanguageEnum lang) {
super.setLangNoLock(lang);
analyzer = null;
}
@Override
public AbstractResult<?> execute(ReaderInterface reader)
throws SearchLibException {
try {
AuthManager authManager = config.getAuthManager();
if (authManager.isEnabled()
&& !(this instanceof SearchFilterRequest)) {
authManager.apply(this);
}
return new ResultSearchSingle((ReaderAbstract) reader, this);
} catch (IOException e) {
throw new SearchLibException(e);
} catch (ParseException e) {
throw new SearchLibException(e);
} catch (SyntaxError e) {
throw new SearchLibException(e);
} catch (SearchLibException e) {
throw new SearchLibException(e);
} catch (InstantiationException e) {
throw new SearchLibException(e);
} catch (IllegalAccessException e) {
throw new SearchLibException(e);
} catch (ClassNotFoundException e) {
throw new SearchLibException(e);
}
}
}