mirror of https://github.com/apache/lucene.git
Added thread-safety around use of core's QueryParser.
Old XML parser constructors use a mode which will synchronize on use of the user-supplied QueryParser. New constructors offer alternative option of passing "defaultField" String which is used to create a new single-use QueryParser for each parse operation. git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@628568 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
95e2e57c86
commit
caed55ef5e
|
@ -59,7 +59,28 @@ public class CoreParser implements QueryBuilder
|
|||
public static int maxNumCachedFilters=20;
|
||||
|
||||
|
||||
/**
|
||||
* Construct an XML parser that uses a single instance QueryParser for handling
|
||||
* UserQuery tags - all parse operations are synchronised on this parser
|
||||
* @param analyzer
|
||||
* @param parser A QueryParser which will be synchronized on during parse calls.
|
||||
*/
|
||||
public CoreParser(Analyzer analyzer, QueryParser parser)
|
||||
{
|
||||
this(null,analyzer,parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an XML parser that creates a QueryParser for each UserQuery request.
|
||||
* @param defaultField The default field name used by QueryParsers constructed for UserQuery tags
|
||||
* @param analyzer
|
||||
*/
|
||||
public CoreParser(String defaultField, Analyzer analyzer)
|
||||
{
|
||||
this(defaultField,analyzer,null);
|
||||
}
|
||||
|
||||
protected CoreParser(String defaultField,Analyzer analyzer, QueryParser parser)
|
||||
{
|
||||
this.analyzer=analyzer;
|
||||
this.parser=parser;
|
||||
|
@ -72,7 +93,14 @@ public class CoreParser implements QueryBuilder
|
|||
queryFactory.addBuilder("TermsQuery",new TermsQueryBuilder(analyzer));
|
||||
queryFactory.addBuilder("MatchAllDocsQuery",new MatchAllDocsQueryBuilder());
|
||||
queryFactory.addBuilder("BooleanQuery",new BooleanQueryBuilder(queryFactory));
|
||||
queryFactory.addBuilder("UserQuery",new UserInputQueryBuilder(parser));
|
||||
if(parser!=null)
|
||||
{
|
||||
queryFactory.addBuilder("UserQuery",new UserInputQueryBuilder(parser));
|
||||
}
|
||||
else
|
||||
{
|
||||
queryFactory.addBuilder("UserQuery",new UserInputQueryBuilder(defaultField,analyzer));
|
||||
}
|
||||
queryFactory.addBuilder("FilteredQuery",new FilteredQueryBuilder(filterFactory,queryFactory));
|
||||
queryFactory.addBuilder("ConstantScoreQuery",new ConstantScoreQueryBuilder(filterFactory));
|
||||
|
||||
|
|
|
@ -27,9 +27,29 @@ import org.apache.lucene.xmlparser.builders.TermsFilterBuilder;
|
|||
public class CorePlusExtensionsParser extends CoreParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Construct an XML parser that uses a single instance QueryParser for handling
|
||||
* UserQuery tags - all parse operations are synchronised on this parser
|
||||
* @param analyzer
|
||||
* @param parser A QueryParser which will be synchronized on during parse calls.
|
||||
*/
|
||||
public CorePlusExtensionsParser(Analyzer analyzer, QueryParser parser)
|
||||
{
|
||||
super(analyzer, parser);
|
||||
this(null,analyzer, parser);
|
||||
}
|
||||
/**
|
||||
* Constructs an XML parser that creates a QueryParser for each UserQuery request.
|
||||
* @param defaultField The default field name used by QueryParsers constructed for UserQuery tags
|
||||
* @param analyzer
|
||||
*/
|
||||
public CorePlusExtensionsParser(String defaultField,Analyzer analyzer)
|
||||
{
|
||||
this(defaultField,analyzer, null);
|
||||
}
|
||||
|
||||
private CorePlusExtensionsParser(String defaultField,Analyzer analyzer, QueryParser parser)
|
||||
{
|
||||
super(defaultField,analyzer, parser);
|
||||
filterFactory.addBuilder("TermsFilter",new TermsFilterBuilder(analyzer));
|
||||
filterFactory.addBuilder("BooleanFilter",new BooleanFilterBuilder(filterFactory));
|
||||
filterFactory.addBuilder("DuplicateFilter",new DuplicateFilterBuilder());
|
||||
|
@ -39,6 +59,4 @@ public class CorePlusExtensionsParser extends CoreParser
|
|||
queryFactory.addBuilder("FuzzyLikeThisQuery", new FuzzyLikeThisQueryBuilder(analyzer));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.apache.lucene.xmlparser.builders;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.queryParser.ParseException;
|
||||
import org.apache.lucene.queryParser.QueryParser;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
@ -26,17 +27,28 @@ import org.w3c.dom.Element;
|
|||
*/
|
||||
|
||||
/**
|
||||
* UserInputQueryBuilder uses 1 of 2 strategies for thread-safe parsing:
|
||||
* 1) Synchronizing access to "parse" calls on a previously supplied QueryParser
|
||||
* or..
|
||||
* 2) creating a new QueryParser object for each parse request
|
||||
* @author maharwood
|
||||
*/
|
||||
public class UserInputQueryBuilder implements QueryBuilder {
|
||||
|
||||
QueryParser parser;
|
||||
QueryParser unSafeParser;
|
||||
private Analyzer analyzer;
|
||||
private String defaultField;
|
||||
|
||||
/**
|
||||
* @param parser
|
||||
* @param parser thread un-safe query parser
|
||||
*/
|
||||
public UserInputQueryBuilder(QueryParser parser) {
|
||||
this.parser = parser;
|
||||
this.unSafeParser = parser;
|
||||
}
|
||||
|
||||
public UserInputQueryBuilder(String defaultField, Analyzer analyzer) {
|
||||
this.analyzer = analyzer;
|
||||
this.defaultField = defaultField;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -45,7 +57,21 @@ public class UserInputQueryBuilder implements QueryBuilder {
|
|||
public Query getQuery(Element e) throws ParserException {
|
||||
String text=DOMUtils.getText(e);
|
||||
try {
|
||||
Query q = parser.parse(text);
|
||||
Query q = null;
|
||||
if(unSafeParser!=null)
|
||||
{
|
||||
//synchronize on unsafe parser
|
||||
synchronized (unSafeParser)
|
||||
{
|
||||
q = unSafeParser.parse(text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Create new parser
|
||||
QueryParser parser=new QueryParser(defaultField,analyzer);
|
||||
q = parser.parse(text);
|
||||
}
|
||||
q.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
||||
return q;
|
||||
} catch (ParseException e1) {
|
||||
|
|
|
@ -12,7 +12,6 @@ import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
|||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.queryParser.QueryParser;
|
||||
import org.apache.lucene.search.Hits;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
@ -56,7 +55,7 @@ public class TestParser extends TestCase {
|
|||
super.setUp();
|
||||
|
||||
//initialize the parser
|
||||
builder=new CorePlusExtensionsParser(analyzer,new QueryParser("contents", analyzer));
|
||||
builder=new CorePlusExtensionsParser("contents",analyzer);
|
||||
|
||||
//initialize the index (done once, then cached in static data for use with ALL tests)
|
||||
if(dir==null)
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.apache.lucene.analysis.Analyzer;
|
|||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.queryParser.QueryParser;
|
||||
import org.apache.lucene.search.Hits;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
|
@ -154,7 +153,7 @@ public class TestQueryTemplateManager extends TestCase {
|
|||
searcher=new IndexSearcher(dir);
|
||||
|
||||
//initialize the parser
|
||||
builder=new CorePlusExtensionsParser(analyzer,new QueryParser("artist", analyzer));
|
||||
builder=new CorePlusExtensionsParser("artist", analyzer);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue