mirror of https://github.com/apache/lucene.git
LUCENE-3311: Cleaned up XML QP codebase
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1158088 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4bf2a3ab2b
commit
e227a64b9d
|
@ -17,21 +17,6 @@
|
||||||
|
|
||||||
package org.apache.lucene.xmlparser.webdemo;
|
package org.apache.lucene.xmlparser.webdemo;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import javax.servlet.RequestDispatcher;
|
|
||||||
import javax.servlet.ServletConfig;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
|
@ -48,108 +33,118 @@ import org.apache.lucene.util.Version;
|
||||||
import org.apache.lucene.xmlparser.CorePlusExtensionsParser;
|
import org.apache.lucene.xmlparser.CorePlusExtensionsParser;
|
||||||
import org.apache.lucene.xmlparser.QueryTemplateManager;
|
import org.apache.lucene.xmlparser.QueryTemplateManager;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.ServletConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
public class FormBasedXmlQueryDemo extends HttpServlet {
|
public class FormBasedXmlQueryDemo extends HttpServlet {
|
||||||
|
|
||||||
private QueryTemplateManager queryTemplateManager;
|
private QueryTemplateManager queryTemplateManager;
|
||||||
private CorePlusExtensionsParser xmlParser;
|
private CorePlusExtensionsParser xmlParser;
|
||||||
private IndexSearcher searcher;
|
private IndexSearcher searcher;
|
||||||
private Analyzer analyzer=new StandardAnalyzer(org.apache.lucene.util.Version.LUCENE_CURRENT);
|
private Analyzer analyzer = new StandardAnalyzer(org.apache.lucene.util.Version.LUCENE_CURRENT);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(ServletConfig config) throws ServletException {
|
public void init(ServletConfig config) throws ServletException {
|
||||||
super.init(config);
|
super.init(config);
|
||||||
try {
|
try {
|
||||||
openExampleIndex();
|
openExampleIndex();
|
||||||
|
|
||||||
//load servlet configuration settings
|
//load servlet configuration settings
|
||||||
String xslFile=config.getInitParameter("xslFile");
|
String xslFile = config.getInitParameter("xslFile");
|
||||||
String defaultStandardQueryParserField = config.getInitParameter("defaultStandardQueryParserField");
|
String defaultStandardQueryParserField = config.getInitParameter("defaultStandardQueryParserField");
|
||||||
|
|
||||||
|
|
||||||
//Load and cache choice of XSL query template using QueryTemplateManager
|
//Load and cache choice of XSL query template using QueryTemplateManager
|
||||||
queryTemplateManager=new QueryTemplateManager(
|
queryTemplateManager = new QueryTemplateManager(
|
||||||
getServletContext().getResourceAsStream("/WEB-INF/"+xslFile));
|
getServletContext().getResourceAsStream("/WEB-INF/" + xslFile));
|
||||||
|
|
||||||
//initialize an XML Query Parser for use by all threads
|
//initialize an XML Query Parser for use by all threads
|
||||||
xmlParser=new CorePlusExtensionsParser(defaultStandardQueryParserField,analyzer);
|
xmlParser = new CorePlusExtensionsParser(defaultStandardQueryParserField, analyzer);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ServletException("Error loading query template",e);
|
throw new ServletException("Error loading query template", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
//Take all completed form fields and add to a Properties object
|
//Take all completed form fields and add to a Properties object
|
||||||
Properties completedFormFields=new Properties();
|
Properties completedFormFields = new Properties();
|
||||||
Enumeration pNames = request.getParameterNames();
|
Enumeration pNames = request.getParameterNames();
|
||||||
while(pNames.hasMoreElements()){
|
while (pNames.hasMoreElements()) {
|
||||||
String propName=(String) pNames.nextElement();
|
String propName = (String) pNames.nextElement();
|
||||||
String value=request.getParameter(propName);
|
String value = request.getParameter(propName);
|
||||||
if((value!=null)&&(value.trim().length()>0)){
|
if ((value != null) && (value.trim().length() > 0)) {
|
||||||
completedFormFields.setProperty(propName, value);
|
completedFormFields.setProperty(propName, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try {
|
||||||
|
//Create an XML query by populating template with given user criteria
|
||||||
|
org.w3c.dom.Document xmlQuery = queryTemplateManager.getQueryAsDOM(completedFormFields);
|
||||||
|
|
||||||
//Create an XML query by populating template with given user criteria
|
//Parse the XML to produce a Lucene query
|
||||||
org.w3c.dom.Document xmlQuery=queryTemplateManager.getQueryAsDOM(completedFormFields);
|
Query query = xmlParser.getQuery(xmlQuery.getDocumentElement());
|
||||||
|
|
||||||
//Parse the XML to produce a Lucene query
|
//Run the query
|
||||||
Query query=xmlParser.getQuery(xmlQuery.getDocumentElement());
|
TopDocs topDocs = searcher.search(query, 10);
|
||||||
|
|
||||||
//Run the query
|
//and package the results and forward to JSP
|
||||||
TopDocs topDocs = searcher.search(query,10);
|
if (topDocs != null) {
|
||||||
|
ScoreDoc[] sd = topDocs.scoreDocs;
|
||||||
|
Document[] results = new Document[sd.length];
|
||||||
|
for (int i = 0; i < results.length; i++) {
|
||||||
|
results[i] = searcher.doc(sd[i].doc);
|
||||||
|
request.setAttribute("results", results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp");
|
||||||
|
dispatcher.forward(request, response);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new ServletException("Error processing query", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//and package the results and forward to JSP
|
private void openExampleIndex() throws CorruptIndexException, IOException {
|
||||||
if(topDocs!=null) {
|
//Create a RAM-based index from our test data file
|
||||||
ScoreDoc[] sd = topDocs.scoreDocs;
|
RAMDirectory rd = new RAMDirectory();
|
||||||
Document[] results=new Document[sd.length];
|
IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_40, analyzer);
|
||||||
for (int i = 0; i < results.length; i++) {
|
IndexWriter writer = new IndexWriter(rd, iwConfig);
|
||||||
results[i]=searcher.doc(sd[i].doc);
|
InputStream dataIn = getServletContext().getResourceAsStream("/WEB-INF/data.tsv");
|
||||||
request.setAttribute("results", results);
|
BufferedReader br = new BufferedReader(new InputStreamReader(dataIn));
|
||||||
}
|
String line = br.readLine();
|
||||||
}
|
while (line != null) {
|
||||||
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp");
|
line = line.trim();
|
||||||
dispatcher.forward(request,response);
|
if (line.length() > 0) {
|
||||||
}
|
//parse row and create a document
|
||||||
catch(Exception e){
|
StringTokenizer st = new StringTokenizer(line, "\t");
|
||||||
throw new ServletException("Error processing query",e);
|
Document doc = new Document();
|
||||||
}
|
doc.add(new Field("location", st.nextToken(), Field.Store.YES,
|
||||||
}
|
Field.Index.ANALYZED_NO_NORMS));
|
||||||
|
doc.add(new Field("salary", st.nextToken(), Field.Store.YES,
|
||||||
|
Field.Index.ANALYZED_NO_NORMS));
|
||||||
|
doc.add(new Field("type", st.nextToken(), Field.Store.YES,
|
||||||
|
Field.Index.ANALYZED_NO_NORMS));
|
||||||
|
doc.add(new Field("description", st.nextToken(), Field.Store.YES,
|
||||||
|
Field.Index.ANALYZED));
|
||||||
|
writer.addDocument(doc);
|
||||||
|
}
|
||||||
|
line = br.readLine();
|
||||||
|
}
|
||||||
|
writer.close();
|
||||||
|
|
||||||
private void openExampleIndex() throws CorruptIndexException, IOException {
|
//open searcher
|
||||||
|
searcher = new IndexSearcher(rd, true);
|
||||||
//Create a RAM-based index from our test data file
|
}
|
||||||
RAMDirectory rd=new RAMDirectory();
|
|
||||||
IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_40, analyzer);
|
|
||||||
IndexWriter writer=new IndexWriter (rd, iwConfig);
|
|
||||||
InputStream dataIn=getServletContext().getResourceAsStream("/WEB-INF/data.tsv");
|
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(dataIn));
|
|
||||||
String line = br.readLine();
|
|
||||||
while(line!=null)
|
|
||||||
{
|
|
||||||
line=line.trim();
|
|
||||||
if(line.length()>0)
|
|
||||||
{
|
|
||||||
//parse row and create a document
|
|
||||||
StringTokenizer st=new StringTokenizer(line,"\t");
|
|
||||||
Document doc=new Document();
|
|
||||||
doc.add(new Field("location",st.nextToken(),Field.Store.YES,
|
|
||||||
Field.Index.ANALYZED_NO_NORMS));
|
|
||||||
doc.add(new Field("salary",st.nextToken(),Field.Store.YES,
|
|
||||||
Field.Index.ANALYZED_NO_NORMS));
|
|
||||||
doc.add(new Field("type",st.nextToken(),Field.Store.YES,
|
|
||||||
Field.Index.ANALYZED_NO_NORMS));
|
|
||||||
doc.add(new Field("description",st.nextToken(),Field.Store.YES,
|
|
||||||
Field.Index.ANALYZED));
|
|
||||||
writer.addDocument(doc);
|
|
||||||
}
|
|
||||||
line=br.readLine();
|
|
||||||
}
|
|
||||||
writer.close();
|
|
||||||
|
|
||||||
//open searcher
|
|
||||||
searcher=new IndexSearcher(rd, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package org.apache.lucene.xmlparser;
|
package org.apache.lucene.xmlparser;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.queryparser.classic.QueryParser;
|
import org.apache.lucene.queryparser.classic.QueryParser;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
@ -12,6 +7,10 @@ import org.apache.lucene.xmlparser.builders.*;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -28,143 +27,130 @@ import org.w3c.dom.Element;
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assembles a QueryBuilder which uses only core Lucene Query objects
|
* Assembles a QueryBuilder which uses only core Lucene Query objects
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CoreParser implements QueryBuilder
|
public class CoreParser implements QueryBuilder {
|
||||||
{
|
|
||||||
|
protected Analyzer analyzer;
|
||||||
protected Analyzer analyzer;
|
protected QueryParser parser;
|
||||||
protected QueryParser parser;
|
protected QueryBuilderFactory queryFactory;
|
||||||
protected QueryBuilderFactory queryFactory;
|
protected FilterBuilderFactory filterFactory;
|
||||||
protected FilterBuilderFactory filterFactory;
|
//Controls the max size of the LRU cache used for QueryFilter objects parsed.
|
||||||
//Controls the max size of the LRU cache used for QueryFilter objects parsed.
|
public static int maxNumCachedFilters = 20;
|
||||||
public static int maxNumCachedFilters=20;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an XML parser that uses a single instance QueryParser for handling
|
* Construct an XML parser that uses a single instance QueryParser for handling
|
||||||
* UserQuery tags - all parse operations are synchronised on this parser
|
* UserQuery tags - all parse operations are synchronised on this parser
|
||||||
* @param analyzer
|
*
|
||||||
* @param parser A QueryParser which will be synchronized on during parse calls.
|
* @param analyzer
|
||||||
*/
|
* @param parser A QueryParser which will be synchronized on during parse calls.
|
||||||
public CoreParser(Analyzer analyzer, QueryParser parser)
|
*/
|
||||||
{
|
public CoreParser(Analyzer analyzer, QueryParser parser) {
|
||||||
this(null,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 CoreParser(String defaultField, Analyzer analyzer)
|
|
||||||
{
|
|
||||||
this(defaultField,analyzer,null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected CoreParser(String defaultField,Analyzer analyzer, QueryParser parser)
|
|
||||||
{
|
|
||||||
this.analyzer=analyzer;
|
|
||||||
this.parser=parser;
|
|
||||||
filterFactory = new FilterBuilderFactory();
|
|
||||||
filterFactory.addBuilder("RangeFilter",new RangeFilterBuilder());
|
|
||||||
filterFactory.addBuilder("NumericRangeFilter",new NumericRangeFilterBuilder());
|
|
||||||
|
|
||||||
queryFactory = new QueryBuilderFactory();
|
|
||||||
queryFactory.addBuilder("TermQuery",new TermQueryBuilder());
|
|
||||||
queryFactory.addBuilder("TermsQuery",new TermsQueryBuilder(analyzer));
|
|
||||||
queryFactory.addBuilder("MatchAllDocsQuery",new MatchAllDocsQueryBuilder());
|
|
||||||
queryFactory.addBuilder("BooleanQuery",new BooleanQueryBuilder(queryFactory));
|
|
||||||
queryFactory.addBuilder("NumericRangeQuery",new NumericRangeQueryBuilder());
|
|
||||||
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));
|
|
||||||
|
|
||||||
filterFactory.addBuilder("CachedFilter",new CachedFilterBuilder(queryFactory,
|
|
||||||
filterFactory, maxNumCachedFilters));
|
|
||||||
|
|
||||||
|
|
||||||
SpanQueryBuilderFactory sqof=new SpanQueryBuilderFactory();
|
|
||||||
|
|
||||||
SpanNearBuilder snb=new SpanNearBuilder(sqof);
|
/**
|
||||||
sqof.addBuilder("SpanNear",snb);
|
* Constructs an XML parser that creates a QueryParser for each UserQuery request.
|
||||||
queryFactory.addBuilder("SpanNear",snb);
|
*
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
|
||||||
BoostingTermBuilder btb=new BoostingTermBuilder();
|
protected CoreParser(String defaultField, Analyzer analyzer, QueryParser parser) {
|
||||||
sqof.addBuilder("BoostingTermQuery",btb);
|
this.analyzer = analyzer;
|
||||||
queryFactory.addBuilder("BoostingTermQuery",btb);
|
this.parser = parser;
|
||||||
|
filterFactory = new FilterBuilderFactory();
|
||||||
|
filterFactory.addBuilder("RangeFilter", new RangeFilterBuilder());
|
||||||
|
filterFactory.addBuilder("NumericRangeFilter", new NumericRangeFilterBuilder());
|
||||||
|
|
||||||
SpanTermBuilder snt=new SpanTermBuilder();
|
queryFactory = new QueryBuilderFactory();
|
||||||
sqof.addBuilder("SpanTerm",snt);
|
queryFactory.addBuilder("TermQuery", new TermQueryBuilder());
|
||||||
queryFactory.addBuilder("SpanTerm",snt);
|
queryFactory.addBuilder("TermsQuery", new TermsQueryBuilder(analyzer));
|
||||||
|
queryFactory.addBuilder("MatchAllDocsQuery", new MatchAllDocsQueryBuilder());
|
||||||
SpanOrBuilder sot=new SpanOrBuilder(sqof);
|
queryFactory.addBuilder("BooleanQuery", new BooleanQueryBuilder(queryFactory));
|
||||||
sqof.addBuilder("SpanOr",sot);
|
queryFactory.addBuilder("NumericRangeQuery", new NumericRangeQueryBuilder());
|
||||||
queryFactory.addBuilder("SpanOr",sot);
|
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));
|
||||||
|
|
||||||
SpanOrTermsBuilder sots=new SpanOrTermsBuilder(analyzer);
|
filterFactory.addBuilder("CachedFilter", new CachedFilterBuilder(queryFactory,
|
||||||
sqof.addBuilder("SpanOrTerms",sots);
|
filterFactory, maxNumCachedFilters));
|
||||||
queryFactory.addBuilder("SpanOrTerms",sots);
|
|
||||||
|
|
||||||
SpanFirstBuilder sft=new SpanFirstBuilder(sqof);
|
|
||||||
sqof.addBuilder("SpanFirst",sft);
|
|
||||||
queryFactory.addBuilder("SpanFirst",sft);
|
|
||||||
|
|
||||||
SpanNotBuilder snot=new SpanNotBuilder(sqof);
|
|
||||||
sqof.addBuilder("SpanNot",snot);
|
|
||||||
queryFactory.addBuilder("SpanNot",snot);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Query parse(InputStream xmlStream) throws ParserException
|
|
||||||
{
|
|
||||||
return getQuery(parseXML(xmlStream).getDocumentElement());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addQueryBuilder(String nodeName,QueryBuilder builder)
|
|
||||||
{
|
|
||||||
queryFactory.addBuilder(nodeName,builder);
|
|
||||||
}
|
|
||||||
public void addFilterBuilder(String nodeName,FilterBuilder builder)
|
|
||||||
{
|
|
||||||
filterFactory.addBuilder(nodeName,builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Document parseXML(InputStream pXmlFile) throws ParserException
|
|
||||||
{
|
|
||||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
|
||||||
DocumentBuilder db = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
db = dbf.newDocumentBuilder();
|
|
||||||
}
|
|
||||||
catch (Exception se)
|
|
||||||
{
|
|
||||||
throw new ParserException("XML Parser configuration error", se);
|
|
||||||
}
|
|
||||||
org.w3c.dom.Document doc = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
doc = db.parse(pXmlFile);
|
|
||||||
}
|
|
||||||
catch (Exception se)
|
|
||||||
{
|
|
||||||
throw new ParserException("Error parsing XML stream:" + se, se);
|
|
||||||
}
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Query getQuery(Element e) throws ParserException
|
|
||||||
{
|
SpanQueryBuilderFactory sqof = new SpanQueryBuilderFactory();
|
||||||
return queryFactory.getQuery(e);
|
|
||||||
|
SpanNearBuilder snb = new SpanNearBuilder(sqof);
|
||||||
|
sqof.addBuilder("SpanNear", snb);
|
||||||
|
queryFactory.addBuilder("SpanNear", snb);
|
||||||
|
|
||||||
|
BoostingTermBuilder btb = new BoostingTermBuilder();
|
||||||
|
sqof.addBuilder("BoostingTermQuery", btb);
|
||||||
|
queryFactory.addBuilder("BoostingTermQuery", btb);
|
||||||
|
|
||||||
|
SpanTermBuilder snt = new SpanTermBuilder();
|
||||||
|
sqof.addBuilder("SpanTerm", snt);
|
||||||
|
queryFactory.addBuilder("SpanTerm", snt);
|
||||||
|
|
||||||
|
SpanOrBuilder sot = new SpanOrBuilder(sqof);
|
||||||
|
sqof.addBuilder("SpanOr", sot);
|
||||||
|
queryFactory.addBuilder("SpanOr", sot);
|
||||||
|
|
||||||
|
SpanOrTermsBuilder sots = new SpanOrTermsBuilder(analyzer);
|
||||||
|
sqof.addBuilder("SpanOrTerms", sots);
|
||||||
|
queryFactory.addBuilder("SpanOrTerms", sots);
|
||||||
|
|
||||||
|
SpanFirstBuilder sft = new SpanFirstBuilder(sqof);
|
||||||
|
sqof.addBuilder("SpanFirst", sft);
|
||||||
|
queryFactory.addBuilder("SpanFirst", sft);
|
||||||
|
|
||||||
|
SpanNotBuilder snot = new SpanNotBuilder(sqof);
|
||||||
|
sqof.addBuilder("SpanNot", snot);
|
||||||
|
queryFactory.addBuilder("SpanNot", snot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query parse(InputStream xmlStream) throws ParserException {
|
||||||
|
return getQuery(parseXML(xmlStream).getDocumentElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addQueryBuilder(String nodeName, QueryBuilder builder) {
|
||||||
|
queryFactory.addBuilder(nodeName, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFilterBuilder(String nodeName, FilterBuilder builder) {
|
||||||
|
filterFactory.addBuilder(nodeName, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Document parseXML(InputStream pXmlFile) throws ParserException {
|
||||||
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder db = null;
|
||||||
|
try {
|
||||||
|
db = dbf.newDocumentBuilder();
|
||||||
|
}
|
||||||
|
catch (Exception se) {
|
||||||
|
throw new ParserException("XML Parser configuration error", se);
|
||||||
|
}
|
||||||
|
org.w3c.dom.Document doc = null;
|
||||||
|
try {
|
||||||
|
doc = db.parse(pXmlFile);
|
||||||
|
}
|
||||||
|
catch (Exception se) {
|
||||||
|
throw new ParserException("Error parsing XML stream:" + se, se);
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Query getQuery(Element e) throws ParserException {
|
||||||
|
return queryFactory.getQuery(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,7 @@ package org.apache.lucene.xmlparser;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.queryparser.classic.QueryParser;
|
import org.apache.lucene.queryparser.classic.QueryParser;
|
||||||
import org.apache.lucene.xmlparser.builders.BooleanFilterBuilder;
|
import org.apache.lucene.xmlparser.builders.*;
|
||||||
import org.apache.lucene.xmlparser.builders.BoostingQueryBuilder;
|
|
||||||
import org.apache.lucene.xmlparser.builders.DuplicateFilterBuilder;
|
|
||||||
import org.apache.lucene.xmlparser.builders.FuzzyLikeThisQueryBuilder;
|
|
||||||
import org.apache.lucene.xmlparser.builders.LikeThisQueryBuilder;
|
|
||||||
import org.apache.lucene.xmlparser.builders.TermsFilterBuilder;
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -26,41 +21,40 @@ import org.apache.lucene.xmlparser.builders.TermsFilterBuilder;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CorePlusExtensionsParser extends CoreParser
|
public class CorePlusExtensionsParser extends CoreParser {
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an XML parser that uses a single instance QueryParser for handling
|
* Construct an XML parser that uses a single instance QueryParser for handling
|
||||||
* UserQuery tags - all parse operations are synchronized on this parser
|
* UserQuery tags - all parse operations are synchronized on this parser
|
||||||
* @param analyzer
|
*
|
||||||
* @param parser A QueryParser which will be synchronized on during parse calls.
|
* @param analyzer
|
||||||
*/
|
* @param parser A QueryParser which will be synchronized on during parse calls.
|
||||||
public CorePlusExtensionsParser(Analyzer analyzer, QueryParser parser)
|
*/
|
||||||
{
|
public CorePlusExtensionsParser(Analyzer analyzer, QueryParser parser) {
|
||||||
this(null,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)
|
/**
|
||||||
{
|
* Constructs an XML parser that creates a QueryParser for each UserQuery request.
|
||||||
super(defaultField,analyzer, parser);
|
*
|
||||||
filterFactory.addBuilder("TermsFilter",new TermsFilterBuilder(analyzer));
|
* @param defaultField The default field name used by QueryParsers constructed for UserQuery tags
|
||||||
filterFactory.addBuilder("BooleanFilter",new BooleanFilterBuilder(filterFactory));
|
* @param analyzer
|
||||||
filterFactory.addBuilder("DuplicateFilter",new DuplicateFilterBuilder());
|
*/
|
||||||
String fields[]={"contents"};
|
public CorePlusExtensionsParser(String defaultField, Analyzer analyzer) {
|
||||||
queryFactory.addBuilder("LikeThisQuery",new LikeThisQueryBuilder(analyzer,fields));
|
this(defaultField, analyzer, null);
|
||||||
queryFactory.addBuilder("BoostingQuery", new BoostingQueryBuilder(queryFactory));
|
}
|
||||||
queryFactory.addBuilder("FuzzyLikeThisQuery", new FuzzyLikeThisQueryBuilder(analyzer));
|
|
||||||
|
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());
|
||||||
|
String fields[] = {"contents"};
|
||||||
|
queryFactory.addBuilder("LikeThisQuery", new LikeThisQueryBuilder(analyzer, fields));
|
||||||
|
queryFactory.addBuilder("BoostingQuery", new BoostingQueryBuilder(queryFactory));
|
||||||
|
queryFactory.addBuilder("FuzzyLikeThisQuery", new FuzzyLikeThisQueryBuilder(analyzer));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package org.apache.lucene.xmlparser;
|
package org.apache.lucene.xmlparser;
|
||||||
import java.io.Reader;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import java.io.Reader;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -26,253 +26,192 @@ import org.xml.sax.InputSource;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DOMUtils
|
public class DOMUtils {
|
||||||
{
|
|
||||||
public static Element getChildByTagOrFail(Element e, String name) throws ParserException
|
|
||||||
{
|
|
||||||
Element kid = getChildByTagName(e, name);
|
|
||||||
if (null == kid)
|
|
||||||
{
|
|
||||||
throw new ParserException(e.getTagName() + " missing \"" + name
|
|
||||||
+ "\" child element");
|
|
||||||
}
|
|
||||||
return kid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Element getFirstChildOrFail(Element e) throws ParserException
|
|
||||||
{
|
|
||||||
Element kid = getFirstChildElement(e);
|
|
||||||
if (null == kid)
|
|
||||||
{
|
|
||||||
throw new ParserException(e.getTagName()
|
|
||||||
+ " does not contain a child element");
|
|
||||||
}
|
|
||||||
return kid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAttributeOrFail(Element e, String name) throws ParserException
|
|
||||||
{
|
|
||||||
String v = e.getAttribute(name);
|
|
||||||
if (null == v)
|
|
||||||
{
|
|
||||||
throw new ParserException(e.getTagName() + " missing \"" + name
|
|
||||||
+ "\" attribute");
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
public static String getAttributeWithInheritanceOrFail(Element e, String name) throws ParserException
|
|
||||||
{
|
|
||||||
String v = getAttributeWithInheritance(e, name);
|
|
||||||
if (null == v)
|
|
||||||
{
|
|
||||||
throw new ParserException(e.getTagName() + " missing \"" + name
|
|
||||||
+ "\" attribute");
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
public static String getNonBlankTextOrFail(Element e) throws ParserException
|
|
||||||
{
|
|
||||||
String v = getText(e);
|
|
||||||
if (null != v)
|
|
||||||
v = v.trim();
|
|
||||||
if (null == v || 0 == v.length())
|
|
||||||
{
|
|
||||||
throw new ParserException(e.getTagName() + " has no text");
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Convenience method where there is only one child Element of a given name */
|
|
||||||
public static Element getChildByTagName(Element e, String name)
|
|
||||||
{
|
|
||||||
for (Node kid = e.getFirstChild(); kid != null; kid = kid.getNextSibling())
|
|
||||||
{
|
|
||||||
if( (kid.getNodeType()==Node.ELEMENT_NODE) && (name.equals(kid.getNodeName())) )
|
|
||||||
{
|
|
||||||
return (Element)kid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public static Element getChildByTagOrFail(Element e, String name) throws ParserException {
|
||||||
* Returns an attribute value from this node, or first parent node with this attribute defined
|
Element kid = getChildByTagName(e, name);
|
||||||
* @param element
|
if (null == kid) {
|
||||||
* @param attributeName
|
throw new ParserException(e.getTagName() + " missing \"" + name
|
||||||
* @return A non-zero-length value if defined, otherwise null
|
+ "\" child element");
|
||||||
*/
|
}
|
||||||
public static String getAttributeWithInheritance(Element element, String attributeName)
|
return kid;
|
||||||
{
|
}
|
||||||
String result=element.getAttribute(attributeName);
|
|
||||||
if( (result==null)|| ("".equals(result) ) )
|
public static Element getFirstChildOrFail(Element e) throws ParserException {
|
||||||
{
|
Element kid = getFirstChildElement(e);
|
||||||
Node n=element.getParentNode();
|
if (null == kid) {
|
||||||
if((n==element)||(n==null))
|
throw new ParserException(e.getTagName()
|
||||||
{
|
+ " does not contain a child element");
|
||||||
return null;
|
}
|
||||||
}
|
return kid;
|
||||||
if(n instanceof Element)
|
}
|
||||||
{
|
|
||||||
Element parent=(Element) n;
|
public static String getAttributeOrFail(Element e, String name) throws ParserException {
|
||||||
return getAttributeWithInheritance(parent,attributeName);
|
String v = e.getAttribute(name);
|
||||||
}
|
if (null == v) {
|
||||||
return null; //we reached the top level of the document without finding attribute
|
throw new ParserException(e.getTagName() + " missing \"" + name
|
||||||
}
|
+ "\" attribute");
|
||||||
return result;
|
}
|
||||||
}
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAttributeWithInheritanceOrFail(Element e, String name) throws ParserException {
|
||||||
|
String v = getAttributeWithInheritance(e, name);
|
||||||
|
if (null == v) {
|
||||||
|
throw new ParserException(e.getTagName() + " missing \"" + name
|
||||||
|
+ "\" attribute");
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNonBlankTextOrFail(Element e) throws ParserException {
|
||||||
|
String v = getText(e);
|
||||||
|
if (null != v)
|
||||||
|
v = v.trim();
|
||||||
|
if (null == v || 0 == v.length()) {
|
||||||
|
throw new ParserException(e.getTagName() + " has no text");
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convenience method where there is only one child Element of a given name */
|
||||||
|
public static Element getChildByTagName(Element e, String name) {
|
||||||
|
for (Node kid = e.getFirstChild(); kid != null; kid = kid.getNextSibling()) {
|
||||||
|
if ((kid.getNodeType() == Node.ELEMENT_NODE) && (name.equals(kid.getNodeName()))) {
|
||||||
|
return (Element) kid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an attribute value from this node, or first parent node with this attribute defined
|
||||||
|
*
|
||||||
|
* @param element
|
||||||
|
* @param attributeName
|
||||||
|
* @return A non-zero-length value if defined, otherwise null
|
||||||
|
*/
|
||||||
|
public static String getAttributeWithInheritance(Element element, String attributeName) {
|
||||||
|
String result = element.getAttribute(attributeName);
|
||||||
|
if ((result == null) || ("".equals(result))) {
|
||||||
|
Node n = element.getParentNode();
|
||||||
|
if ((n == element) || (n == null)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (n instanceof Element) {
|
||||||
|
Element parent = (Element) n;
|
||||||
|
return getAttributeWithInheritance(parent, attributeName);
|
||||||
|
}
|
||||||
|
return null; //we reached the top level of the document without finding attribute
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convenience method where there is only one child Element of a given name */
|
||||||
|
public static String getChildTextByTagName(Element e, String tagName) {
|
||||||
|
Element child = getChildByTagName(e, tagName);
|
||||||
|
return child != null ? getText(child) : null;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convenience method where there is only one child Element of a given name */
|
/* Convenience method to append a new child with text*/
|
||||||
public static String getChildTextByTagName(Element e, String tagName)
|
public static Element insertChild(Element parent, String tagName, String text) {
|
||||||
{
|
Element child = parent.getOwnerDocument().createElement(tagName);
|
||||||
Element child=getChildByTagName(e,tagName);
|
parent.appendChild(child);
|
||||||
if(child!=null)
|
if (text != null) {
|
||||||
{
|
child.appendChild(child.getOwnerDocument().createTextNode(text));
|
||||||
return getText(child);
|
}
|
||||||
}
|
return child;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Convenience method to append a new child with text*/
|
public static String getAttribute(Element element, String attributeName, String deflt) {
|
||||||
public static Element insertChild(Element parent, String tagName, String text)
|
String result = element.getAttribute(attributeName);
|
||||||
{
|
return (result == null) || ("".equals(result)) ? deflt : result;
|
||||||
Element child = parent.getOwnerDocument().createElement(tagName);
|
}
|
||||||
parent.appendChild(child);
|
|
||||||
if(text!=null)
|
|
||||||
{
|
|
||||||
child.appendChild(child.getOwnerDocument().createTextNode(text));
|
|
||||||
}
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAttribute(Element element, String attributeName, String deflt)
|
public static float getAttribute(Element element, String attributeName, float deflt) {
|
||||||
{
|
String result = element.getAttribute(attributeName);
|
||||||
String result=element.getAttribute(attributeName);
|
return (result == null) || ("".equals(result)) ? deflt : Float.parseFloat(result);
|
||||||
if( (result==null)|| ("".equals(result) ) )
|
}
|
||||||
{
|
|
||||||
return deflt;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
public static float getAttribute(Element element, String attributeName, float deflt)
|
|
||||||
{
|
|
||||||
String result=element.getAttribute(attributeName);
|
|
||||||
if( (result==null)|| ("".equals(result) ) )
|
|
||||||
{
|
|
||||||
return deflt;
|
|
||||||
}
|
|
||||||
return Float.parseFloat(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getAttribute(Element element, String attributeName, int deflt)
|
public static int getAttribute(Element element, String attributeName, int deflt) {
|
||||||
{
|
String result = element.getAttribute(attributeName);
|
||||||
String result=element.getAttribute(attributeName);
|
return (result == null) || ("".equals(result)) ? deflt : Integer.parseInt(result);
|
||||||
if( (result==null)|| ("".equals(result) ) )
|
}
|
||||||
{
|
|
||||||
return deflt;
|
|
||||||
}
|
|
||||||
return Integer.parseInt(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getAttribute(Element element, String attributeName,
|
|
||||||
boolean deflt)
|
|
||||||
{
|
|
||||||
String result = element.getAttribute(attributeName);
|
|
||||||
if ((result == null) || ("".equals(result)))
|
|
||||||
{
|
|
||||||
return deflt;
|
|
||||||
}
|
|
||||||
return Boolean.valueOf(result).booleanValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns text of node and all child nodes - without markup */
|
public static boolean getAttribute(Element element, String attributeName,
|
||||||
//MH changed to Node from Element 25/11/2005
|
boolean deflt) {
|
||||||
public static String getText(Node e)
|
String result = element.getAttribute(attributeName);
|
||||||
{
|
return (result == null) || ("".equals(result)) ? deflt : Boolean.valueOf(result);
|
||||||
StringBuilder sb=new StringBuilder();
|
}
|
||||||
getTextBuffer(e, sb);
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Element getFirstChildElement(Element element)
|
|
||||||
{
|
|
||||||
for (Node kid = element.getFirstChild(); kid != null; kid = kid
|
|
||||||
.getNextSibling())
|
|
||||||
{
|
|
||||||
if (kid.getNodeType() == Node.ELEMENT_NODE)
|
|
||||||
{
|
|
||||||
return (Element) kid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void getTextBuffer(Node e, StringBuilder sb)
|
/* Returns text of node and all child nodes - without markup */
|
||||||
{
|
//MH changed to Node from Element 25/11/2005
|
||||||
for (Node kid = e.getFirstChild(); kid != null; kid = kid.getNextSibling())
|
|
||||||
{
|
|
||||||
switch(kid.getNodeType())
|
|
||||||
{
|
|
||||||
case Node.TEXT_NODE:
|
|
||||||
{
|
|
||||||
sb.append(kid.getNodeValue());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Node.ELEMENT_NODE:
|
|
||||||
{
|
|
||||||
getTextBuffer(kid, sb);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Node.ENTITY_REFERENCE_NODE:
|
|
||||||
{
|
|
||||||
getTextBuffer(kid, sb);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public static String getText(Node e) {
|
||||||
* Helper method to parse an XML file into a DOM tree, given a reader.
|
StringBuilder sb = new StringBuilder();
|
||||||
* @param is reader of the XML file to be parsed
|
getTextBuffer(e, sb);
|
||||||
* @return an org.w3c.dom.Document object
|
return sb.toString();
|
||||||
*/
|
}
|
||||||
public static Document loadXML(Reader is)
|
|
||||||
{
|
|
||||||
|
|
||||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
public static Element getFirstChildElement(Element element) {
|
||||||
DocumentBuilder db = null;
|
for (Node kid = element.getFirstChild(); kid != null; kid = kid.getNextSibling()) {
|
||||||
|
if (kid.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
try
|
return (Element) kid;
|
||||||
{
|
}
|
||||||
db = dbf.newDocumentBuilder();
|
}
|
||||||
}
|
return null;
|
||||||
catch (Exception se)
|
}
|
||||||
{
|
|
||||||
throw new RuntimeException("Parser configuration error", se);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: parse the input file
|
private static void getTextBuffer(Node e, StringBuilder sb) {
|
||||||
org.w3c.dom.Document doc = null;
|
for (Node kid = e.getFirstChild(); kid != null; kid = kid.getNextSibling()) {
|
||||||
try
|
switch (kid.getNodeType()) {
|
||||||
{
|
case Node.TEXT_NODE: {
|
||||||
doc = db.parse(new InputSource(is));
|
sb.append(kid.getNodeValue());
|
||||||
//doc = db.parse(is);
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception se)
|
case Node.ELEMENT_NODE: {
|
||||||
{
|
getTextBuffer(kid, sb);
|
||||||
throw new RuntimeException("Error parsing file:" + se, se);
|
break;
|
||||||
}
|
}
|
||||||
|
case Node.ENTITY_REFERENCE_NODE: {
|
||||||
|
getTextBuffer(kid, sb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return doc;
|
/**
|
||||||
|
* Helper method to parse an XML file into a DOM tree, given a reader.
|
||||||
|
*
|
||||||
|
* @param is reader of the XML file to be parsed
|
||||||
|
* @return an org.w3c.dom.Document object
|
||||||
|
*/
|
||||||
|
public static Document loadXML(Reader is) {
|
||||||
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder db = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
db = dbf.newDocumentBuilder();
|
||||||
|
}
|
||||||
|
catch (Exception se) {
|
||||||
|
throw new RuntimeException("Parser configuration error", se);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: parse the input file
|
||||||
|
org.w3c.dom.Document doc = null;
|
||||||
|
try {
|
||||||
|
doc = db.parse(new InputSource(is));
|
||||||
|
//doc = db.parse(is);
|
||||||
|
}
|
||||||
|
catch (Exception se) {
|
||||||
|
throw new RuntimeException("Error parsing file:" + se, se);
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,5 +26,6 @@ import org.w3c.dom.Element;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface FilterBuilder {
|
public interface FilterBuilder {
|
||||||
|
|
||||||
public Filter getFilter(Element e) throws ParserException;
|
public Filter getFilter(Element e) throws ParserException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.lucene.xmlparser;
|
package org.apache.lucene.xmlparser;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.Filter;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -25,26 +25,25 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class FilterBuilderFactory implements FilterBuilder {
|
public class FilterBuilderFactory implements FilterBuilder {
|
||||||
|
|
||||||
HashMap<String,FilterBuilder> builders=new HashMap<String,FilterBuilder>();
|
HashMap<String, FilterBuilder> builders = new HashMap<String, FilterBuilder>();
|
||||||
|
|
||||||
public Filter getFilter(Element n) throws ParserException {
|
public Filter getFilter(Element n) throws ParserException {
|
||||||
FilterBuilder builder= builders.get(n.getNodeName());
|
FilterBuilder builder = builders.get(n.getNodeName());
|
||||||
if(builder==null)
|
if (builder == null) {
|
||||||
{
|
throw new ParserException("No FilterBuilder defined for node " + n.getNodeName());
|
||||||
throw new ParserException("No FilterBuilder defined for node "+n.getNodeName());
|
}
|
||||||
}
|
return builder.getFilter(n);
|
||||||
return builder.getFilter(n);
|
}
|
||||||
}
|
|
||||||
public void addBuilder(String nodeName,FilterBuilder builder)
|
public void addBuilder(String nodeName, FilterBuilder builder) {
|
||||||
{
|
builders.put(nodeName, builder);
|
||||||
builders.put(nodeName,builder);
|
}
|
||||||
}
|
|
||||||
public FilterBuilder getFilterBuilder(String nodeName)
|
public FilterBuilder getFilterBuilder(String nodeName) {
|
||||||
{
|
return builders.get(nodeName);
|
||||||
return builders.get(nodeName);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,12 +30,14 @@ public class ParserException extends Exception {
|
||||||
public ParserException() {
|
public ParserException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param message
|
* @param message
|
||||||
*/
|
*/
|
||||||
public ParserException(String message) {
|
public ParserException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param message
|
* @param message
|
||||||
* @param cause
|
* @param cause
|
||||||
|
@ -43,6 +45,7 @@ public class ParserException extends Exception {
|
||||||
public ParserException(String message, Throwable cause) {
|
public ParserException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param cause
|
* @param cause
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,5 +25,4 @@ import org.w3c.dom.Element;
|
||||||
public interface QueryBuilder {
|
public interface QueryBuilder {
|
||||||
|
|
||||||
public Query getQuery(Element e) throws ParserException;
|
public Query getQuery(Element e) throws ParserException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.lucene.xmlparser;
|
package org.apache.lucene.xmlparser;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -25,27 +25,26 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class QueryBuilderFactory implements QueryBuilder {
|
public class QueryBuilderFactory implements QueryBuilder {
|
||||||
|
|
||||||
HashMap<String,QueryBuilder> builders=new HashMap<String,QueryBuilder>();
|
HashMap<String, QueryBuilder> builders = new HashMap<String, QueryBuilder>();
|
||||||
|
|
||||||
public Query getQuery(Element n) throws ParserException {
|
public Query getQuery(Element n) throws ParserException {
|
||||||
QueryBuilder builder= builders.get(n.getNodeName());
|
QueryBuilder builder = builders.get(n.getNodeName());
|
||||||
if(builder==null)
|
if (builder == null) {
|
||||||
{
|
throw new ParserException("No QueryObjectBuilder defined for node " + n.getNodeName());
|
||||||
throw new ParserException("No QueryObjectBuilder defined for node "+n.getNodeName());
|
}
|
||||||
}
|
return builder.getQuery(n);
|
||||||
return builder.getQuery(n);
|
}
|
||||||
}
|
|
||||||
public void addBuilder(String nodeName,QueryBuilder builder)
|
public void addBuilder(String nodeName, QueryBuilder builder) {
|
||||||
{
|
builders.put(nodeName, builder);
|
||||||
builders.put(nodeName,builder);
|
}
|
||||||
}
|
|
||||||
public QueryBuilder getQueryBuilder(String nodeName)
|
public QueryBuilder getQueryBuilder(String nodeName) {
|
||||||
{
|
return builders.get(nodeName);
|
||||||
return builders.get(nodeName);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
package org.apache.lucene.xmlparser;
|
package org.apache.lucene.xmlparser;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.*;
|
||||||
|
import javax.xml.transform.dom.DOMResult;
|
||||||
|
import javax.xml.transform.dom.DOMSource;
|
||||||
|
import javax.xml.transform.stream.StreamResult;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -7,23 +18,6 @@ import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import javax.xml.transform.Result;
|
|
||||||
import javax.xml.transform.Templates;
|
|
||||||
import javax.xml.transform.Transformer;
|
|
||||||
import javax.xml.transform.TransformerConfigurationException;
|
|
||||||
import javax.xml.transform.TransformerException;
|
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
import javax.xml.transform.dom.DOMResult;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
|
||||||
import javax.xml.transform.stream.StreamResult;
|
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -40,171 +34,168 @@ import org.xml.sax.SAXException;
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides utilities for turning query form input (such as from a web page or Swing gui) into
|
* Provides utilities for turning query form input (such as from a web page or Swing gui) into
|
||||||
* Lucene XML queries by using XSL templates. This approach offers a convenient way of externalizing
|
* Lucene XML queries by using XSL templates. This approach offers a convenient way of externalizing
|
||||||
* and changing how user input is turned into Lucene queries.
|
* and changing how user input is turned into Lucene queries.
|
||||||
* Database applications often adopt similar practices by externalizing SQL in template files that can
|
* Database applications often adopt similar practices by externalizing SQL in template files that can
|
||||||
* be easily changed/optimized by a DBA.
|
* be easily changed/optimized by a DBA.
|
||||||
* The static methods can be used on their own or by creating an instance of this class you can store and
|
* The static methods can be used on their own or by creating an instance of this class you can store and
|
||||||
* re-use compiled stylesheets for fast use (e.g. in a server environment)
|
* re-use compiled stylesheets for fast use (e.g. in a server environment)
|
||||||
*/
|
*/
|
||||||
public class QueryTemplateManager
|
public class QueryTemplateManager {
|
||||||
{
|
static final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||||
static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ();
|
static final TransformerFactory tFactory = TransformerFactory.newInstance();
|
||||||
static TransformerFactory tFactory = TransformerFactory.newInstance();
|
|
||||||
|
|
||||||
HashMap<String,Templates> compiledTemplatesCache=new HashMap<String,Templates>();
|
HashMap<String, Templates> compiledTemplatesCache = new HashMap<String, Templates>();
|
||||||
Templates defaultCompiledTemplates=null;
|
Templates defaultCompiledTemplates = null;
|
||||||
|
|
||||||
|
|
||||||
public QueryTemplateManager()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
public QueryTemplateManager(InputStream xslIs) throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException
|
|
||||||
{
|
|
||||||
addDefaultQueryTemplate(xslIs);
|
|
||||||
}
|
|
||||||
public void addDefaultQueryTemplate(InputStream xslIs) throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException
|
|
||||||
{
|
|
||||||
defaultCompiledTemplates=getTemplates(xslIs);
|
|
||||||
}
|
|
||||||
public void addQueryTemplate(String name, InputStream xslIs) throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException
|
|
||||||
{
|
|
||||||
compiledTemplatesCache.put(name,getTemplates(xslIs));
|
|
||||||
}
|
|
||||||
public String getQueryAsXmlString(Properties formProperties,String queryTemplateName) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
|
||||||
{
|
|
||||||
Templates ts= compiledTemplatesCache.get(queryTemplateName);
|
|
||||||
return getQueryAsXmlString(formProperties, ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Document getQueryAsDOM(Properties formProperties,String queryTemplateName) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
|
||||||
{
|
|
||||||
Templates ts= compiledTemplatesCache.get(queryTemplateName);
|
|
||||||
return getQueryAsDOM(formProperties, ts);
|
|
||||||
}
|
|
||||||
public String getQueryAsXmlString(Properties formProperties) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
|
||||||
{
|
|
||||||
return getQueryAsXmlString(formProperties, defaultCompiledTemplates);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Document getQueryAsDOM(Properties formProperties) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
|
||||||
{
|
|
||||||
return getQueryAsDOM(formProperties, defaultCompiledTemplates);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fast means of constructing query using a precompiled stylesheet
|
|
||||||
*/
|
|
||||||
public static String getQueryAsXmlString(Properties formProperties, Templates template) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
|
||||||
{
|
|
||||||
ByteArrayOutputStream baos=new ByteArrayOutputStream();
|
|
||||||
StreamResult result=new StreamResult(baos);
|
|
||||||
transformCriteria(formProperties,template,result);
|
|
||||||
return baos.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Slow means of constructing query parsing a stylesheet from an input stream
|
|
||||||
*/
|
|
||||||
public static String getQueryAsXmlString(Properties formProperties, InputStream xslIs) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
|
||||||
{
|
|
||||||
ByteArrayOutputStream baos=new ByteArrayOutputStream();
|
|
||||||
StreamResult result=new StreamResult(baos);
|
|
||||||
transformCriteria(formProperties,xslIs,result);
|
|
||||||
return baos.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
public QueryTemplateManager() {
|
||||||
* Fast means of constructing query using a cached,precompiled stylesheet
|
|
||||||
*/
|
|
||||||
public static Document getQueryAsDOM(Properties formProperties, Templates template) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
|
||||||
{
|
|
||||||
DOMResult result=new DOMResult();
|
|
||||||
transformCriteria(formProperties,template,result);
|
|
||||||
return (Document)result.getNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Slow means of constructing query - parses stylesheet from input stream
|
public QueryTemplateManager(InputStream xslIs)
|
||||||
*/
|
throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException {
|
||||||
public static Document getQueryAsDOM(Properties formProperties, InputStream xslIs) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
addDefaultQueryTemplate(xslIs);
|
||||||
{
|
}
|
||||||
DOMResult result=new DOMResult();
|
|
||||||
transformCriteria(formProperties,xslIs,result);
|
public void addDefaultQueryTemplate(InputStream xslIs)
|
||||||
return (Document)result.getNode();
|
throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException {
|
||||||
}
|
defaultCompiledTemplates = getTemplates(xslIs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addQueryTemplate(String name, InputStream xslIs)
|
||||||
|
throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException {
|
||||||
/**
|
compiledTemplatesCache.put(name, getTemplates(xslIs));
|
||||||
* Slower transformation using an uncompiled stylesheet (suitable for development environment)
|
}
|
||||||
*/
|
|
||||||
public static void transformCriteria(Properties formProperties, InputStream xslIs, Result result) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
public String getQueryAsXmlString(Properties formProperties, String queryTemplateName)
|
||||||
{
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
dbf.setNamespaceAware(true);
|
Templates ts = compiledTemplatesCache.get(queryTemplateName);
|
||||||
DocumentBuilder builder = dbf.newDocumentBuilder();
|
return getQueryAsXmlString(formProperties, ts);
|
||||||
org.w3c.dom.Document xslDoc = builder.parse(xslIs);
|
}
|
||||||
DOMSource ds = new DOMSource(xslDoc);
|
|
||||||
|
public Document getQueryAsDOM(Properties formProperties, String queryTemplateName)
|
||||||
Transformer transformer =null;
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
synchronized (tFactory)
|
Templates ts = compiledTemplatesCache.get(queryTemplateName);
|
||||||
{
|
return getQueryAsDOM(formProperties, ts);
|
||||||
transformer = tFactory.newTransformer(ds);
|
}
|
||||||
}
|
|
||||||
transformCriteria(formProperties,transformer,result);
|
public String getQueryAsXmlString(Properties formProperties)
|
||||||
}
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
|
return getQueryAsXmlString(formProperties, defaultCompiledTemplates);
|
||||||
/**
|
}
|
||||||
* Fast transformation using a pre-compiled stylesheet (suitable for production environments)
|
|
||||||
*/
|
public Document getQueryAsDOM(Properties formProperties)
|
||||||
public static void transformCriteria(Properties formProperties, Templates template, Result result) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
{
|
return getQueryAsDOM(formProperties, defaultCompiledTemplates);
|
||||||
transformCriteria(formProperties,template.newTransformer(),result);
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Fast means of constructing query using a precompiled stylesheet
|
||||||
|
*/
|
||||||
public static void transformCriteria(Properties formProperties, Transformer transformer, Result result) throws SAXException, IOException, ParserConfigurationException, TransformerException
|
public static String getQueryAsXmlString(Properties formProperties, Templates template)
|
||||||
{
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
dbf.setNamespaceAware(true);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
StreamResult result = new StreamResult(baos);
|
||||||
//Create an XML document representing the search index document.
|
transformCriteria(formProperties, template, result);
|
||||||
DocumentBuilder db = dbf.newDocumentBuilder ();
|
return baos.toString();
|
||||||
org.w3c.dom.Document doc = db.newDocument ();
|
}
|
||||||
Element root = doc.createElement ("Document");
|
|
||||||
doc.appendChild (root);
|
/**
|
||||||
|
* Slow means of constructing query parsing a stylesheet from an input stream
|
||||||
Enumeration keysEnum = formProperties.keys();
|
*/
|
||||||
while(keysEnum.hasMoreElements())
|
public static String getQueryAsXmlString(Properties formProperties, InputStream xslIs)
|
||||||
{
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
String propName=(String) keysEnum.nextElement();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
String value=formProperties.getProperty(propName);
|
StreamResult result = new StreamResult(baos);
|
||||||
if((value!=null)&&(value.length()>0))
|
transformCriteria(formProperties, xslIs, result);
|
||||||
{
|
return baos.toString();
|
||||||
DOMUtils.insertChild(root,propName,value);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
//Use XSLT to to transform into an XML query string using the queryTemplate
|
/**
|
||||||
DOMSource xml=new DOMSource(doc);
|
* Fast means of constructing query using a cached,precompiled stylesheet
|
||||||
transformer.transform(xml,result);
|
*/
|
||||||
}
|
public static Document getQueryAsDOM(Properties formProperties, Templates template)
|
||||||
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
/**
|
DOMResult result = new DOMResult();
|
||||||
* Parses a query stylesheet for repeated use
|
transformCriteria(formProperties, template, result);
|
||||||
*/
|
return (Document) result.getNode();
|
||||||
public static Templates getTemplates(InputStream xslIs) throws ParserConfigurationException, SAXException, IOException, TransformerConfigurationException
|
}
|
||||||
{
|
|
||||||
dbf.setNamespaceAware(true);
|
|
||||||
DocumentBuilder builder = dbf.newDocumentBuilder();
|
/**
|
||||||
org.w3c.dom.Document xslDoc = builder.parse(xslIs);
|
* Slow means of constructing query - parses stylesheet from input stream
|
||||||
DOMSource ds = new DOMSource(xslDoc);
|
*/
|
||||||
return tFactory.newTemplates(ds);
|
public static Document getQueryAsDOM(Properties formProperties, InputStream xslIs)
|
||||||
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
|
DOMResult result = new DOMResult();
|
||||||
|
transformCriteria(formProperties, xslIs, result);
|
||||||
|
return (Document) result.getNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slower transformation using an uncompiled stylesheet (suitable for development environment)
|
||||||
|
*/
|
||||||
|
public static void transformCriteria(Properties formProperties, InputStream xslIs, Result result)
|
||||||
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
|
dbf.setNamespaceAware(true);
|
||||||
|
DocumentBuilder builder = dbf.newDocumentBuilder();
|
||||||
|
org.w3c.dom.Document xslDoc = builder.parse(xslIs);
|
||||||
|
DOMSource ds = new DOMSource(xslDoc);
|
||||||
|
|
||||||
|
Transformer transformer = null;
|
||||||
|
synchronized (tFactory) {
|
||||||
|
transformer = tFactory.newTransformer(ds);
|
||||||
|
}
|
||||||
|
transformCriteria(formProperties, transformer, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fast transformation using a pre-compiled stylesheet (suitable for production environments)
|
||||||
|
*/
|
||||||
|
public static void transformCriteria(Properties formProperties, Templates template, Result result)
|
||||||
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
|
transformCriteria(formProperties, template.newTransformer(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void transformCriteria(Properties formProperties, Transformer transformer, Result result)
|
||||||
|
throws SAXException, IOException, ParserConfigurationException, TransformerException {
|
||||||
|
dbf.setNamespaceAware(true);
|
||||||
|
|
||||||
|
//Create an XML document representing the search index document.
|
||||||
|
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||||
|
org.w3c.dom.Document doc = db.newDocument();
|
||||||
|
Element root = doc.createElement("Document");
|
||||||
|
doc.appendChild(root);
|
||||||
|
|
||||||
|
Enumeration keysEnum = formProperties.keys();
|
||||||
|
while (keysEnum.hasMoreElements()) {
|
||||||
|
String propName = (String) keysEnum.nextElement();
|
||||||
|
String value = formProperties.getProperty(propName);
|
||||||
|
if ((value != null) && (value.length() > 0)) {
|
||||||
|
DOMUtils.insertChild(root, propName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Use XSLT to to transform into an XML query string using the queryTemplate
|
||||||
|
DOMSource xml = new DOMSource(doc);
|
||||||
|
transformer.transform(xml, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a query stylesheet for repeated use
|
||||||
|
*/
|
||||||
|
public static Templates getTemplates(InputStream xslIs)
|
||||||
|
throws ParserConfigurationException, SAXException, IOException, TransformerConfigurationException {
|
||||||
|
dbf.setNamespaceAware(true);
|
||||||
|
DocumentBuilder builder = dbf.newDocumentBuilder();
|
||||||
|
org.w3c.dom.Document xslDoc = builder.parse(xslIs);
|
||||||
|
DOMSource ds = new DOMSource(xslDoc);
|
||||||
|
return tFactory.newTemplates(ds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,36 +32,33 @@ import org.w3c.dom.NodeList;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BooleanFilterBuilder implements FilterBuilder {
|
public class BooleanFilterBuilder implements FilterBuilder {
|
||||||
|
|
||||||
private FilterBuilder factory;
|
|
||||||
|
|
||||||
public BooleanFilterBuilder(FilterBuilder factory)
|
private final FilterBuilder factory;
|
||||||
{
|
|
||||||
this.factory=factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Filter getFilter(Element e) throws ParserException {
|
public BooleanFilterBuilder(FilterBuilder factory) {
|
||||||
BooleanFilter bf=new BooleanFilter();
|
this.factory = factory;
|
||||||
NodeList nl = e.getChildNodes();
|
}
|
||||||
|
|
||||||
for(int i=0;i<nl.getLength();i++)
|
public Filter getFilter(Element e) throws ParserException {
|
||||||
{
|
BooleanFilter bf = new BooleanFilter();
|
||||||
Node node = nl.item(i);
|
NodeList nl = e.getChildNodes();
|
||||||
if(node.getNodeName().equals("Clause"))
|
|
||||||
{
|
for (int i = 0; i < nl.getLength(); i++) {
|
||||||
Element clauseElem=(Element) node;
|
Node node = nl.item(i);
|
||||||
BooleanClause.Occur occurs=BooleanQueryBuilder.getOccursValue(clauseElem);
|
if (node.getNodeName().equals("Clause")) {
|
||||||
|
Element clauseElem = (Element) node;
|
||||||
Element clauseFilter=DOMUtils.getFirstChildOrFail(clauseElem);
|
BooleanClause.Occur occurs = BooleanQueryBuilder.getOccursValue(clauseElem);
|
||||||
Filter f=factory.getFilter(clauseFilter);
|
|
||||||
bf.add(new FilterClause(f,occurs));
|
Element clauseFilter = DOMUtils.getFirstChildOrFail(clauseElem);
|
||||||
}
|
Filter f = factory.getFilter(clauseFilter);
|
||||||
}
|
bf.add(new FilterClause(f, occurs));
|
||||||
|
}
|
||||||
return bf;
|
}
|
||||||
}
|
|
||||||
|
return bf;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,73 +30,61 @@ import org.w3c.dom.NodeList;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BooleanQueryBuilder implements QueryBuilder {
|
public class BooleanQueryBuilder implements QueryBuilder {
|
||||||
|
|
||||||
private QueryBuilder factory;
|
|
||||||
|
|
||||||
public BooleanQueryBuilder(QueryBuilder factory)
|
private final QueryBuilder factory;
|
||||||
{
|
|
||||||
this.factory=factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
public BooleanQueryBuilder(QueryBuilder factory) {
|
||||||
* @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
|
this.factory = factory;
|
||||||
*/
|
}
|
||||||
public Query getQuery(Element e) throws ParserException {
|
|
||||||
BooleanQuery bq=new BooleanQuery(DOMUtils.getAttribute(e,"disableCoord",false));
|
/* (non-Javadoc)
|
||||||
bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e,"minimumNumberShouldMatch",0));
|
* @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
|
||||||
bq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
*/
|
||||||
|
|
||||||
NodeList nl = e.getChildNodes();
|
public Query getQuery(Element e) throws ParserException {
|
||||||
for(int i=0;i<nl.getLength();i++)
|
BooleanQuery bq = new BooleanQuery(DOMUtils.getAttribute(e, "disableCoord", false));
|
||||||
{
|
bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e, "minimumNumberShouldMatch", 0));
|
||||||
Node node = nl.item(i);
|
bq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
if(node.getNodeName().equals("Clause"))
|
|
||||||
{
|
NodeList nl = e.getChildNodes();
|
||||||
Element clauseElem=(Element) node;
|
for (int i = 0; i < nl.getLength(); i++) {
|
||||||
BooleanClause.Occur occurs=getOccursValue(clauseElem);
|
Node node = nl.item(i);
|
||||||
|
if (node.getNodeName().equals("Clause")) {
|
||||||
Element clauseQuery=DOMUtils.getFirstChildOrFail(clauseElem);
|
Element clauseElem = (Element) node;
|
||||||
Query q=factory.getQuery(clauseQuery);
|
BooleanClause.Occur occurs = getOccursValue(clauseElem);
|
||||||
bq.add(new BooleanClause(q,occurs));
|
|
||||||
}
|
Element clauseQuery = DOMUtils.getFirstChildOrFail(clauseElem);
|
||||||
}
|
Query q = factory.getQuery(clauseQuery);
|
||||||
|
bq.add(new BooleanClause(q, occurs));
|
||||||
return bq;
|
}
|
||||||
}
|
}
|
||||||
static BooleanClause.Occur getOccursValue(Element clauseElem) throws ParserException
|
|
||||||
{
|
return bq;
|
||||||
String occs=clauseElem.getAttribute("occurs");
|
}
|
||||||
BooleanClause.Occur occurs=BooleanClause.Occur.SHOULD;
|
|
||||||
if("must".equalsIgnoreCase(occs))
|
static BooleanClause.Occur getOccursValue(Element clauseElem) throws ParserException {
|
||||||
{
|
String occs = clauseElem.getAttribute("occurs");
|
||||||
occurs=BooleanClause.Occur.MUST;
|
BooleanClause.Occur occurs = BooleanClause.Occur.SHOULD;
|
||||||
}
|
if ("must".equalsIgnoreCase(occs)) {
|
||||||
else
|
occurs = BooleanClause.Occur.MUST;
|
||||||
{
|
} else {
|
||||||
if("mustNot".equalsIgnoreCase(occs))
|
if ("mustNot".equalsIgnoreCase(occs)) {
|
||||||
{
|
occurs = BooleanClause.Occur.MUST_NOT;
|
||||||
occurs=BooleanClause.Occur.MUST_NOT;
|
} else {
|
||||||
}
|
if (("should".equalsIgnoreCase(occs)) || ("".equals(occs))) {
|
||||||
else
|
occurs = BooleanClause.Occur.SHOULD;
|
||||||
{
|
} else {
|
||||||
if(("should".equalsIgnoreCase(occs))||("".equals(occs)))
|
if (occs != null) {
|
||||||
{
|
throw new ParserException("Invalid value for \"occurs\" attribute of clause:" + occs);
|
||||||
occurs=BooleanClause.Occur.SHOULD;
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
if(occs!=null)
|
return occurs;
|
||||||
{
|
|
||||||
throw new ParserException("Invalid value for \"occurs\" attribute of clause:"+occs);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return occurs;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,37 +24,32 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BoostingQueryBuilder implements QueryBuilder
|
public class BoostingQueryBuilder implements QueryBuilder {
|
||||||
{
|
|
||||||
|
|
||||||
private QueryBuilder factory;
|
|
||||||
float defaultBoost=0.01f;
|
|
||||||
|
|
||||||
public BoostingQueryBuilder (QueryBuilder factory)
|
private static float DEFAULT_BOOST = 0.01f;
|
||||||
{
|
|
||||||
this.factory=factory;
|
private final QueryBuilder factory;
|
||||||
}
|
|
||||||
|
|
||||||
public Query getQuery(Element e) throws ParserException
|
public BoostingQueryBuilder(QueryBuilder factory) {
|
||||||
{
|
this.factory = factory;
|
||||||
|
}
|
||||||
Element mainQueryElem=DOMUtils.getChildByTagOrFail(e,"Query");
|
|
||||||
mainQueryElem=DOMUtils.getFirstChildOrFail(mainQueryElem);
|
|
||||||
Query mainQuery=factory.getQuery(mainQueryElem);
|
|
||||||
|
|
||||||
Element boostQueryElem=DOMUtils.getChildByTagOrFail(e,"BoostQuery");
|
public Query getQuery(Element e) throws ParserException {
|
||||||
float boost=DOMUtils.getAttribute(boostQueryElem,"boost",defaultBoost);
|
Element mainQueryElem = DOMUtils.getChildByTagOrFail(e, "Query");
|
||||||
boostQueryElem=DOMUtils.getFirstChildOrFail(boostQueryElem);
|
mainQueryElem = DOMUtils.getFirstChildOrFail(mainQueryElem);
|
||||||
Query boostQuery=factory.getQuery(boostQueryElem);
|
Query mainQuery = factory.getQuery(mainQueryElem);
|
||||||
|
|
||||||
BoostingQuery bq = new BoostingQuery(mainQuery,boostQuery,boost);
|
|
||||||
|
|
||||||
bq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
Element boostQueryElem = DOMUtils.getChildByTagOrFail(e, "BoostQuery");
|
||||||
return bq;
|
float boost = DOMUtils.getAttribute(boostQueryElem, "boost", DEFAULT_BOOST);
|
||||||
|
boostQueryElem = DOMUtils.getFirstChildOrFail(boostQueryElem);
|
||||||
|
Query boostQuery = factory.getQuery(boostQueryElem);
|
||||||
|
|
||||||
}
|
BoostingQuery bq = new BoostingQuery(mainQuery, boostQuery, boost);
|
||||||
|
|
||||||
|
bq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
return bq;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package org.apache.lucene.xmlparser.builders;
|
package org.apache.lucene.xmlparser.builders;
|
||||||
|
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.spans.SpanQuery;
|
|
||||||
import org.apache.lucene.search.payloads.PayloadTermQuery;
|
|
||||||
import org.apache.lucene.search.payloads.AveragePayloadFunction;
|
import org.apache.lucene.search.payloads.AveragePayloadFunction;
|
||||||
|
import org.apache.lucene.search.payloads.PayloadTermQuery;
|
||||||
|
import org.apache.lucene.search.spans.SpanQuery;
|
||||||
import org.apache.lucene.xmlparser.DOMUtils;
|
import org.apache.lucene.xmlparser.DOMUtils;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
@ -26,20 +26,17 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BoostingTermBuilder extends SpanBuilderBase
|
public class BoostingTermBuilder extends SpanBuilderBase {
|
||||||
{
|
|
||||||
|
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException
|
public SpanQuery getSpanQuery(Element e) throws ParserException {
|
||||||
{
|
String fieldName = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
String fieldName=DOMUtils.getAttributeWithInheritanceOrFail(e,"fieldName");
|
String value = DOMUtils.getNonBlankTextOrFail(e);
|
||||||
String value=DOMUtils.getNonBlankTextOrFail(e);
|
|
||||||
PayloadTermQuery btq = new PayloadTermQuery(new Term(fieldName,value), new AveragePayloadFunction());
|
|
||||||
|
|
||||||
btq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
PayloadTermQuery btq = new PayloadTermQuery(new Term(fieldName, value), new AveragePayloadFunction());
|
||||||
return btq;
|
btq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
return btq;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,19 +3,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.lucene.xmlparser.builders;
|
package org.apache.lucene.xmlparser.builders;
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.CachingWrapperFilter;
|
import org.apache.lucene.search.CachingWrapperFilter;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.Filter;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.QueryWrapperFilter;
|
import org.apache.lucene.search.QueryWrapperFilter;
|
||||||
import org.apache.lucene.xmlparser.DOMUtils;
|
import org.apache.lucene.xmlparser.*;
|
||||||
import org.apache.lucene.xmlparser.FilterBuilder;
|
|
||||||
import org.apache.lucene.xmlparser.FilterBuilderFactory;
|
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
|
||||||
import org.apache.lucene.xmlparser.QueryBuilder;
|
|
||||||
import org.apache.lucene.xmlparser.QueryBuilderFactory;
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -32,99 +27,89 @@ import org.w3c.dom.Element;
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters are cached in an LRU Cache keyed on the contained query or filter object. Using this will
|
* Filters are cached in an LRU Cache keyed on the contained query or filter object. Using this will
|
||||||
* speed up overall performance for repeated uses of the same expensive query/filter. The sorts of
|
* speed up overall performance for repeated uses of the same expensive query/filter. The sorts of
|
||||||
* queries/filters likely to benefit from caching need not necessarily be complex - e.g. simple
|
* queries/filters likely to benefit from caching need not necessarily be complex - e.g. simple
|
||||||
* TermQuerys with a large DF (document frequency) can be expensive on large indexes.
|
* TermQuerys with a large DF (document frequency) can be expensive on large indexes.
|
||||||
* A good example of this might be a term query on a field with only 2 possible values -
|
* A good example of this might be a term query on a field with only 2 possible values -
|
||||||
* "true" or "false". In a large index, querying or filtering on this field requires reading
|
* "true" or "false". In a large index, querying or filtering on this field requires reading
|
||||||
* millions of document ids from disk which can more usefully be cached as a filter bitset.
|
* millions of document ids from disk which can more usefully be cached as a filter bitset.
|
||||||
*
|
* <p/>
|
||||||
* For Queries/Filters to be cached and reused the object must implement hashcode and
|
* For Queries/Filters to be cached and reused the object must implement hashcode and
|
||||||
* equals methods correctly so that duplicate queries/filters can be detected in the cache.
|
* equals methods correctly so that duplicate queries/filters can be detected in the cache.
|
||||||
*
|
* <p/>
|
||||||
* The CoreParser.maxNumCachedFilters property can be used to control the size of the LRU
|
* The CoreParser.maxNumCachedFilters property can be used to control the size of the LRU
|
||||||
* Cache established during the construction of CoreParser instances.
|
* Cache established during the construction of CoreParser instances.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CachedFilterBuilder implements FilterBuilder {
|
public class CachedFilterBuilder implements FilterBuilder {
|
||||||
|
|
||||||
private QueryBuilderFactory queryFactory;
|
private final QueryBuilderFactory queryFactory;
|
||||||
private FilterBuilderFactory filterFactory;
|
private final FilterBuilderFactory filterFactory;
|
||||||
|
|
||||||
private LRUCache<Object,Filter> filterCache = null;
|
|
||||||
|
|
||||||
private int cacheSize;
|
private LRUCache<Object, Filter> filterCache;
|
||||||
|
|
||||||
public CachedFilterBuilder(QueryBuilderFactory queryFactory,
|
private final int cacheSize;
|
||||||
FilterBuilderFactory filterFactory,int cacheSize)
|
|
||||||
{
|
|
||||||
this.queryFactory=queryFactory;
|
|
||||||
this.filterFactory=filterFactory;
|
|
||||||
this.cacheSize=cacheSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Filter getFilter(Element e) throws ParserException
|
public CachedFilterBuilder(QueryBuilderFactory queryFactory,
|
||||||
{
|
FilterBuilderFactory filterFactory,
|
||||||
|
int cacheSize) {
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.filterFactory = filterFactory;
|
||||||
|
this.cacheSize = cacheSize;
|
||||||
|
}
|
||||||
|
|
||||||
Element childElement = DOMUtils.getFirstChildOrFail(e);
|
public synchronized Filter getFilter(Element e) throws ParserException {
|
||||||
|
Element childElement = DOMUtils.getFirstChildOrFail(e);
|
||||||
|
|
||||||
if (filterCache == null)
|
if (filterCache == null) {
|
||||||
{
|
filterCache = new LRUCache<Object, Filter>(cacheSize);
|
||||||
filterCache = new LRUCache<Object,Filter>(cacheSize);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Test to see if child Element is a query or filter that needs to be
|
// Test to see if child Element is a query or filter that needs to be
|
||||||
// cached
|
// cached
|
||||||
QueryBuilder qb = queryFactory.getQueryBuilder(childElement.getNodeName());
|
QueryBuilder qb = queryFactory.getQueryBuilder(childElement.getNodeName());
|
||||||
Object cacheKey = null;
|
Object cacheKey = null;
|
||||||
Query q = null;
|
Query q = null;
|
||||||
Filter f = null;
|
Filter f = null;
|
||||||
if (qb != null)
|
if (qb != null) {
|
||||||
{
|
q = qb.getQuery(childElement);
|
||||||
q = qb.getQuery(childElement);
|
cacheKey = q;
|
||||||
cacheKey = q;
|
} else {
|
||||||
} else
|
f = filterFactory.getFilter(childElement);
|
||||||
{
|
cacheKey = f;
|
||||||
f = filterFactory.getFilter(childElement);
|
}
|
||||||
cacheKey = f;
|
Filter cachedFilter = filterCache.get(cacheKey);
|
||||||
}
|
if (cachedFilter != null) {
|
||||||
Filter cachedFilter = filterCache.get(cacheKey);
|
return cachedFilter; // cache hit
|
||||||
if (cachedFilter != null)
|
}
|
||||||
{
|
|
||||||
return cachedFilter; // cache hit
|
|
||||||
}
|
|
||||||
|
|
||||||
//cache miss
|
|
||||||
if (qb != null)
|
|
||||||
{
|
|
||||||
cachedFilter = new QueryWrapperFilter(q);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
cachedFilter = new CachingWrapperFilter(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
filterCache.put(cacheKey, cachedFilter);
|
//cache miss
|
||||||
return cachedFilter;
|
if (qb != null) {
|
||||||
}
|
cachedFilter = new QueryWrapperFilter(q);
|
||||||
|
} else {
|
||||||
static class LRUCache<K,V> extends java.util.LinkedHashMap<K,V>
|
cachedFilter = new CachingWrapperFilter(f);
|
||||||
{
|
}
|
||||||
public LRUCache(int maxsize)
|
|
||||||
{
|
|
||||||
super(maxsize * 4 / 3 + 1, 0.75f, true);
|
|
||||||
this.maxsize = maxsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int maxsize;
|
filterCache.put(cacheKey, cachedFilter);
|
||||||
|
return cachedFilter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
static class LRUCache<K, V> extends java.util.LinkedHashMap<K, V> {
|
||||||
protected boolean removeEldestEntry(Entry<K,V> eldest)
|
|
||||||
{
|
|
||||||
return size() > maxsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
public LRUCache(int maxsize) {
|
||||||
|
super(maxsize * 4 / 3 + 1, 0.75f, true);
|
||||||
|
this.maxsize = maxsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int maxsize;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
|
||||||
|
return size() > maxsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,26 +25,22 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ConstantScoreQueryBuilder implements QueryBuilder
|
public class ConstantScoreQueryBuilder implements QueryBuilder {
|
||||||
{
|
|
||||||
private FilterBuilderFactory filterFactory;
|
|
||||||
|
|
||||||
public ConstantScoreQueryBuilder(FilterBuilderFactory filterFactory)
|
private final FilterBuilderFactory filterFactory;
|
||||||
{
|
|
||||||
this.filterFactory=filterFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Query getQuery(Element e) throws ParserException
|
public ConstantScoreQueryBuilder(FilterBuilderFactory filterFactory) {
|
||||||
{
|
this.filterFactory = filterFactory;
|
||||||
Element filterElem=DOMUtils.getFirstChildOrFail(e);
|
}
|
||||||
Query q=new ConstantScoreQuery(filterFactory.getFilter(filterElem));
|
|
||||||
|
|
||||||
q.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
public Query getQuery(Element e) throws ParserException {
|
||||||
|
Element filterElem = DOMUtils.getFirstChildOrFail(e);
|
||||||
|
|
||||||
return q;
|
Query q = new ConstantScoreQuery(filterFactory.getFilter(filterElem));
|
||||||
|
q.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
}
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,44 +28,33 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DuplicateFilterBuilder implements FilterBuilder {
|
public class DuplicateFilterBuilder implements FilterBuilder {
|
||||||
|
|
||||||
|
|
||||||
public Filter getFilter(Element e) throws ParserException {
|
public Filter getFilter(Element e) throws ParserException {
|
||||||
String fieldName=DOMUtils.getAttributeWithInheritanceOrFail(e,"fieldName");
|
String fieldName = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
DuplicateFilter df=new DuplicateFilter(fieldName);
|
DuplicateFilter df = new DuplicateFilter(fieldName);
|
||||||
String keepMode=DOMUtils.getAttribute(e,"keepMode","first");
|
|
||||||
if(keepMode.equalsIgnoreCase("first"))
|
String keepMode = DOMUtils.getAttribute(e, "keepMode", "first");
|
||||||
{
|
if (keepMode.equalsIgnoreCase("first")) {
|
||||||
df.setKeepMode(DuplicateFilter.KeepMode.KM_USE_FIRST_OCCURRENCE);
|
df.setKeepMode(DuplicateFilter.KeepMode.KM_USE_FIRST_OCCURRENCE);
|
||||||
}
|
} else if (keepMode.equalsIgnoreCase("last")) {
|
||||||
else
|
df.setKeepMode(DuplicateFilter.KeepMode.KM_USE_LAST_OCCURRENCE);
|
||||||
if(keepMode.equalsIgnoreCase("last"))
|
} else {
|
||||||
{
|
throw new ParserException("Illegal keepMode attribute in DuplicateFilter:" + keepMode);
|
||||||
df.setKeepMode(DuplicateFilter.KeepMode.KM_USE_LAST_OCCURRENCE);
|
}
|
||||||
}
|
|
||||||
else
|
String processingMode = DOMUtils.getAttribute(e, "processingMode", "full");
|
||||||
{
|
if (processingMode.equalsIgnoreCase("full")) {
|
||||||
throw new ParserException("Illegal keepMode attribute in DuplicateFilter:"+keepMode);
|
df.setProcessingMode(DuplicateFilter.ProcessingMode.PM_FULL_VALIDATION);
|
||||||
}
|
} else if (processingMode.equalsIgnoreCase("fast")) {
|
||||||
String processingMode=DOMUtils.getAttribute(e,"processingMode","full");
|
df.setProcessingMode(DuplicateFilter.ProcessingMode.PM_FAST_INVALIDATION);
|
||||||
if(processingMode.equalsIgnoreCase("full"))
|
} else {
|
||||||
{
|
throw new ParserException("Illegal processingMode attribute in DuplicateFilter:" + processingMode);
|
||||||
df.setProcessingMode(DuplicateFilter.ProcessingMode.PM_FULL_VALIDATION);
|
}
|
||||||
}
|
|
||||||
else
|
return df;
|
||||||
if(processingMode.equalsIgnoreCase("fast"))
|
}
|
||||||
{
|
|
||||||
df.setProcessingMode(DuplicateFilter.ProcessingMode.PM_FAST_INVALIDATION);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ParserException("Illegal processingMode attribute in DuplicateFilter:"+processingMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return df;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,35 +30,34 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class FilteredQueryBuilder implements QueryBuilder {
|
public class FilteredQueryBuilder implements QueryBuilder {
|
||||||
|
|
||||||
private FilterBuilder filterFactory;
|
|
||||||
private QueryBuilder queryFactory;
|
|
||||||
|
|
||||||
public FilteredQueryBuilder(FilterBuilder filterFactory, QueryBuilder queryFactory)
|
private final FilterBuilder filterFactory;
|
||||||
{
|
private final QueryBuilder queryFactory;
|
||||||
this.filterFactory=filterFactory;
|
|
||||||
this.queryFactory=queryFactory;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
public FilteredQueryBuilder(FilterBuilder filterFactory, QueryBuilder queryFactory) {
|
||||||
* @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
|
this.filterFactory = filterFactory;
|
||||||
*/
|
this.queryFactory = queryFactory;
|
||||||
public Query getQuery(Element e) throws ParserException {
|
|
||||||
Element filterElement=DOMUtils.getChildByTagOrFail(e,"Filter");
|
}
|
||||||
filterElement=DOMUtils.getFirstChildOrFail(filterElement);
|
|
||||||
Filter f=filterFactory.getFilter(filterElement);
|
/* (non-Javadoc)
|
||||||
|
* @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
|
||||||
Element queryElement=DOMUtils.getChildByTagOrFail(e,"Query");
|
*/
|
||||||
queryElement=DOMUtils.getFirstChildOrFail(queryElement);
|
public Query getQuery(Element e) throws ParserException {
|
||||||
Query q=queryFactory.getQuery(queryElement);
|
Element filterElement = DOMUtils.getChildByTagOrFail(e, "Filter");
|
||||||
|
filterElement = DOMUtils.getFirstChildOrFail(filterElement);
|
||||||
FilteredQuery fq = new FilteredQuery(q,f);
|
Filter f = filterFactory.getFilter(filterElement);
|
||||||
fq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
|
||||||
return fq;
|
Element queryElement = DOMUtils.getChildByTagOrFail(e, "Query");
|
||||||
}
|
queryElement = DOMUtils.getFirstChildOrFail(queryElement);
|
||||||
|
Query q = queryFactory.getQuery(queryElement);
|
||||||
|
|
||||||
|
FilteredQuery fq = new FilteredQuery(q, f);
|
||||||
|
fq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
return fq;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,40 +28,39 @@ import org.w3c.dom.NodeList;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class FuzzyLikeThisQueryBuilder implements QueryBuilder
|
public class FuzzyLikeThisQueryBuilder implements QueryBuilder {
|
||||||
{
|
|
||||||
int defaultMaxNumTerms=50;
|
|
||||||
float defaultMinSimilarity=FuzzyQuery.defaultMinSimilarity;
|
|
||||||
int defaultPrefixLength=1;
|
|
||||||
boolean defaultIgnoreTF=false;
|
|
||||||
private Analyzer analyzer;
|
|
||||||
|
|
||||||
public FuzzyLikeThisQueryBuilder(Analyzer analyzer)
|
|
||||||
{
|
|
||||||
this.analyzer=analyzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Query getQuery(Element e) throws ParserException
|
private static final int DEFAULT_MAX_NUM_TERMS = 50;
|
||||||
{
|
private static final float DEFAULT_MIN_SIMILARITY = FuzzyQuery.defaultMinSimilarity;
|
||||||
NodeList nl = e.getElementsByTagName("Field");
|
private static final int DEFAULT_PREFIX_LENGTH = 1;
|
||||||
int maxNumTerms=DOMUtils.getAttribute(e,"maxNumTerms",defaultMaxNumTerms);
|
private static final boolean DEFAULT_IGNORE_TF = false;
|
||||||
FuzzyLikeThisQuery fbq=new FuzzyLikeThisQuery(maxNumTerms,analyzer);
|
|
||||||
fbq.setIgnoreTF(DOMUtils.getAttribute(e,"ignoreTF",defaultIgnoreTF));
|
|
||||||
for(int i=0;i<nl.getLength();i++)
|
|
||||||
{
|
|
||||||
Element fieldElem=(Element) nl.item(i);
|
|
||||||
float minSimilarity=DOMUtils.getAttribute(fieldElem,"minSimilarity",defaultMinSimilarity);
|
|
||||||
int prefixLength=DOMUtils.getAttribute(fieldElem,"prefixLength",defaultPrefixLength);
|
|
||||||
String fieldName=DOMUtils.getAttributeWithInheritance(fieldElem,"fieldName");
|
|
||||||
|
|
||||||
String value=DOMUtils.getText(fieldElem);
|
|
||||||
fbq.addTerms(value,fieldName,minSimilarity,prefixLength);
|
|
||||||
}
|
|
||||||
fbq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
|
||||||
|
|
||||||
return fbq;
|
private final Analyzer analyzer;
|
||||||
}
|
|
||||||
|
public FuzzyLikeThisQueryBuilder(Analyzer analyzer) {
|
||||||
|
this.analyzer = analyzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query getQuery(Element e) throws ParserException {
|
||||||
|
NodeList nl = e.getElementsByTagName("Field");
|
||||||
|
int maxNumTerms = DOMUtils.getAttribute(e, "maxNumTerms", DEFAULT_MAX_NUM_TERMS);
|
||||||
|
FuzzyLikeThisQuery fbq = new FuzzyLikeThisQuery(maxNumTerms, analyzer);
|
||||||
|
fbq.setIgnoreTF(DOMUtils.getAttribute(e, "ignoreTF", DEFAULT_IGNORE_TF));
|
||||||
|
|
||||||
|
for (int i = 0; i < nl.getLength(); i++) {
|
||||||
|
Element fieldElem = (Element) nl.item(i);
|
||||||
|
float minSimilarity = DOMUtils.getAttribute(fieldElem, "minSimilarity", DEFAULT_MIN_SIMILARITY);
|
||||||
|
int prefixLength = DOMUtils.getAttribute(fieldElem, "prefixLength", DEFAULT_PREFIX_LENGTH);
|
||||||
|
String fieldName = DOMUtils.getAttributeWithInheritance(fieldElem, "fieldName");
|
||||||
|
|
||||||
|
String value = DOMUtils.getText(fieldElem);
|
||||||
|
fbq.addTerms(value, fieldName, minSimilarity, prefixLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
fbq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
return fbq;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,83 +35,74 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class LikeThisQueryBuilder implements QueryBuilder {
|
public class LikeThisQueryBuilder implements QueryBuilder {
|
||||||
|
|
||||||
private Analyzer analyzer;
|
private static final int DEFAULT_MAX_QUERY_TERMS = 20;
|
||||||
String defaultFieldNames [];
|
private static final int DEFAULT_MIN_TERM_FREQUENCY = 1;
|
||||||
int defaultMaxQueryTerms=20;
|
private static final float DEFAULT_PERCENT_TERMS_TO_MATCH = 30; //default is a 3rd of selected terms must match
|
||||||
int defaultMinTermFrequency=1;
|
|
||||||
float defaultPercentTermsToMatch=30; //default is a 3rd of selected terms must match
|
|
||||||
|
|
||||||
public LikeThisQueryBuilder(Analyzer analyzer,String [] defaultFieldNames)
|
private final Analyzer analyzer;
|
||||||
{
|
private final String defaultFieldNames[];
|
||||||
this.analyzer=analyzer;
|
|
||||||
this.defaultFieldNames=defaultFieldNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
|
|
||||||
*/
|
|
||||||
public Query getQuery(Element e) throws ParserException {
|
|
||||||
String fieldsList=e.getAttribute("fieldNames"); //a comma-delimited list of fields
|
|
||||||
String fields[]=defaultFieldNames;
|
|
||||||
if((fieldsList!=null)&&(fieldsList.trim().length()>0))
|
|
||||||
{
|
|
||||||
fields=fieldsList.trim().split(",");
|
|
||||||
//trim the fieldnames
|
|
||||||
for (int i = 0; i < fields.length; i++) {
|
|
||||||
fields[i]=fields[i].trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Parse any "stopWords" attribute
|
|
||||||
//TODO MoreLikeThis needs to ideally have per-field stopWords lists - until then
|
|
||||||
//I use all analyzers/fields to generate multi-field compatible stop list
|
|
||||||
String stopWords=e.getAttribute("stopWords");
|
|
||||||
Set<String> stopWordsSet=null;
|
|
||||||
if((stopWords!=null)&&(fields!=null))
|
|
||||||
{
|
|
||||||
stopWordsSet=new HashSet<String>();
|
|
||||||
for (int i = 0; i < fields.length; i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
TokenStream ts = analyzer.reusableTokenStream(fields[i],new StringReader(stopWords));
|
|
||||||
CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
|
|
||||||
ts.reset();
|
|
||||||
while(ts.incrementToken()) {
|
|
||||||
stopWordsSet.add(termAtt.toString());
|
|
||||||
}
|
|
||||||
ts.end();
|
|
||||||
ts.close();
|
|
||||||
}
|
|
||||||
catch(IOException ioe)
|
|
||||||
{
|
|
||||||
throw new ParserException("IoException parsing stop words list in "
|
|
||||||
+getClass().getName()+":"+ioe.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MoreLikeThisQuery mlt=new MoreLikeThisQuery(DOMUtils.getText(e),fields,analyzer, fields[0]);
|
|
||||||
mlt.setMaxQueryTerms(DOMUtils.getAttribute(e,"maxQueryTerms",defaultMaxQueryTerms));
|
|
||||||
mlt.setMinTermFrequency(DOMUtils.getAttribute(e,"minTermFrequency",defaultMinTermFrequency));
|
|
||||||
mlt.setPercentTermsToMatch(DOMUtils.getAttribute(e,"percentTermsToMatch",defaultPercentTermsToMatch)/100);
|
|
||||||
mlt.setStopWords(stopWordsSet);
|
|
||||||
int minDocFreq=DOMUtils.getAttribute(e,"minDocFreq",-1);
|
|
||||||
if(minDocFreq>=0)
|
|
||||||
{
|
|
||||||
mlt.setMinDocFreq(minDocFreq);
|
|
||||||
}
|
|
||||||
|
|
||||||
mlt.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
public LikeThisQueryBuilder(Analyzer analyzer, String[] defaultFieldNames) {
|
||||||
|
this.analyzer = analyzer;
|
||||||
|
this.defaultFieldNames = defaultFieldNames;
|
||||||
|
}
|
||||||
|
|
||||||
return mlt;
|
/* (non-Javadoc)
|
||||||
}
|
* @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
|
||||||
|
*/
|
||||||
|
public Query getQuery(Element e) throws ParserException {
|
||||||
|
String fieldsList = e.getAttribute("fieldNames"); //a comma-delimited list of fields
|
||||||
|
String fields[] = defaultFieldNames;
|
||||||
|
if ((fieldsList != null) && (fieldsList.trim().length() > 0)) {
|
||||||
|
fields = fieldsList.trim().split(",");
|
||||||
|
//trim the fieldnames
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
fields[i] = fields[i].trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parse any "stopWords" attribute
|
||||||
|
//TODO MoreLikeThis needs to ideally have per-field stopWords lists - until then
|
||||||
|
//I use all analyzers/fields to generate multi-field compatible stop list
|
||||||
|
String stopWords = e.getAttribute("stopWords");
|
||||||
|
Set<String> stopWordsSet = null;
|
||||||
|
if ((stopWords != null) && (fields != null)) {
|
||||||
|
stopWordsSet = new HashSet<String>();
|
||||||
|
for (String field : fields) {
|
||||||
|
try {
|
||||||
|
TokenStream ts = analyzer.reusableTokenStream(field, new StringReader(stopWords));
|
||||||
|
CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
|
||||||
|
ts.reset();
|
||||||
|
while (ts.incrementToken()) {
|
||||||
|
stopWordsSet.add(termAtt.toString());
|
||||||
|
}
|
||||||
|
ts.end();
|
||||||
|
ts.close();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new ParserException("IoException parsing stop words list in "
|
||||||
|
+ getClass().getName() + ":" + ioe.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MoreLikeThisQuery mlt = new MoreLikeThisQuery(DOMUtils.getText(e), fields, analyzer, fields[0]);
|
||||||
|
mlt.setMaxQueryTerms(DOMUtils.getAttribute(e, "maxQueryTerms", DEFAULT_MAX_QUERY_TERMS));
|
||||||
|
mlt.setMinTermFrequency(DOMUtils.getAttribute(e, "minTermFrequency", DEFAULT_MIN_TERM_FREQUENCY));
|
||||||
|
mlt.setPercentTermsToMatch(DOMUtils.getAttribute(e, "percentTermsToMatch", DEFAULT_PERCENT_TERMS_TO_MATCH) / 100);
|
||||||
|
mlt.setStopWords(stopWordsSet);
|
||||||
|
int minDocFreq = DOMUtils.getAttribute(e, "minDocFreq", -1);
|
||||||
|
if (minDocFreq >= 0) {
|
||||||
|
mlt.setMinDocFreq(minDocFreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
mlt.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
|
||||||
|
return mlt;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,11 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MatchAllDocsQueryBuilder implements QueryBuilder
|
public class MatchAllDocsQueryBuilder implements QueryBuilder {
|
||||||
{
|
|
||||||
public Query getQuery(Element e) throws ParserException
|
public Query getQuery(Element e) throws ParserException {
|
||||||
{
|
return new MatchAllDocsQuery();
|
||||||
return new MatchAllDocsQuery();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@ package org.apache.lucene.xmlparser.builders;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
|
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
|
||||||
import org.apache.lucene.search.DocIdSet;
|
import org.apache.lucene.search.DocIdSet;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.Filter;
|
||||||
|
@ -29,6 +27,8 @@ import org.apache.lucene.xmlparser.FilterBuilder;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link NumericRangeFilter}. The table below specifies the required
|
* Creates a {@link NumericRangeFilter}. The table below specifies the required
|
||||||
* attributes and the defaults if optional attributes are omitted. For more
|
* attributes and the defaults if optional attributes are omitted. For more
|
||||||
|
@ -84,80 +84,79 @@ import org.w3c.dom.Element;
|
||||||
* <td>4</td>
|
* <td>4</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* </table>
|
* </table>
|
||||||
* <p>
|
* <p/>
|
||||||
* If an error occurs parsing the supplied <tt>lowerTerm</tt> or
|
* If an error occurs parsing the supplied <tt>lowerTerm</tt> or
|
||||||
* <tt>upperTerm</tt> into the numeric type specified by <tt>type</tt>, then the
|
* <tt>upperTerm</tt> into the numeric type specified by <tt>type</tt>, then the
|
||||||
* error will be silently ignored and the resulting filter will not match any
|
* error will be silently ignored and the resulting filter will not match any
|
||||||
* documents.
|
* documents.
|
||||||
*/
|
*/
|
||||||
public class NumericRangeFilterBuilder implements FilterBuilder {
|
public class NumericRangeFilterBuilder implements FilterBuilder {
|
||||||
private static final NoMatchFilter NO_MATCH_FILTER = new NoMatchFilter();
|
|
||||||
|
private static final NoMatchFilter NO_MATCH_FILTER = new NoMatchFilter();
|
||||||
|
|
||||||
private boolean strictMode = false;
|
private boolean strictMode = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies how this {@link NumericRangeFilterBuilder} will handle errors.
|
* Specifies how this {@link NumericRangeFilterBuilder} will handle errors.
|
||||||
* <p>
|
* <p/>
|
||||||
* If this is set to true, {@link #getFilter(Element)} will throw a
|
* If this is set to true, {@link #getFilter(Element)} will throw a
|
||||||
* {@link ParserException} if it is unable to parse the lowerTerm or upperTerm
|
* {@link ParserException} if it is unable to parse the lowerTerm or upperTerm
|
||||||
* into the appropriate numeric type. If this is set to false, then this
|
* into the appropriate numeric type. If this is set to false, then this
|
||||||
* exception will be silently ignored and the resulting filter will not match
|
* exception will be silently ignored and the resulting filter will not match
|
||||||
* any documents.
|
* any documents.
|
||||||
* <p>
|
* <p/>
|
||||||
* Defaults to false.
|
* Defaults to false.
|
||||||
*
|
*
|
||||||
* @param strictMode
|
* @param strictMode
|
||||||
*/
|
*/
|
||||||
public void setStrictMode(boolean strictMode) {
|
public void setStrictMode(boolean strictMode) {
|
||||||
this.strictMode = strictMode;
|
this.strictMode = strictMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Filter getFilter(Element e) throws ParserException {
|
public Filter getFilter(Element e) throws ParserException {
|
||||||
String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
String lowerTerm = DOMUtils.getAttributeOrFail(e, "lowerTerm");
|
String lowerTerm = DOMUtils.getAttributeOrFail(e, "lowerTerm");
|
||||||
String upperTerm = DOMUtils.getAttributeOrFail(e, "upperTerm");
|
String upperTerm = DOMUtils.getAttributeOrFail(e, "upperTerm");
|
||||||
boolean lowerInclusive = DOMUtils.getAttribute(e, "includeLower", true);
|
boolean lowerInclusive = DOMUtils.getAttribute(e, "includeLower", true);
|
||||||
boolean upperInclusive = DOMUtils.getAttribute(e, "includeUpper", true);
|
boolean upperInclusive = DOMUtils.getAttribute(e, "includeUpper", true);
|
||||||
int precisionStep = DOMUtils.getAttribute(e, "precisionStep", NumericUtils.PRECISION_STEP_DEFAULT);
|
int precisionStep = DOMUtils.getAttribute(e, "precisionStep", NumericUtils.PRECISION_STEP_DEFAULT);
|
||||||
|
|
||||||
String type = DOMUtils.getAttribute(e, "type", "int");
|
String type = DOMUtils.getAttribute(e, "type", "int");
|
||||||
try {
|
try {
|
||||||
Filter filter;
|
Filter filter;
|
||||||
if (type.equalsIgnoreCase("int")) {
|
if (type.equalsIgnoreCase("int")) {
|
||||||
filter = NumericRangeFilter.newIntRange(field, precisionStep, Integer
|
filter = NumericRangeFilter.newIntRange(field, precisionStep, Integer
|
||||||
.valueOf(lowerTerm), Integer.valueOf(upperTerm), lowerInclusive,
|
.valueOf(lowerTerm), Integer.valueOf(upperTerm), lowerInclusive,
|
||||||
upperInclusive);
|
upperInclusive);
|
||||||
} else if (type.equalsIgnoreCase("long")) {
|
} else if (type.equalsIgnoreCase("long")) {
|
||||||
filter = NumericRangeFilter.newLongRange(field, precisionStep, Long
|
filter = NumericRangeFilter.newLongRange(field, precisionStep, Long
|
||||||
.valueOf(lowerTerm), Long.valueOf(upperTerm), lowerInclusive,
|
.valueOf(lowerTerm), Long.valueOf(upperTerm), lowerInclusive,
|
||||||
upperInclusive);
|
upperInclusive);
|
||||||
} else if (type.equalsIgnoreCase("double")) {
|
} else if (type.equalsIgnoreCase("double")) {
|
||||||
filter = NumericRangeFilter.newDoubleRange(field, precisionStep, Double
|
filter = NumericRangeFilter.newDoubleRange(field, precisionStep, Double
|
||||||
.valueOf(lowerTerm), Double.valueOf(upperTerm), lowerInclusive,
|
.valueOf(lowerTerm), Double.valueOf(upperTerm), lowerInclusive,
|
||||||
upperInclusive);
|
upperInclusive);
|
||||||
} else if (type.equalsIgnoreCase("float")) {
|
} else if (type.equalsIgnoreCase("float")) {
|
||||||
filter = NumericRangeFilter.newFloatRange(field, precisionStep, Float
|
filter = NumericRangeFilter.newFloatRange(field, precisionStep, Float
|
||||||
.valueOf(lowerTerm), Float.valueOf(upperTerm), lowerInclusive,
|
.valueOf(lowerTerm), Float.valueOf(upperTerm), lowerInclusive,
|
||||||
upperInclusive);
|
upperInclusive);
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException(
|
throw new ParserException("type attribute must be one of: [long, int, double, float]");
|
||||||
"type attribute must be one of: [long, int, double, float]");
|
}
|
||||||
}
|
return filter;
|
||||||
return filter;
|
} catch (NumberFormatException nfe) {
|
||||||
} catch (NumberFormatException nfe) {
|
if (strictMode) {
|
||||||
if (strictMode) {
|
throw new ParserException("Could not parse lowerTerm or upperTerm into a number", nfe);
|
||||||
throw new ParserException(
|
}
|
||||||
"Could not parse lowerTerm or upperTerm into a number", nfe);
|
return NO_MATCH_FILTER;
|
||||||
}
|
}
|
||||||
return NO_MATCH_FILTER;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class NoMatchFilter extends Filter {
|
static class NoMatchFilter extends Filter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException {
|
public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,48 +80,46 @@ import org.w3c.dom.Element;
|
||||||
* <td>4</td>
|
* <td>4</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* </table>
|
* </table>
|
||||||
* <p>
|
* <p/>
|
||||||
* A {@link ParserException} will be thrown if an error occurs parsing the
|
* A {@link ParserException} will be thrown if an error occurs parsing the
|
||||||
* supplied <tt>lowerTerm</tt> or <tt>upperTerm</tt> into the numeric type
|
* supplied <tt>lowerTerm</tt> or <tt>upperTerm</tt> into the numeric type
|
||||||
* specified by <tt>type</tt>.
|
* specified by <tt>type</tt>.
|
||||||
*/
|
*/
|
||||||
public class NumericRangeQueryBuilder implements QueryBuilder {
|
public class NumericRangeQueryBuilder implements QueryBuilder {
|
||||||
|
|
||||||
public Query getQuery(Element e) throws ParserException {
|
public Query getQuery(Element e) throws ParserException {
|
||||||
String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
String lowerTerm = DOMUtils.getAttributeOrFail(e, "lowerTerm");
|
String lowerTerm = DOMUtils.getAttributeOrFail(e, "lowerTerm");
|
||||||
String upperTerm = DOMUtils.getAttributeOrFail(e, "upperTerm");
|
String upperTerm = DOMUtils.getAttributeOrFail(e, "upperTerm");
|
||||||
boolean lowerInclusive = DOMUtils.getAttribute(e, "includeLower", true);
|
boolean lowerInclusive = DOMUtils.getAttribute(e, "includeLower", true);
|
||||||
boolean upperInclusive = DOMUtils.getAttribute(e, "includeUpper", true);
|
boolean upperInclusive = DOMUtils.getAttribute(e, "includeUpper", true);
|
||||||
int precisionStep = DOMUtils.getAttribute(e, "precisionStep", NumericUtils.PRECISION_STEP_DEFAULT);
|
int precisionStep = DOMUtils.getAttribute(e, "precisionStep", NumericUtils.PRECISION_STEP_DEFAULT);
|
||||||
|
|
||||||
String type = DOMUtils.getAttribute(e, "type", "int");
|
String type = DOMUtils.getAttribute(e, "type", "int");
|
||||||
try {
|
try {
|
||||||
Query filter;
|
Query filter;
|
||||||
if (type.equalsIgnoreCase("int")) {
|
if (type.equalsIgnoreCase("int")) {
|
||||||
filter = NumericRangeQuery.newIntRange(field, precisionStep, Integer
|
filter = NumericRangeQuery.newIntRange(field, precisionStep, Integer
|
||||||
.valueOf(lowerTerm), Integer.valueOf(upperTerm), lowerInclusive,
|
.valueOf(lowerTerm), Integer.valueOf(upperTerm), lowerInclusive,
|
||||||
upperInclusive);
|
upperInclusive);
|
||||||
} else if (type.equalsIgnoreCase("long")) {
|
} else if (type.equalsIgnoreCase("long")) {
|
||||||
filter = NumericRangeQuery.newLongRange(field, precisionStep, Long
|
filter = NumericRangeQuery.newLongRange(field, precisionStep, Long
|
||||||
.valueOf(lowerTerm), Long.valueOf(upperTerm), lowerInclusive,
|
.valueOf(lowerTerm), Long.valueOf(upperTerm), lowerInclusive,
|
||||||
upperInclusive);
|
upperInclusive);
|
||||||
} else if (type.equalsIgnoreCase("double")) {
|
} else if (type.equalsIgnoreCase("double")) {
|
||||||
filter = NumericRangeQuery.newDoubleRange(field, precisionStep, Double
|
filter = NumericRangeQuery.newDoubleRange(field, precisionStep, Double
|
||||||
.valueOf(lowerTerm), Double.valueOf(upperTerm), lowerInclusive,
|
.valueOf(lowerTerm), Double.valueOf(upperTerm), lowerInclusive,
|
||||||
upperInclusive);
|
upperInclusive);
|
||||||
} else if (type.equalsIgnoreCase("float")) {
|
} else if (type.equalsIgnoreCase("float")) {
|
||||||
filter = NumericRangeQuery.newFloatRange(field, precisionStep, Float
|
filter = NumericRangeQuery.newFloatRange(field, precisionStep, Float
|
||||||
.valueOf(lowerTerm), Float.valueOf(upperTerm), lowerInclusive,
|
.valueOf(lowerTerm), Float.valueOf(upperTerm), lowerInclusive,
|
||||||
upperInclusive);
|
upperInclusive);
|
||||||
} else {
|
} else {
|
||||||
throw new ParserException(
|
throw new ParserException("type attribute must be one of: [long, int, double, float]");
|
||||||
"type attribute must be one of: [long, int, double, float]");
|
}
|
||||||
}
|
return filter;
|
||||||
return filter;
|
} catch (NumberFormatException nfe) {
|
||||||
} catch (NumberFormatException nfe) {
|
throw new ParserException("Could not parse lowerTerm or upperTerm into a number", nfe);
|
||||||
throw new ParserException(
|
}
|
||||||
"Could not parse lowerTerm or upperTerm into a number", nfe);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,20 +28,18 @@ import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RangeFilterBuilder implements FilterBuilder {
|
public class RangeFilterBuilder implements FilterBuilder {
|
||||||
|
|
||||||
|
public Filter getFilter(Element e) throws ParserException {
|
||||||
|
String fieldName = DOMUtils.getAttributeWithInheritance(e, "fieldName");
|
||||||
|
|
||||||
public Filter getFilter(Element e) throws ParserException {
|
String lowerTerm = e.getAttribute("lowerTerm");
|
||||||
|
String upperTerm = e.getAttribute("upperTerm");
|
||||||
String fieldName=DOMUtils.getAttributeWithInheritance(e,"fieldName");
|
boolean includeLower = DOMUtils.getAttribute(e, "includeLower", true);
|
||||||
|
boolean includeUpper = DOMUtils.getAttribute(e, "includeUpper", true);
|
||||||
String lowerTerm=e.getAttribute("lowerTerm");
|
return TermRangeFilter.newStringRange(fieldName, lowerTerm, upperTerm, includeLower, includeUpper);
|
||||||
String upperTerm=e.getAttribute("upperTerm");
|
}
|
||||||
boolean includeLower=DOMUtils.getAttribute(e,"includeLower",true);
|
|
||||||
boolean includeUpper=DOMUtils.getAttribute(e,"includeUpper",true);
|
|
||||||
return TermRangeFilter.newStringRange(fieldName,lowerTerm,upperTerm,includeLower,includeUpper);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,12 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class SpanBuilderBase implements SpanQueryBuilder
|
public abstract class SpanBuilderBase implements SpanQueryBuilder {
|
||||||
{
|
|
||||||
public Query getQuery(Element e) throws ParserException
|
public Query getQuery(Element e) throws ParserException {
|
||||||
{
|
return getSpanQuery(e);
|
||||||
return getSpanQuery(e);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,28 +23,25 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpanFirstBuilder extends SpanBuilderBase
|
public class SpanFirstBuilder extends SpanBuilderBase {
|
||||||
{
|
|
||||||
SpanQueryBuilder factory;
|
|
||||||
|
|
||||||
public SpanFirstBuilder(SpanQueryBuilder factory)
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
this.factory = factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException
|
private final SpanQueryBuilder factory;
|
||||||
{
|
|
||||||
int end=DOMUtils.getAttribute(e,"end",1);
|
public SpanFirstBuilder(SpanQueryBuilder factory) {
|
||||||
Element child=DOMUtils.getFirstChildElement(e);
|
this.factory = factory;
|
||||||
SpanQuery q=factory.getSpanQuery(child);
|
}
|
||||||
|
|
||||||
SpanFirstQuery sfq = new SpanFirstQuery(q,end);
|
public SpanQuery getSpanQuery(Element e) throws ParserException {
|
||||||
|
int end = DOMUtils.getAttribute(e, "end", 1);
|
||||||
sfq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
Element child = DOMUtils.getFirstChildElement(e);
|
||||||
return sfq;
|
SpanQuery q = factory.getSpanQuery(child);
|
||||||
}
|
|
||||||
|
SpanFirstQuery sfq = new SpanFirstQuery(q, end);
|
||||||
|
|
||||||
|
sfq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
return sfq;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package org.apache.lucene.xmlparser.builders;
|
package org.apache.lucene.xmlparser.builders;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.spans.SpanNearQuery;
|
import org.apache.lucene.search.spans.SpanNearQuery;
|
||||||
import org.apache.lucene.search.spans.SpanQuery;
|
import org.apache.lucene.search.spans.SpanQuery;
|
||||||
import org.apache.lucene.xmlparser.DOMUtils;
|
import org.apache.lucene.xmlparser.DOMUtils;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -26,32 +27,28 @@ import org.w3c.dom.Node;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpanNearBuilder extends SpanBuilderBase
|
public class SpanNearBuilder extends SpanBuilderBase {
|
||||||
{
|
|
||||||
SpanQueryBuilder factory;
|
private final SpanQueryBuilder factory;
|
||||||
public SpanNearBuilder(SpanQueryBuilder factory)
|
|
||||||
{
|
public SpanNearBuilder(SpanQueryBuilder factory) {
|
||||||
this.factory=factory;
|
this.factory = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException
|
public SpanQuery getSpanQuery(Element e) throws ParserException {
|
||||||
{
|
String slopString = DOMUtils.getAttributeOrFail(e, "slop");
|
||||||
String slopString=DOMUtils.getAttributeOrFail(e,"slop");
|
int slop = Integer.parseInt(slopString);
|
||||||
int slop=Integer.parseInt(slopString);
|
boolean inOrder = DOMUtils.getAttribute(e, "inOrder", false);
|
||||||
boolean inOrder=DOMUtils.getAttribute(e,"inOrder",false);
|
List<SpanQuery> spans = new ArrayList<SpanQuery>();
|
||||||
ArrayList<SpanQuery> spans=new ArrayList<SpanQuery>();
|
for (Node kid = e.getFirstChild(); kid != null; kid = kid.getNextSibling()) {
|
||||||
for (Node kid = e.getFirstChild(); kid != null; kid = kid.getNextSibling())
|
if (kid.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
{
|
spans.add(factory.getSpanQuery((Element) kid));
|
||||||
if (kid.getNodeType() == Node.ELEMENT_NODE)
|
}
|
||||||
{
|
}
|
||||||
spans.add(factory.getSpanQuery((Element) kid));
|
SpanQuery[] spanQueries = spans.toArray(new SpanQuery[spans.size()]);
|
||||||
}
|
return new SpanNearQuery(spanQueries, slop, inOrder);
|
||||||
}
|
}
|
||||||
SpanQuery[] spanQueries= spans.toArray(new SpanQuery[spans.size()]);
|
|
||||||
SpanNearQuery snq=new SpanNearQuery(spanQueries,slop,inOrder);
|
|
||||||
return snq;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,36 +23,33 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpanNotBuilder extends SpanBuilderBase
|
public class SpanNotBuilder extends SpanBuilderBase {
|
||||||
{
|
|
||||||
|
|
||||||
SpanQueryBuilder factory;
|
|
||||||
|
|
||||||
/**
|
private final SpanQueryBuilder factory;
|
||||||
* @param factory
|
|
||||||
*/
|
|
||||||
public SpanNotBuilder(SpanQueryBuilder factory)
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
this.factory = factory;
|
|
||||||
}
|
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException
|
|
||||||
{
|
|
||||||
Element includeElem=DOMUtils.getChildByTagOrFail(e,"Include");
|
|
||||||
includeElem=DOMUtils.getFirstChildOrFail(includeElem);
|
|
||||||
|
|
||||||
Element excludeElem=DOMUtils.getChildByTagOrFail(e,"Exclude");
|
/**
|
||||||
excludeElem=DOMUtils.getFirstChildOrFail(excludeElem);
|
* @param factory
|
||||||
|
*/
|
||||||
|
public SpanNotBuilder(SpanQueryBuilder factory) {
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
SpanQuery include=factory.getSpanQuery(includeElem);
|
public SpanQuery getSpanQuery(Element e) throws ParserException {
|
||||||
SpanQuery exclude=factory.getSpanQuery(excludeElem);
|
Element includeElem = DOMUtils.getChildByTagOrFail(e, "Include");
|
||||||
|
includeElem = DOMUtils.getFirstChildOrFail(includeElem);
|
||||||
SpanNotQuery snq = new SpanNotQuery(include,exclude);
|
|
||||||
|
Element excludeElem = DOMUtils.getChildByTagOrFail(e, "Exclude");
|
||||||
snq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
excludeElem = DOMUtils.getFirstChildOrFail(excludeElem);
|
||||||
return snq;
|
|
||||||
}
|
SpanQuery include = factory.getSpanQuery(includeElem);
|
||||||
|
SpanQuery exclude = factory.getSpanQuery(excludeElem);
|
||||||
|
|
||||||
|
SpanNotQuery snq = new SpanNotQuery(include, exclude);
|
||||||
|
|
||||||
|
snq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
return snq;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package org.apache.lucene.xmlparser.builders;
|
package org.apache.lucene.xmlparser.builders;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.spans.SpanOrQuery;
|
import org.apache.lucene.search.spans.SpanOrQuery;
|
||||||
import org.apache.lucene.search.spans.SpanQuery;
|
import org.apache.lucene.search.spans.SpanQuery;
|
||||||
import org.apache.lucene.xmlparser.DOMUtils;
|
import org.apache.lucene.xmlparser.DOMUtils;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -26,34 +27,28 @@ import org.w3c.dom.Node;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpanOrBuilder extends SpanBuilderBase
|
public class SpanOrBuilder extends SpanBuilderBase {
|
||||||
{
|
|
||||||
|
private final SpanQueryBuilder factory;
|
||||||
SpanQueryBuilder factory;
|
|
||||||
|
public SpanOrBuilder(SpanQueryBuilder factory) {
|
||||||
public SpanOrBuilder(SpanQueryBuilder factory)
|
this.factory = factory;
|
||||||
{
|
}
|
||||||
super();
|
|
||||||
this.factory = factory;
|
public SpanQuery getSpanQuery(Element e) throws ParserException {
|
||||||
|
List<SpanQuery> clausesList = new ArrayList<SpanQuery>();
|
||||||
|
for (Node kid = e.getFirstChild(); kid != null; kid = kid.getNextSibling()) {
|
||||||
|
if (kid.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
SpanQuery clause = factory.getSpanQuery((Element) kid);
|
||||||
|
clausesList.add(clause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
SpanQuery[] clauses = clausesList.toArray(new SpanQuery[clausesList.size()]);
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException
|
SpanOrQuery soq = new SpanOrQuery(clauses);
|
||||||
{
|
soq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
ArrayList<SpanQuery> clausesList=new ArrayList<SpanQuery>();
|
return soq;
|
||||||
for (Node kid = e.getFirstChild(); kid != null; kid = kid.getNextSibling())
|
}
|
||||||
{
|
|
||||||
if (kid.getNodeType() == Node.ELEMENT_NODE)
|
|
||||||
{
|
|
||||||
SpanQuery clause=factory.getSpanQuery((Element) kid);
|
|
||||||
clausesList.add(clause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SpanQuery[] clauses= clausesList.toArray(new SpanQuery[clausesList.size()]);
|
|
||||||
SpanOrQuery soq = new SpanOrQuery(clauses);
|
|
||||||
soq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
|
||||||
return soq;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package org.apache.lucene.xmlparser.builders;
|
package org.apache.lucene.xmlparser.builders;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
|
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
|
||||||
|
@ -15,6 +11,11 @@ import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.xmlparser.DOMUtils;
|
import org.apache.lucene.xmlparser.DOMUtils;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -33,48 +34,43 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpanOrTermsBuilder extends SpanBuilderBase
|
public class SpanOrTermsBuilder extends SpanBuilderBase {
|
||||||
{
|
|
||||||
Analyzer analyzer;
|
private final Analyzer analyzer;
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* @param analyzer
|
||||||
* @param analyzer
|
*/
|
||||||
*/
|
public SpanOrTermsBuilder(Analyzer analyzer) {
|
||||||
public SpanOrTermsBuilder(Analyzer analyzer)
|
this.analyzer = analyzer;
|
||||||
{
|
}
|
||||||
super();
|
|
||||||
this.analyzer = analyzer;
|
public SpanQuery getSpanQuery(Element e) throws ParserException {
|
||||||
}
|
String fieldName = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException
|
String value = DOMUtils.getNonBlankTextOrFail(e);
|
||||||
{
|
|
||||||
String fieldName=DOMUtils.getAttributeWithInheritanceOrFail(e,"fieldName");
|
try {
|
||||||
String value=DOMUtils.getNonBlankTextOrFail(e);
|
List<SpanQuery> clausesList = new ArrayList<SpanQuery>();
|
||||||
|
TokenStream ts = analyzer.reusableTokenStream(fieldName, new StringReader(value));
|
||||||
try
|
TermToBytesRefAttribute termAtt = ts.addAttribute(TermToBytesRefAttribute.class);
|
||||||
{
|
|
||||||
ArrayList<SpanQuery> clausesList=new ArrayList<SpanQuery>();
|
|
||||||
TokenStream ts=analyzer.reusableTokenStream(fieldName,new StringReader(value));
|
|
||||||
TermToBytesRefAttribute termAtt = ts.addAttribute(TermToBytesRefAttribute.class);
|
|
||||||
BytesRef bytes = termAtt.getBytesRef();
|
BytesRef bytes = termAtt.getBytesRef();
|
||||||
ts.reset();
|
ts.reset();
|
||||||
while (ts.incrementToken()) {
|
while (ts.incrementToken()) {
|
||||||
termAtt.fillBytesRef();
|
termAtt.fillBytesRef();
|
||||||
SpanTermQuery stq=new SpanTermQuery(new Term(fieldName, new BytesRef(bytes)));
|
SpanTermQuery stq = new SpanTermQuery(new Term(fieldName, new BytesRef(bytes)));
|
||||||
clausesList.add(stq);
|
clausesList.add(stq);
|
||||||
}
|
}
|
||||||
ts.end();
|
ts.end();
|
||||||
ts.close();
|
ts.close();
|
||||||
SpanOrQuery soq=new SpanOrQuery(clausesList.toArray(new SpanQuery[clausesList.size()]));
|
SpanOrQuery soq = new SpanOrQuery(clausesList.toArray(new SpanQuery[clausesList.size()]));
|
||||||
soq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
soq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
return soq;
|
return soq;
|
||||||
}
|
}
|
||||||
catch(IOException ioe)
|
catch (IOException ioe) {
|
||||||
{
|
throw new ParserException("IOException parsing value:" + value);
|
||||||
throw new ParserException("IOException parsing value:"+value);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,7 @@ import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.apache.lucene.xmlparser.QueryBuilder;
|
import org.apache.lucene.xmlparser.QueryBuilder;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
public interface SpanQueryBuilder extends QueryBuilder {
|
||||||
public interface SpanQueryBuilder extends QueryBuilder{
|
|
||||||
|
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException;
|
public SpanQuery getSpanQuery(Element e) throws ParserException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package org.apache.lucene.xmlparser.builders;
|
package org.apache.lucene.xmlparser.builders;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.spans.SpanQuery;
|
import org.apache.lucene.search.spans.SpanQuery;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -24,27 +25,26 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpanQueryBuilderFactory implements SpanQueryBuilder {
|
public class SpanQueryBuilderFactory implements SpanQueryBuilder {
|
||||||
|
|
||||||
HashMap<String,SpanQueryBuilder> builders=new HashMap<String,SpanQueryBuilder>();
|
private final Map<String, SpanQueryBuilder> builders = new HashMap<String, SpanQueryBuilder>();
|
||||||
|
|
||||||
public Query getQuery(Element e) throws ParserException {
|
public Query getQuery(Element e) throws ParserException {
|
||||||
return getSpanQuery(e);
|
return getSpanQuery(e);
|
||||||
}
|
}
|
||||||
public void addBuilder(String nodeName,SpanQueryBuilder builder)
|
|
||||||
{
|
public void addBuilder(String nodeName, SpanQueryBuilder builder) {
|
||||||
builders.put(nodeName,builder);
|
builders.put(nodeName, builder);
|
||||||
}
|
}
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException
|
|
||||||
{
|
public SpanQuery getSpanQuery(Element e) throws ParserException {
|
||||||
SpanQueryBuilder builder= builders.get(e.getNodeName());
|
SpanQueryBuilder builder = builders.get(e.getNodeName());
|
||||||
if(builder==null)
|
if (builder == null) {
|
||||||
{
|
throw new ParserException("No SpanQueryObjectBuilder defined for node " + e.getNodeName());
|
||||||
throw new ParserException("No SpanQueryObjectBuilder defined for node "+e.getNodeName());
|
}
|
||||||
}
|
return builder.getSpanQuery(e);
|
||||||
return builder.getSpanQuery(e);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,20 +24,17 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SpanTermBuilder extends SpanBuilderBase
|
public class SpanTermBuilder extends SpanBuilderBase {
|
||||||
{
|
|
||||||
|
|
||||||
public SpanQuery getSpanQuery(Element e) throws ParserException
|
public SpanQuery getSpanQuery(Element e) throws ParserException {
|
||||||
{
|
String fieldName = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
String fieldName=DOMUtils.getAttributeWithInheritanceOrFail(e,"fieldName");
|
String value = DOMUtils.getNonBlankTextOrFail(e);
|
||||||
String value=DOMUtils.getNonBlankTextOrFail(e);
|
SpanTermQuery stq = new SpanTermQuery(new Term(fieldName, value));
|
||||||
SpanTermQuery stq = new SpanTermQuery(new Term(fieldName,value));
|
|
||||||
|
stq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
stq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
return stq;
|
||||||
return stq;
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,19 +25,16 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TermQueryBuilder implements QueryBuilder {
|
public class TermQueryBuilder implements QueryBuilder {
|
||||||
|
|
||||||
public Query getQuery(Element e) throws ParserException {
|
public Query getQuery(Element e) throws ParserException {
|
||||||
|
String field = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
String field=DOMUtils.getAttributeWithInheritanceOrFail(e,"fieldName");
|
String value = DOMUtils.getNonBlankTextOrFail(e);
|
||||||
String value=DOMUtils.getNonBlankTextOrFail(e);
|
TermQuery tq = new TermQuery(new Term(field, value));
|
||||||
TermQuery tq = new TermQuery(new Term(field,value));
|
tq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
tq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
return tq;
|
||||||
|
}
|
||||||
return tq;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package org.apache.lucene.xmlparser.builders;
|
package org.apache.lucene.xmlparser.builders;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
|
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
|
||||||
|
@ -15,6 +12,9 @@ import org.apache.lucene.xmlparser.FilterBuilder;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -33,51 +33,46 @@ import org.w3c.dom.Element;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TermsFilterBuilder implements FilterBuilder
|
public class TermsFilterBuilder implements FilterBuilder {
|
||||||
{
|
|
||||||
Analyzer analyzer;
|
private final Analyzer analyzer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param analyzer
|
* @param analyzer
|
||||||
*/
|
*/
|
||||||
public TermsFilterBuilder(Analyzer analyzer)
|
public TermsFilterBuilder(Analyzer analyzer) {
|
||||||
{
|
this.analyzer = analyzer;
|
||||||
this.analyzer = analyzer;
|
}
|
||||||
}
|
|
||||||
|
/*
|
||||||
/*
|
* (non-Javadoc)
|
||||||
* (non-Javadoc)
|
*
|
||||||
*
|
* @see org.apache.lucene.xmlparser.FilterBuilder#process(org.w3c.dom.Element)
|
||||||
* @see org.apache.lucene.xmlparser.FilterBuilder#process(org.w3c.dom.Element)
|
*/
|
||||||
*/
|
public Filter getFilter(Element e) throws ParserException {
|
||||||
public Filter getFilter(Element e) throws ParserException
|
TermsFilter tf = new TermsFilter();
|
||||||
{
|
String text = DOMUtils.getNonBlankTextOrFail(e);
|
||||||
TermsFilter tf = new TermsFilter();
|
String fieldName = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
String text = DOMUtils.getNonBlankTextOrFail(e);
|
|
||||||
String fieldName = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
try {
|
||||||
|
TokenStream ts = analyzer.reusableTokenStream(fieldName, new StringReader(text));
|
||||||
try
|
TermToBytesRefAttribute termAtt = ts.addAttribute(TermToBytesRefAttribute.class);
|
||||||
{
|
Term term = null;
|
||||||
TokenStream ts = analyzer.reusableTokenStream(fieldName, new StringReader(text));
|
|
||||||
TermToBytesRefAttribute termAtt = ts.addAttribute(TermToBytesRefAttribute.class);
|
|
||||||
Term term = null;
|
|
||||||
BytesRef bytes = termAtt.getBytesRef();
|
BytesRef bytes = termAtt.getBytesRef();
|
||||||
ts.reset();
|
ts.reset();
|
||||||
while (ts.incrementToken()) {
|
while (ts.incrementToken()) {
|
||||||
termAtt.fillBytesRef();
|
termAtt.fillBytesRef();
|
||||||
term = new Term(fieldName, new BytesRef(bytes));
|
term = new Term(fieldName, new BytesRef(bytes));
|
||||||
tf.addTerm(term);
|
tf.addTerm(term);
|
||||||
}
|
}
|
||||||
ts.end();
|
ts.end();
|
||||||
ts.close();
|
ts.close();
|
||||||
}
|
}
|
||||||
catch (IOException ioe)
|
catch (IOException ioe) {
|
||||||
{
|
throw new RuntimeException("Error constructing terms from index:" + ioe);
|
||||||
throw new RuntimeException("Error constructing terms from index:"
|
}
|
||||||
+ ioe);
|
return tf;
|
||||||
}
|
}
|
||||||
return tf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package org.apache.lucene.xmlparser.builders;
|
package org.apache.lucene.xmlparser.builders;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
|
import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
|
||||||
|
@ -17,6 +14,9 @@ import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.apache.lucene.xmlparser.QueryBuilder;
|
import org.apache.lucene.xmlparser.QueryBuilder;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -33,52 +33,44 @@ import org.w3c.dom.Element;
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a BooleanQuery from all of the terms found in the XML element using the choice of analyzer
|
* Builds a BooleanQuery from all of the terms found in the XML element using the choice of analyzer
|
||||||
*/
|
*/
|
||||||
public class TermsQueryBuilder implements QueryBuilder {
|
public class TermsQueryBuilder implements QueryBuilder {
|
||||||
|
|
||||||
Analyzer analyzer;
|
private final Analyzer analyzer;
|
||||||
|
|
||||||
|
public TermsQueryBuilder(Analyzer analyzer) {
|
||||||
public TermsQueryBuilder(Analyzer analyzer)
|
this.analyzer = analyzer;
|
||||||
{
|
}
|
||||||
this.analyzer = analyzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public Query getQuery(Element e) throws ParserException {
|
||||||
|
String fieldName = DOMUtils.getAttributeWithInheritanceOrFail(e, "fieldName");
|
||||||
|
String text = DOMUtils.getNonBlankTextOrFail(e);
|
||||||
|
|
||||||
|
BooleanQuery bq = new BooleanQuery(DOMUtils.getAttribute(e, "disableCoord", false));
|
||||||
public Query getQuery(Element e) throws ParserException {
|
bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e, "minimumNumberShouldMatch", 0));
|
||||||
|
try {
|
||||||
String fieldName=DOMUtils.getAttributeWithInheritanceOrFail(e,"fieldName");
|
TokenStream ts = analyzer.reusableTokenStream(fieldName, new StringReader(text));
|
||||||
String text=DOMUtils.getNonBlankTextOrFail(e);
|
TermToBytesRefAttribute termAtt = ts.addAttribute(TermToBytesRefAttribute.class);
|
||||||
|
Term term = null;
|
||||||
BooleanQuery bq=new BooleanQuery(DOMUtils.getAttribute(e,"disableCoord",false));
|
|
||||||
bq.setMinimumNumberShouldMatch(DOMUtils.getAttribute(e,"minimumNumberShouldMatch",0));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
TokenStream ts = analyzer.reusableTokenStream(fieldName, new StringReader(text));
|
|
||||||
TermToBytesRefAttribute termAtt = ts.addAttribute(TermToBytesRefAttribute.class);
|
|
||||||
Term term = null;
|
|
||||||
BytesRef bytes = termAtt.getBytesRef();
|
BytesRef bytes = termAtt.getBytesRef();
|
||||||
ts.reset();
|
ts.reset();
|
||||||
while (ts.incrementToken()) {
|
while (ts.incrementToken()) {
|
||||||
termAtt.fillBytesRef();
|
termAtt.fillBytesRef();
|
||||||
term = new Term(fieldName, new BytesRef(bytes));
|
term = new Term(fieldName, new BytesRef(bytes));
|
||||||
bq.add(new BooleanClause(new TermQuery(term),BooleanClause.Occur.SHOULD));
|
bq.add(new BooleanClause(new TermQuery(term), BooleanClause.Occur.SHOULD));
|
||||||
}
|
}
|
||||||
ts.end();
|
ts.end();
|
||||||
ts.close();
|
ts.close();
|
||||||
}
|
}
|
||||||
catch (IOException ioe)
|
catch (IOException ioe) {
|
||||||
{
|
throw new RuntimeException("Error constructing terms from index:" + ioe);
|
||||||
throw new RuntimeException("Error constructing terms from index:"
|
}
|
||||||
+ ioe);
|
|
||||||
}
|
|
||||||
bq.setBoost(DOMUtils.getAttribute(e,"boost",1.0f));
|
|
||||||
|
|
||||||
return bq;
|
bq.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
return bq;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.queryparser.classic.ParseException;
|
import org.apache.lucene.queryparser.classic.ParseException;
|
||||||
import org.apache.lucene.queryparser.classic.QueryParser;
|
import org.apache.lucene.queryparser.classic.QueryParser;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.util.Version;
|
||||||
import org.apache.lucene.xmlparser.DOMUtils;
|
import org.apache.lucene.xmlparser.DOMUtils;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.apache.lucene.xmlparser.QueryBuilder;
|
import org.apache.lucene.xmlparser.QueryBuilder;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.apache.lucene.util.Version;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
@ -35,62 +35,59 @@ import org.apache.lucene.util.Version;
|
||||||
*/
|
*/
|
||||||
public class UserInputQueryBuilder implements QueryBuilder {
|
public class UserInputQueryBuilder implements QueryBuilder {
|
||||||
|
|
||||||
QueryParser unSafeParser;
|
private QueryParser unSafeParser;
|
||||||
private Analyzer analyzer;
|
private Analyzer analyzer;
|
||||||
private String defaultField;
|
private String defaultField;
|
||||||
|
|
||||||
/**
|
|
||||||
* This constructor has the disadvantage of not being able to change choice of default field name
|
|
||||||
* @param parser thread un-safe query parser
|
|
||||||
*/
|
|
||||||
public UserInputQueryBuilder(QueryParser parser) {
|
|
||||||
this.unSafeParser = parser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserInputQueryBuilder(String defaultField, Analyzer analyzer) {
|
/**
|
||||||
this.analyzer = analyzer;
|
* This constructor has the disadvantage of not being able to change choice of default field name
|
||||||
this.defaultField = defaultField;
|
*
|
||||||
}
|
* @param parser thread un-safe query parser
|
||||||
|
*/
|
||||||
/* (non-Javadoc)
|
public UserInputQueryBuilder(QueryParser parser) {
|
||||||
* @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
|
this.unSafeParser = parser;
|
||||||
*/
|
}
|
||||||
public Query getQuery(Element e) throws ParserException {
|
|
||||||
String text=DOMUtils.getText(e);
|
public UserInputQueryBuilder(String defaultField, Analyzer analyzer) {
|
||||||
try {
|
this.analyzer = analyzer;
|
||||||
Query q = null;
|
this.defaultField = defaultField;
|
||||||
if(unSafeParser!=null)
|
}
|
||||||
{
|
|
||||||
//synchronize on unsafe parser
|
/* (non-Javadoc)
|
||||||
synchronized (unSafeParser)
|
* @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
|
||||||
{
|
*/
|
||||||
q = unSafeParser.parse(text);
|
|
||||||
}
|
public Query getQuery(Element e) throws ParserException {
|
||||||
}
|
String text = DOMUtils.getText(e);
|
||||||
else
|
try {
|
||||||
{
|
Query q = null;
|
||||||
String fieldName=DOMUtils.getAttribute(e, "fieldName", defaultField);
|
if (unSafeParser != null) {
|
||||||
//Create new parser
|
//synchronize on unsafe parser
|
||||||
QueryParser parser=createQueryParser(fieldName, analyzer);
|
synchronized (unSafeParser) {
|
||||||
q = parser.parse(text);
|
q = unSafeParser.parse(text);
|
||||||
}
|
}
|
||||||
// use the boost of the original query here, too and multiply (which may be != 1.0f):
|
} else {
|
||||||
q.setBoost(q.getBoost()*DOMUtils.getAttribute(e,"boost",1.0f));
|
String fieldName = DOMUtils.getAttribute(e, "fieldName", defaultField);
|
||||||
return q;
|
//Create new parser
|
||||||
} catch (ParseException e1) {
|
QueryParser parser = createQueryParser(fieldName, analyzer);
|
||||||
throw new ParserException(e1.getMessage());
|
q = parser.parse(text);
|
||||||
}
|
}
|
||||||
}
|
q.setBoost(DOMUtils.getAttribute(e, "boost", 1.0f));
|
||||||
|
return q;
|
||||||
/**
|
} catch (ParseException e1) {
|
||||||
* Method to create a QueryParser - designed to be overridden
|
throw new ParserException(e1.getMessage());
|
||||||
* @param fieldName
|
}
|
||||||
* @param analyzer
|
}
|
||||||
* @return QueryParser
|
|
||||||
*/
|
/**
|
||||||
protected QueryParser createQueryParser(String fieldName, Analyzer analyzer)
|
* Method to create a QueryParser - designed to be overridden
|
||||||
{
|
*
|
||||||
return new QueryParser(Version.LUCENE_CURRENT, fieldName,analyzer);
|
* @param fieldName
|
||||||
|
* @param analyzer
|
||||||
|
* @return QueryParser
|
||||||
|
*/
|
||||||
|
protected QueryParser createQueryParser(String fieldName, Analyzer analyzer) {
|
||||||
|
return new QueryParser(Version.LUCENE_CURRENT, fieldName, analyzer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
package org.apache.lucene.xmlparser;
|
package org.apache.lucene.xmlparser;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.MockAnalyzer;
|
import org.apache.lucene.analysis.MockAnalyzer;
|
||||||
import org.apache.lucene.analysis.MockTokenFilter;
|
import org.apache.lucene.analysis.MockTokenFilter;
|
||||||
|
@ -18,11 +13,17 @@ import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.ScoreDoc;
|
import org.apache.lucene.search.ScoreDoc;
|
||||||
import org.apache.lucene.search.TopDocs;
|
import org.apache.lucene.search.TopDocs;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.util.Version;
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
import org.apache.lucene.util.Version;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -30,9 +31,9 @@ import org.junit.BeforeClass;
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
* 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 not use this file except in compliance with
|
||||||
* the License. You may obtain a copy of the License at
|
* the License. You may obtain a copy of the License at
|
||||||
*
|
* <p/>
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
* <p/>
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -41,201 +42,185 @@ import org.junit.BeforeClass;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class TestParser extends LuceneTestCase {
|
public class TestParser extends LuceneTestCase {
|
||||||
private static CoreParser builder;
|
|
||||||
private static Directory dir;
|
|
||||||
private static IndexReader reader;
|
|
||||||
private static IndexSearcher searcher;
|
|
||||||
|
|
||||||
@BeforeClass
|
private static CoreParser builder;
|
||||||
public static void beforeClass() throws Exception {
|
private static Directory dir;
|
||||||
// TODO: rewrite test (this needs to set QueryParser.enablePositionIncrements, too, for work with CURRENT):
|
private static IndexReader reader;
|
||||||
Analyzer analyzer=new MockAnalyzer(random, MockTokenizer.WHITESPACE, true, MockTokenFilter.ENGLISH_STOPSET, false);
|
private static IndexSearcher searcher;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
// TODO: rewrite test (this needs to set QueryParser.enablePositionIncrements, too, for work with CURRENT):
|
||||||
|
Analyzer analyzer = new MockAnalyzer(random, MockTokenizer.WHITESPACE, true, MockTokenFilter.ENGLISH_STOPSET, false);
|
||||||
//initialize the parser
|
//initialize the parser
|
||||||
builder=new CorePlusExtensionsParser("contents",analyzer);
|
builder = new CorePlusExtensionsParser("contents", analyzer);
|
||||||
|
|
||||||
BufferedReader d = new BufferedReader(new InputStreamReader(TestParser.class.getResourceAsStream("reuters21578.txt")));
|
|
||||||
dir=newDirectory();
|
|
||||||
IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(Version.LUCENE_40, analyzer));
|
|
||||||
String line = d.readLine();
|
|
||||||
while(line!=null)
|
|
||||||
{
|
|
||||||
int endOfDate=line.indexOf('\t');
|
|
||||||
String date=line.substring(0,endOfDate).trim();
|
|
||||||
String content=line.substring(endOfDate).trim();
|
|
||||||
org.apache.lucene.document.Document doc =new org.apache.lucene.document.Document();
|
|
||||||
doc.add(newField("date",date,Field.Store.YES,Field.Index.ANALYZED));
|
|
||||||
doc.add(newField("contents",content,Field.Store.YES,Field.Index.ANALYZED));
|
|
||||||
NumericField numericField = new NumericField("date2");
|
|
||||||
numericField.setIntValue(Integer.valueOf(date));
|
|
||||||
doc.add(numericField);
|
|
||||||
writer.addDocument(doc);
|
|
||||||
line=d.readLine();
|
|
||||||
}
|
|
||||||
d.close();
|
|
||||||
writer.close();
|
|
||||||
reader=IndexReader.open(dir, true);
|
|
||||||
searcher=newSearcher(reader);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void afterClass() throws Exception {
|
|
||||||
reader.close();
|
|
||||||
searcher.close();
|
|
||||||
dir.close();
|
|
||||||
reader = null;
|
|
||||||
searcher = null;
|
|
||||||
dir = null;
|
|
||||||
builder = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSimpleXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("TermQuery.xml");
|
|
||||||
dumpResults("TermQuery", q, 5);
|
|
||||||
}
|
|
||||||
public void testSimpleTermsQueryXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("TermsQuery.xml");
|
|
||||||
dumpResults("TermsQuery", q, 5);
|
|
||||||
}
|
|
||||||
public void testBooleanQueryXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("BooleanQuery.xml");
|
|
||||||
dumpResults("BooleanQuery", q, 5);
|
|
||||||
}
|
|
||||||
public void testRangeFilterQueryXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("RangeFilterQuery.xml");
|
|
||||||
dumpResults("RangeFilter", q, 5);
|
|
||||||
}
|
|
||||||
public void testUserQueryXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("UserInputQuery.xml");
|
|
||||||
dumpResults("UserInput with Filter", q, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCustomFieldUserQueryXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("UserInputQueryCustomField.xml");
|
|
||||||
assertEquals(20.0f, q.getBoost());
|
|
||||||
int h = searcher.search(q, null, 1000).totalHits;
|
|
||||||
assertEquals("UserInputQueryCustomField should produce 0 result ", 0,h);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testLikeThisQueryXML() throws Exception
|
|
||||||
{
|
|
||||||
Query q=parse("LikeThisQuery.xml");
|
|
||||||
dumpResults("like this", q, 5);
|
|
||||||
}
|
|
||||||
public void testBoostingQueryXML() throws Exception
|
|
||||||
{
|
|
||||||
Query q=parse("BoostingQuery.xml");
|
|
||||||
dumpResults("boosting ",q, 5);
|
|
||||||
}
|
|
||||||
public void testFuzzyLikeThisQueryXML() throws Exception
|
|
||||||
{
|
|
||||||
Query q=parse("FuzzyLikeThisQuery.xml");
|
|
||||||
//show rewritten fuzzyLikeThisQuery - see what is being matched on
|
|
||||||
if(VERBOSE)
|
|
||||||
{
|
|
||||||
System.out.println(q.rewrite(reader));
|
|
||||||
}
|
|
||||||
dumpResults("FuzzyLikeThis", q, 5);
|
|
||||||
}
|
|
||||||
public void testTermsFilterXML() throws Exception
|
|
||||||
{
|
|
||||||
Query q=parse("TermsFilterQuery.xml");
|
|
||||||
dumpResults("Terms Filter",q, 5);
|
|
||||||
}
|
|
||||||
public void testBoostingTermQueryXML() throws Exception
|
|
||||||
{
|
|
||||||
Query q=parse("BoostingTermQuery.xml");
|
|
||||||
dumpResults("BoostingTermQuery",q, 5);
|
|
||||||
}
|
|
||||||
public void testSpanTermXML() throws Exception
|
|
||||||
{
|
|
||||||
Query q=parse("SpanQuery.xml");
|
|
||||||
dumpResults("Span Query",q, 5);
|
|
||||||
}
|
|
||||||
public void testConstantScoreQueryXML() throws Exception
|
|
||||||
{
|
|
||||||
Query q=parse("ConstantScoreQuery.xml");
|
|
||||||
dumpResults("ConstantScoreQuery",q, 5);
|
|
||||||
}
|
|
||||||
public void testMatchAllDocsPlusFilterXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("MatchAllDocsQuery.xml");
|
|
||||||
dumpResults("MatchAllDocsQuery with range filter", q, 5);
|
|
||||||
}
|
|
||||||
public void testBooleanFilterXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("BooleanFilter.xml");
|
|
||||||
dumpResults("Boolean filter", q, 5);
|
|
||||||
}
|
|
||||||
public void testNestedBooleanQuery() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("NestedBooleanQuery.xml");
|
|
||||||
dumpResults("Nested Boolean query", q, 5);
|
|
||||||
}
|
|
||||||
public void testCachedFilterXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("CachedFilter.xml");
|
|
||||||
dumpResults("Cached filter", q, 5);
|
|
||||||
}
|
|
||||||
public void testDuplicateFilterQueryXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Assume.assumeTrue(searcher.getIndexReader().getSequentialSubReaders() == null ||
|
|
||||||
searcher.getIndexReader().getSequentialSubReaders().length == 1);
|
|
||||||
Query q=parse("DuplicateFilterQuery.xml");
|
|
||||||
int h = searcher.search(q, null, 1000).totalHits;
|
|
||||||
assertEquals("DuplicateFilterQuery should produce 1 result ", 1,h);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNumericRangeFilterQueryXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("NumericRangeFilterQuery.xml");
|
|
||||||
dumpResults("NumericRangeFilter", q, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNumericRangeQueryQueryXML() throws ParserException, IOException
|
|
||||||
{
|
|
||||||
Query q=parse("NumericRangeQueryQuery.xml");
|
|
||||||
dumpResults("NumericRangeQuery", q, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
BufferedReader d = new BufferedReader(new InputStreamReader(TestParser.class.getResourceAsStream("reuters21578.txt")));
|
||||||
|
dir = newDirectory();
|
||||||
|
IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(Version.LUCENE_40, analyzer));
|
||||||
|
String line = d.readLine();
|
||||||
|
while (line != null) {
|
||||||
|
int endOfDate = line.indexOf('\t');
|
||||||
|
String date = line.substring(0, endOfDate).trim();
|
||||||
|
String content = line.substring(endOfDate).trim();
|
||||||
|
org.apache.lucene.document.Document doc = new org.apache.lucene.document.Document();
|
||||||
|
doc.add(newField("date", date, Field.Store.YES, Field.Index.ANALYZED));
|
||||||
|
doc.add(newField("contents", content, Field.Store.YES, Field.Index.ANALYZED));
|
||||||
|
NumericField numericField = new NumericField("date2");
|
||||||
|
numericField.setIntValue(Integer.valueOf(date));
|
||||||
|
doc.add(numericField);
|
||||||
|
writer.addDocument(doc);
|
||||||
|
line = d.readLine();
|
||||||
|
}
|
||||||
|
d.close();
|
||||||
|
writer.close();
|
||||||
|
reader = IndexReader.open(dir, true);
|
||||||
|
searcher = newSearcher(reader);
|
||||||
|
|
||||||
//================= Helper methods ===================================
|
}
|
||||||
private Query parse(String xmlFileName) throws ParserException, IOException
|
|
||||||
{
|
|
||||||
InputStream xmlStream=TestParser.class.getResourceAsStream(xmlFileName);
|
|
||||||
Query result=builder.parse(xmlStream);
|
|
||||||
xmlStream.close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
private void dumpResults(String qType,Query q, int numDocs) throws IOException
|
|
||||||
{
|
|
||||||
if (VERBOSE) {
|
|
||||||
System.out.println("TEST: query=" + q);
|
|
||||||
}
|
|
||||||
TopDocs hits = searcher.search(q, null, numDocs);
|
|
||||||
assertTrue(qType +" should produce results ", hits.totalHits>0);
|
|
||||||
if(VERBOSE)
|
|
||||||
{
|
|
||||||
System.out.println("========="+qType+"============");
|
|
||||||
ScoreDoc[] scoreDocs = hits.scoreDocs;
|
|
||||||
for(int i=0;i<Math.min(numDocs,hits.totalHits);i++)
|
|
||||||
{
|
|
||||||
org.apache.lucene.document.Document ldoc=searcher.doc(scoreDocs[i].doc);
|
|
||||||
System.out.println("["+ldoc.get("date")+"]"+ldoc.get("contents"));
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() throws Exception {
|
||||||
|
reader.close();
|
||||||
|
searcher.close();
|
||||||
|
dir.close();
|
||||||
|
reader = null;
|
||||||
|
searcher = null;
|
||||||
|
dir = null;
|
||||||
|
builder = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSimpleXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("TermQuery.xml");
|
||||||
|
dumpResults("TermQuery", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSimpleTermsQueryXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("TermsQuery.xml");
|
||||||
|
dumpResults("TermsQuery", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBooleanQueryXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("BooleanQuery.xml");
|
||||||
|
dumpResults("BooleanQuery", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRangeFilterQueryXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("RangeFilterQuery.xml");
|
||||||
|
dumpResults("RangeFilter", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUserQueryXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("UserInputQuery.xml");
|
||||||
|
dumpResults("UserInput with Filter", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCustomFieldUserQueryXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("UserInputQueryCustomField.xml");
|
||||||
|
int h = searcher.search(q, null, 1000).totalHits;
|
||||||
|
assertEquals("UserInputQueryCustomField should produce 0 result ", 0, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLikeThisQueryXML() throws Exception {
|
||||||
|
Query q = parse("LikeThisQuery.xml");
|
||||||
|
dumpResults("like this", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBoostingQueryXML() throws Exception {
|
||||||
|
Query q = parse("BoostingQuery.xml");
|
||||||
|
dumpResults("boosting ", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFuzzyLikeThisQueryXML() throws Exception {
|
||||||
|
Query q = parse("FuzzyLikeThisQuery.xml");
|
||||||
|
//show rewritten fuzzyLikeThisQuery - see what is being matched on
|
||||||
|
if (VERBOSE) {
|
||||||
|
System.out.println(q.rewrite(reader));
|
||||||
|
}
|
||||||
|
dumpResults("FuzzyLikeThis", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTermsFilterXML() throws Exception {
|
||||||
|
Query q = parse("TermsFilterQuery.xml");
|
||||||
|
dumpResults("Terms Filter", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBoostingTermQueryXML() throws Exception {
|
||||||
|
Query q = parse("BoostingTermQuery.xml");
|
||||||
|
dumpResults("BoostingTermQuery", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSpanTermXML() throws Exception {
|
||||||
|
Query q = parse("SpanQuery.xml");
|
||||||
|
dumpResults("Span Query", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConstantScoreQueryXML() throws Exception {
|
||||||
|
Query q = parse("ConstantScoreQuery.xml");
|
||||||
|
dumpResults("ConstantScoreQuery", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMatchAllDocsPlusFilterXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("MatchAllDocsQuery.xml");
|
||||||
|
dumpResults("MatchAllDocsQuery with range filter", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBooleanFilterXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("BooleanFilter.xml");
|
||||||
|
dumpResults("Boolean filter", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNestedBooleanQuery() throws ParserException, IOException {
|
||||||
|
Query q = parse("NestedBooleanQuery.xml");
|
||||||
|
dumpResults("Nested Boolean query", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCachedFilterXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("CachedFilter.xml");
|
||||||
|
dumpResults("Cached filter", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDuplicateFilterQueryXML() throws ParserException, IOException {
|
||||||
|
Assume.assumeTrue(searcher.getIndexReader().getSequentialSubReaders() == null ||
|
||||||
|
searcher.getIndexReader().getSequentialSubReaders().length == 1);
|
||||||
|
Query q = parse("DuplicateFilterQuery.xml");
|
||||||
|
int h = searcher.search(q, null, 1000).totalHits;
|
||||||
|
assertEquals("DuplicateFilterQuery should produce 1 result ", 1, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNumericRangeFilterQueryXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("NumericRangeFilterQuery.xml");
|
||||||
|
dumpResults("NumericRangeFilter", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNumericRangeQueryQueryXML() throws ParserException, IOException {
|
||||||
|
Query q = parse("NumericRangeQueryQuery.xml");
|
||||||
|
dumpResults("NumericRangeQuery", q, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
//================= Helper methods ===================================
|
||||||
|
|
||||||
|
private Query parse(String xmlFileName) throws ParserException, IOException {
|
||||||
|
InputStream xmlStream = TestParser.class.getResourceAsStream(xmlFileName);
|
||||||
|
Query result = builder.parse(xmlStream);
|
||||||
|
xmlStream.close();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dumpResults(String qType, Query q, int numDocs) throws IOException {
|
||||||
|
if (VERBOSE) {
|
||||||
|
System.out.println("TEST: query=" + q);
|
||||||
|
}
|
||||||
|
TopDocs hits = searcher.search(q, null, numDocs);
|
||||||
|
assertTrue(qType + " should produce results ", hits.totalHits > 0);
|
||||||
|
if (VERBOSE) {
|
||||||
|
System.out.println("=========" + qType + "============");
|
||||||
|
ScoreDoc[] scoreDocs = hits.scoreDocs;
|
||||||
|
for (int i = 0; i < Math.min(numDocs, hits.totalHits); i++) {
|
||||||
|
org.apache.lucene.document.Document ldoc = searcher.doc(scoreDocs[i].doc);
|
||||||
|
System.out.println("[" + ldoc.get("date") + "]" + ldoc.get("contents"));
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
package org.apache.lucene.xmlparser;
|
package org.apache.lucene.xmlparser;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import javax.xml.transform.TransformerException;
|
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.MockAnalyzer;
|
import org.apache.lucene.analysis.MockAnalyzer;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
|
@ -17,10 +9,16 @@ import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.lucene.util.Constants;
|
import org.apache.lucene.util.Constants;
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
@ -37,138 +35,128 @@ import org.xml.sax.SAXException;
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class illustrates how form input (such as from a web page or Swing gui) can be
|
* This class illustrates how form input (such as from a web page or Swing gui) can be
|
||||||
* turned into Lucene queries using a choice of XSL templates for different styles of queries.
|
* turned into Lucene queries using a choice of XSL templates for different styles of queries.
|
||||||
*/
|
*/
|
||||||
public class TestQueryTemplateManager extends LuceneTestCase {
|
public class TestQueryTemplateManager extends LuceneTestCase {
|
||||||
|
|
||||||
CoreParser builder;
|
private CoreParser builder;
|
||||||
Analyzer analyzer=new MockAnalyzer(random);
|
private final Analyzer analyzer = new MockAnalyzer(random);
|
||||||
private IndexSearcher searcher;
|
private IndexSearcher searcher;
|
||||||
private Directory dir;
|
private Directory dir;
|
||||||
|
|
||||||
//A collection of documents' field values for use in our tests
|
//A collection of documents' field values for use in our tests
|
||||||
String docFieldValues []=
|
String docFieldValues[] =
|
||||||
{
|
{
|
||||||
"artist=Jeff Buckley \talbum=Grace \treleaseDate=1999 \tgenre=rock",
|
"artist=Jeff Buckley \talbum=Grace \treleaseDate=1999 \tgenre=rock",
|
||||||
"artist=Fugazi \talbum=Repeater \treleaseDate=1990 \tgenre=alternative",
|
"artist=Fugazi \talbum=Repeater \treleaseDate=1990 \tgenre=alternative",
|
||||||
"artist=Fugazi \talbum=Red Medicine \treleaseDate=1995 \tgenre=alternative",
|
"artist=Fugazi \talbum=Red Medicine \treleaseDate=1995 \tgenre=alternative",
|
||||||
"artist=Peeping Tom \talbum=Peeping Tom \treleaseDate=2006 \tgenre=rock",
|
"artist=Peeping Tom \talbum=Peeping Tom \treleaseDate=2006 \tgenre=rock",
|
||||||
"artist=Red Snapper \talbum=Prince Blimey \treleaseDate=1996 \tgenre=electronic"
|
"artist=Red Snapper \talbum=Prince Blimey \treleaseDate=1996 \tgenre=electronic"
|
||||||
};
|
};
|
||||||
|
|
||||||
//A collection of example queries, consisting of name/value pairs representing form content plus
|
//A collection of example queries, consisting of name/value pairs representing form content plus
|
||||||
// a choice of query style template to use in the test, with expected number of hits
|
// a choice of query style template to use in the test, with expected number of hits
|
||||||
String queryForms[]=
|
String queryForms[] =
|
||||||
{
|
{
|
||||||
"artist=Fugazi \texpectedMatches=2 \ttemplate=albumBooleanQuery",
|
"artist=Fugazi \texpectedMatches=2 \ttemplate=albumBooleanQuery",
|
||||||
"artist=Fugazi \treleaseDate=1990 \texpectedMatches=1 \ttemplate=albumBooleanQuery",
|
"artist=Fugazi \treleaseDate=1990 \texpectedMatches=1 \ttemplate=albumBooleanQuery",
|
||||||
"artist=Buckley \tgenre=rock \texpectedMatches=1 \ttemplate=albumFilteredQuery",
|
"artist=Buckley \tgenre=rock \texpectedMatches=1 \ttemplate=albumFilteredQuery",
|
||||||
"artist=Buckley \tgenre=electronic \texpectedMatches=0 \ttemplate=albumFilteredQuery",
|
"artist=Buckley \tgenre=electronic \texpectedMatches=0 \ttemplate=albumFilteredQuery",
|
||||||
"queryString=artist:buckly~ NOT genre:electronic \texpectedMatches=1 \ttemplate=albumLuceneClassicQuery"
|
"queryString=artist:buckly~ NOT genre:electronic \texpectedMatches=1 \ttemplate=albumLuceneClassicQuery"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public void testFormTransforms() throws SAXException, IOException, ParserConfigurationException, TransformerException, ParserException
|
public void testFormTransforms() throws SAXException, IOException, ParserConfigurationException, TransformerException, ParserException {
|
||||||
{
|
// Sun 1.5 suffers from http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6240963
|
||||||
// Sun 1.5 suffers from http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6240963
|
if (Constants.JAVA_VENDOR.startsWith("Sun") && Constants.JAVA_VERSION.startsWith("1.5")) {
|
||||||
if (Constants.JAVA_VENDOR.startsWith("Sun") && Constants.JAVA_VERSION.startsWith("1.5")) {
|
String defLang = Locale.getDefault().getLanguage();
|
||||||
String defLang = Locale.getDefault().getLanguage();
|
assumeFalse("Sun JRE 1.5 suffers from http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6240963 under Turkish locale", defLang.equals("tr") || defLang.equals("az"));
|
||||||
assumeFalse("Sun JRE 1.5 suffers from http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6240963 under Turkish locale", defLang.equals("tr") || defLang.equals("az"));
|
}
|
||||||
}
|
//Cache all the query templates we will be referring to.
|
||||||
//Cache all the query templates we will be referring to.
|
QueryTemplateManager qtm = new QueryTemplateManager();
|
||||||
QueryTemplateManager qtm=new QueryTemplateManager();
|
qtm.addQueryTemplate("albumBooleanQuery", getClass().getResourceAsStream("albumBooleanQuery.xsl"));
|
||||||
qtm.addQueryTemplate("albumBooleanQuery", getClass().getResourceAsStream("albumBooleanQuery.xsl"));
|
qtm.addQueryTemplate("albumFilteredQuery", getClass().getResourceAsStream("albumFilteredQuery.xsl"));
|
||||||
qtm.addQueryTemplate("albumFilteredQuery", getClass().getResourceAsStream("albumFilteredQuery.xsl"));
|
qtm.addQueryTemplate("albumLuceneClassicQuery", getClass().getResourceAsStream("albumLuceneClassicQuery.xsl"));
|
||||||
qtm.addQueryTemplate("albumLuceneClassicQuery", getClass().getResourceAsStream("albumLuceneClassicQuery.xsl"));
|
//Run all of our test queries
|
||||||
//Run all of our test queries
|
for (String queryForm : queryForms) {
|
||||||
for (int i = 0; i < queryForms.length; i++)
|
Properties queryFormProperties = getPropsFromString(queryForm);
|
||||||
{
|
|
||||||
Properties queryFormProperties=getPropsFromString(queryForms[i]);
|
//Get the required query XSL template for this test
|
||||||
|
|
||||||
//Get the required query XSL template for this test
|
|
||||||
// Templates template=getTemplate(queryFormProperties.getProperty("template"));
|
// Templates template=getTemplate(queryFormProperties.getProperty("template"));
|
||||||
|
|
||||||
//Transform the queryFormProperties into a Lucene XML query
|
//Transform the queryFormProperties into a Lucene XML query
|
||||||
Document doc=qtm.getQueryAsDOM(queryFormProperties,queryFormProperties.getProperty("template"));
|
Document doc = qtm.getQueryAsDOM(queryFormProperties, queryFormProperties.getProperty("template"));
|
||||||
|
|
||||||
//Parse the XML query using the XML parser
|
//Parse the XML query using the XML parser
|
||||||
Query q=builder.getQuery(doc.getDocumentElement());
|
Query q = builder.getQuery(doc.getDocumentElement());
|
||||||
|
|
||||||
//Run the query
|
//Run the query
|
||||||
int h=searcher.search(q, null, 1000).totalHits;
|
int h = searcher.search(q, null, 1000).totalHits;
|
||||||
|
|
||||||
//Check we have the expected number of results
|
//Check we have the expected number of results
|
||||||
int expectedHits=Integer.parseInt(queryFormProperties.getProperty("expectedMatches"));
|
int expectedHits = Integer.parseInt(queryFormProperties.getProperty("expectedMatches"));
|
||||||
assertEquals("Number of results should match for query "+queryForms[i],expectedHits,h);
|
assertEquals("Number of results should match for query " + queryForm, expectedHits, h);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Helper method to construct Lucene query forms used in our test
|
//Helper method to construct Lucene query forms used in our test
|
||||||
Properties getPropsFromString(String nameValuePairs)
|
Properties getPropsFromString(String nameValuePairs) {
|
||||||
{
|
Properties result = new Properties();
|
||||||
Properties result=new Properties();
|
StringTokenizer st = new StringTokenizer(nameValuePairs, "\t=");
|
||||||
StringTokenizer st=new StringTokenizer(nameValuePairs,"\t=");
|
while (st.hasMoreTokens()) {
|
||||||
while(st.hasMoreTokens())
|
String name = st.nextToken().trim();
|
||||||
{
|
if (st.hasMoreTokens()) {
|
||||||
String name=st.nextToken().trim();
|
String value = st.nextToken().trim();
|
||||||
if(st.hasMoreTokens())
|
result.setProperty(name, value);
|
||||||
{
|
}
|
||||||
String value=st.nextToken().trim();
|
}
|
||||||
result.setProperty(name,value);
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result;
|
//Helper method to construct Lucene documents used in our tests
|
||||||
}
|
org.apache.lucene.document.Document getDocumentFromString(String nameValuePairs) {
|
||||||
|
org.apache.lucene.document.Document result = new org.apache.lucene.document.Document();
|
||||||
//Helper method to construct Lucene documents used in our tests
|
StringTokenizer st = new StringTokenizer(nameValuePairs, "\t=");
|
||||||
org.apache.lucene.document.Document getDocumentFromString(String nameValuePairs)
|
while (st.hasMoreTokens()) {
|
||||||
{
|
String name = st.nextToken().trim();
|
||||||
org.apache.lucene.document.Document result=new org.apache.lucene.document.Document();
|
if (st.hasMoreTokens()) {
|
||||||
StringTokenizer st=new StringTokenizer(nameValuePairs,"\t=");
|
String value = st.nextToken().trim();
|
||||||
while(st.hasMoreTokens())
|
result.add(newField(name, value, Field.Store.YES, Field.Index.ANALYZED));
|
||||||
{
|
}
|
||||||
String name=st.nextToken().trim();
|
}
|
||||||
if(st.hasMoreTokens())
|
return result;
|
||||||
{
|
}
|
||||||
String value=st.nextToken().trim();
|
|
||||||
result.add(newField(name,value,Field.Store.YES,Field.Index.ANALYZED));
|
/*
|
||||||
}
|
* @see TestCase#setUp()
|
||||||
}
|
*/
|
||||||
return result;
|
@Override
|
||||||
}
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
/*
|
|
||||||
* @see TestCase#setUp()
|
//Create an index
|
||||||
*/
|
dir = newDirectory();
|
||||||
@Override
|
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, analyzer));
|
||||||
public void setUp() throws Exception {
|
for (String docFieldValue : docFieldValues) {
|
||||||
super.setUp();
|
w.addDocument(getDocumentFromString(docFieldValue));
|
||||||
|
}
|
||||||
|
w.optimize();
|
||||||
//Create an index
|
w.close();
|
||||||
dir=newDirectory();
|
searcher = new IndexSearcher(dir, true);
|
||||||
IndexWriter w=new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, analyzer));
|
|
||||||
for (int i = 0; i < docFieldValues.length; i++)
|
//initialize the parser
|
||||||
{
|
builder = new CorePlusExtensionsParser("artist", analyzer);
|
||||||
w.addDocument(getDocumentFromString(docFieldValues[i]));
|
|
||||||
}
|
}
|
||||||
w.optimize();
|
|
||||||
w.close();
|
@Override
|
||||||
searcher=new IndexSearcher(dir, true);
|
public void tearDown() throws Exception {
|
||||||
|
searcher.close();
|
||||||
//initialize the parser
|
dir.close();
|
||||||
builder=new CorePlusExtensionsParser("artist", analyzer);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
searcher.close();
|
|
||||||
dir.close();
|
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,6 @@ package org.apache.lucene.xmlparser.builders;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
|
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
|
||||||
import org.apache.lucene.index.IndexWriter;
|
import org.apache.lucene.index.IndexWriter;
|
||||||
|
@ -34,184 +24,191 @@ import org.apache.lucene.index.SlowMultiReaderWrapper;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.Filter;
|
||||||
import org.apache.lucene.search.NumericRangeFilter;
|
import org.apache.lucene.search.NumericRangeFilter;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class TestNumericRangeFilterBuilder extends LuceneTestCase {
|
public class TestNumericRangeFilterBuilder extends LuceneTestCase {
|
||||||
|
|
||||||
public void testGetFilterHandleNumericParseErrorStrict() throws Exception {
|
public void testGetFilterHandleNumericParseErrorStrict() throws Exception {
|
||||||
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
||||||
filterBuilder.setStrictMode(true);
|
filterBuilder.setStrictMode(true);
|
||||||
|
|
||||||
String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
|
String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
|
||||||
Document doc = getDocumentFromString(xml);
|
Document doc = getDocumentFromString(xml);
|
||||||
try {
|
try {
|
||||||
filterBuilder.getFilter(doc.getDocumentElement());
|
filterBuilder.getFilter(doc.getDocumentElement());
|
||||||
} catch (ParserException e) {
|
} catch (ParserException e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fail("Expected to throw " + ParserException.class);
|
fail("Expected to throw " + ParserException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetFilterHandleNumericParseError() throws Exception {
|
public void testGetFilterHandleNumericParseError() throws Exception {
|
||||||
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
||||||
filterBuilder.setStrictMode(false);
|
filterBuilder.setStrictMode(false);
|
||||||
|
|
||||||
String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
|
String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
|
||||||
Document doc = getDocumentFromString(xml);
|
Document doc = getDocumentFromString(xml);
|
||||||
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
||||||
Directory ramDir = newDirectory();
|
Directory ramDir = newDirectory();
|
||||||
IndexWriter writer = new IndexWriter(ramDir, newIndexWriterConfig(TEST_VERSION_CURRENT, null));
|
IndexWriter writer = new IndexWriter(ramDir, newIndexWriterConfig(TEST_VERSION_CURRENT, null));
|
||||||
writer.commit();
|
writer.commit();
|
||||||
try
|
try {
|
||||||
{
|
IndexReader reader = new SlowMultiReaderWrapper(IndexReader.open(ramDir, true));
|
||||||
IndexReader reader = new SlowMultiReaderWrapper(IndexReader.open(ramDir, true));
|
try {
|
||||||
try
|
assertNull(filter.getDocIdSet((AtomicReaderContext) reader.getTopReaderContext()));
|
||||||
{
|
}
|
||||||
assertNull(filter.getDocIdSet((AtomicReaderContext) reader.getTopReaderContext()));
|
finally {
|
||||||
}
|
reader.close();
|
||||||
finally
|
}
|
||||||
{
|
}
|
||||||
reader.close();
|
finally {
|
||||||
}
|
writer.commit();
|
||||||
}
|
writer.close();
|
||||||
finally
|
ramDir.close();
|
||||||
{
|
}
|
||||||
writer.commit();
|
}
|
||||||
writer.close();
|
|
||||||
ramDir.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetFilterInt() throws Exception {
|
@SuppressWarnings("unchecked")
|
||||||
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
public void testGetFilterInt() throws Exception {
|
||||||
filterBuilder.setStrictMode(true);
|
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
||||||
|
filterBuilder.setStrictMode(true);
|
||||||
|
|
||||||
String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10'/>";
|
String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10'/>";
|
||||||
Document doc = getDocumentFromString(xml);
|
Document doc = getDocumentFromString(xml);
|
||||||
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
||||||
assertTrue(filter instanceof NumericRangeFilter<?>);
|
assertTrue(filter instanceof NumericRangeFilter<?>);
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
NumericRangeFilter<Integer> numRangeFilter = (NumericRangeFilter<Integer>) filter;
|
|
||||||
assertEquals(Integer.valueOf(-1), numRangeFilter.getMin());
|
|
||||||
assertEquals(Integer.valueOf(10), numRangeFilter.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter.getField());
|
|
||||||
assertTrue(numRangeFilter.includesMin());
|
|
||||||
assertTrue(numRangeFilter.includesMax());
|
|
||||||
|
|
||||||
String xml2 = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10' includeUpper='false'/>";
|
NumericRangeFilter<Integer> numRangeFilter = (NumericRangeFilter<Integer>) filter;
|
||||||
Document doc2 = getDocumentFromString(xml2);
|
assertEquals(Integer.valueOf(-1), numRangeFilter.getMin());
|
||||||
Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement());
|
assertEquals(Integer.valueOf(10), numRangeFilter.getMax());
|
||||||
assertTrue(filter2 instanceof NumericRangeFilter<?>);
|
assertEquals("AGE", numRangeFilter.getField());
|
||||||
@SuppressWarnings("unchecked")
|
assertTrue(numRangeFilter.includesMin());
|
||||||
NumericRangeFilter<Integer> numRangeFilter2 = (NumericRangeFilter) filter2;
|
assertTrue(numRangeFilter.includesMax());
|
||||||
assertEquals(Integer.valueOf(-1), numRangeFilter2.getMin());
|
|
||||||
assertEquals(Integer.valueOf(10), numRangeFilter2.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter2.getField());
|
|
||||||
assertTrue(numRangeFilter2.includesMin());
|
|
||||||
assertFalse(numRangeFilter2.includesMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetFilterLong() throws Exception {
|
String xml2 = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10' includeUpper='false'/>";
|
||||||
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
Document doc2 = getDocumentFromString(xml2);
|
||||||
filterBuilder.setStrictMode(true);
|
Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement());
|
||||||
|
assertTrue(filter2 instanceof NumericRangeFilter<?>);
|
||||||
|
|
||||||
String xml = "<NumericRangeFilter fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000'/>";
|
NumericRangeFilter<Integer> numRangeFilter2 = (NumericRangeFilter) filter2;
|
||||||
Document doc = getDocumentFromString(xml);
|
assertEquals(Integer.valueOf(-1), numRangeFilter2.getMin());
|
||||||
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
assertEquals(Integer.valueOf(10), numRangeFilter2.getMax());
|
||||||
assertTrue(filter instanceof NumericRangeFilter<?>);
|
assertEquals("AGE", numRangeFilter2.getField());
|
||||||
@SuppressWarnings("unchecked")
|
assertTrue(numRangeFilter2.includesMin());
|
||||||
NumericRangeFilter<Long> numRangeFilter = (NumericRangeFilter) filter;
|
assertFalse(numRangeFilter2.includesMax());
|
||||||
assertEquals(Long.valueOf(-2321L), numRangeFilter.getMin());
|
}
|
||||||
assertEquals(Long.valueOf(60000000L), numRangeFilter.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter.getField());
|
|
||||||
assertTrue(numRangeFilter.includesMin());
|
|
||||||
assertTrue(numRangeFilter.includesMax());
|
|
||||||
|
|
||||||
String xml2 = "<NumericRangeFilter fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000' includeUpper='false'/>";
|
@SuppressWarnings("unchecked")
|
||||||
Document doc2 = getDocumentFromString(xml2);
|
public void testGetFilterLong() throws Exception {
|
||||||
Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement());
|
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
||||||
assertTrue(filter2 instanceof NumericRangeFilter<?>);
|
filterBuilder.setStrictMode(true);
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
NumericRangeFilter<Long> numRangeFilter2 = (NumericRangeFilter) filter2;
|
|
||||||
assertEquals(Long.valueOf(-2321L), numRangeFilter2.getMin());
|
|
||||||
assertEquals(Long.valueOf(60000000L), numRangeFilter2.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter2.getField());
|
|
||||||
assertTrue(numRangeFilter2.includesMin());
|
|
||||||
assertFalse(numRangeFilter2.includesMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetFilterDouble() throws Exception {
|
String xml = "<NumericRangeFilter fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000'/>";
|
||||||
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
Document doc = getDocumentFromString(xml);
|
||||||
filterBuilder.setStrictMode(true);
|
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
||||||
|
assertTrue(filter instanceof NumericRangeFilter<?>);
|
||||||
|
|
||||||
String xml = "<NumericRangeFilter fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023'/>";
|
NumericRangeFilter<Long> numRangeFilter = (NumericRangeFilter) filter;
|
||||||
Document doc = getDocumentFromString(xml);
|
assertEquals(Long.valueOf(-2321L), numRangeFilter.getMin());
|
||||||
|
assertEquals(Long.valueOf(60000000L), numRangeFilter.getMax());
|
||||||
|
assertEquals("AGE", numRangeFilter.getField());
|
||||||
|
assertTrue(numRangeFilter.includesMin());
|
||||||
|
assertTrue(numRangeFilter.includesMax());
|
||||||
|
|
||||||
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
String xml2 = "<NumericRangeFilter fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000' includeUpper='false'/>";
|
||||||
assertTrue(filter instanceof NumericRangeFilter<?>);
|
Document doc2 = getDocumentFromString(xml2);
|
||||||
@SuppressWarnings("unchecked")
|
Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement());
|
||||||
NumericRangeFilter<Double> numRangeFilter = (NumericRangeFilter) filter;
|
assertTrue(filter2 instanceof NumericRangeFilter<?>);
|
||||||
assertEquals(Double.valueOf(-23.21d), numRangeFilter.getMin());
|
NumericRangeFilter<Long> numRangeFilter2 = (NumericRangeFilter) filter2;
|
||||||
assertEquals(Double.valueOf(60000.00023d), numRangeFilter.getMax());
|
assertEquals(Long.valueOf(-2321L), numRangeFilter2.getMin());
|
||||||
assertEquals("AGE", numRangeFilter.getField());
|
assertEquals(Long.valueOf(60000000L), numRangeFilter2.getMax());
|
||||||
assertTrue(numRangeFilter.includesMin());
|
assertEquals("AGE", numRangeFilter2.getField());
|
||||||
assertTrue(numRangeFilter.includesMax());
|
assertTrue(numRangeFilter2.includesMin());
|
||||||
|
assertFalse(numRangeFilter2.includesMax());
|
||||||
|
}
|
||||||
|
|
||||||
String xml2 = "<NumericRangeFilter fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023' includeUpper='false'/>";
|
@SuppressWarnings("unchecked")
|
||||||
Document doc2 = getDocumentFromString(xml2);
|
public void testGetFilterDouble() throws Exception {
|
||||||
Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement());
|
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
||||||
assertTrue(filter2 instanceof NumericRangeFilter<?>);
|
filterBuilder.setStrictMode(true);
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
NumericRangeFilter<Double> numRangeFilter2 = (NumericRangeFilter) filter2;
|
|
||||||
assertEquals(Double.valueOf(-23.21d), numRangeFilter2.getMin());
|
|
||||||
assertEquals(Double.valueOf(60000.00023d), numRangeFilter2.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter2.getField());
|
|
||||||
assertTrue(numRangeFilter2.includesMin());
|
|
||||||
assertFalse(numRangeFilter2.includesMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetFilterFloat() throws Exception {
|
String xml = "<NumericRangeFilter fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023'/>";
|
||||||
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
Document doc = getDocumentFromString(xml);
|
||||||
filterBuilder.setStrictMode(true);
|
|
||||||
|
|
||||||
String xml = "<NumericRangeFilter fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23'/>";
|
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
||||||
Document doc = getDocumentFromString(xml);
|
assertTrue(filter instanceof NumericRangeFilter<?>);
|
||||||
|
|
||||||
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
NumericRangeFilter<Double> numRangeFilter = (NumericRangeFilter) filter;
|
||||||
assertTrue(filter instanceof NumericRangeFilter<?>);
|
assertEquals(Double.valueOf(-23.21d), numRangeFilter.getMin());
|
||||||
@SuppressWarnings("unchecked")
|
assertEquals(Double.valueOf(60000.00023d), numRangeFilter.getMax());
|
||||||
NumericRangeFilter<Float> numRangeFilter = (NumericRangeFilter) filter;
|
assertEquals("AGE", numRangeFilter.getField());
|
||||||
assertEquals(Float.valueOf(-2.321432f), numRangeFilter.getMin());
|
assertTrue(numRangeFilter.includesMin());
|
||||||
assertEquals(Float.valueOf(32432.23f), numRangeFilter.getMax());
|
assertTrue(numRangeFilter.includesMax());
|
||||||
assertEquals("AGE", numRangeFilter.getField());
|
|
||||||
assertTrue(numRangeFilter.includesMin());
|
|
||||||
assertTrue(numRangeFilter.includesMax());
|
|
||||||
|
|
||||||
String xml2 = "<NumericRangeFilter fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23' includeUpper='false' precisionStep='2' />";
|
String xml2 = "<NumericRangeFilter fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023' includeUpper='false'/>";
|
||||||
Document doc2 = getDocumentFromString(xml2);
|
Document doc2 = getDocumentFromString(xml2);
|
||||||
|
Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement());
|
||||||
|
assertTrue(filter2 instanceof NumericRangeFilter<?>);
|
||||||
|
|
||||||
Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement());
|
NumericRangeFilter<Double> numRangeFilter2 = (NumericRangeFilter) filter2;
|
||||||
assertTrue(filter2 instanceof NumericRangeFilter<?>);
|
assertEquals(Double.valueOf(-23.21d), numRangeFilter2.getMin());
|
||||||
@SuppressWarnings("unchecked")
|
assertEquals(Double.valueOf(60000.00023d), numRangeFilter2.getMax());
|
||||||
NumericRangeFilter<Float> numRangeFilter2 = (NumericRangeFilter) filter2;
|
assertEquals("AGE", numRangeFilter2.getField());
|
||||||
assertEquals(Float.valueOf(-2.321432f), numRangeFilter2.getMin());
|
assertTrue(numRangeFilter2.includesMin());
|
||||||
assertEquals(Float.valueOf(32432.23f), numRangeFilter2.getMax());
|
assertFalse(numRangeFilter2.includesMax());
|
||||||
assertEquals("AGE", numRangeFilter2.getField());
|
}
|
||||||
assertTrue(numRangeFilter2.includesMin());
|
|
||||||
assertFalse(numRangeFilter2.includesMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Document getDocumentFromString(String str)
|
@SuppressWarnings("unchecked")
|
||||||
throws SAXException, IOException, ParserConfigurationException {
|
public void testGetFilterFloat() throws Exception {
|
||||||
InputStream is = new ByteArrayInputStream(str.getBytes());
|
NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
filterBuilder.setStrictMode(true);
|
||||||
factory.setNamespaceAware(true);
|
|
||||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
String xml = "<NumericRangeFilter fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23'/>";
|
||||||
Document doc = builder.parse(is);
|
Document doc = getDocumentFromString(xml);
|
||||||
is.close();
|
|
||||||
return doc;
|
Filter filter = filterBuilder.getFilter(doc.getDocumentElement());
|
||||||
}
|
assertTrue(filter instanceof NumericRangeFilter<?>);
|
||||||
|
|
||||||
|
NumericRangeFilter<Float> numRangeFilter = (NumericRangeFilter) filter;
|
||||||
|
assertEquals(Float.valueOf(-2.321432f), numRangeFilter.getMin());
|
||||||
|
assertEquals(Float.valueOf(32432.23f), numRangeFilter.getMax());
|
||||||
|
assertEquals("AGE", numRangeFilter.getField());
|
||||||
|
assertTrue(numRangeFilter.includesMin());
|
||||||
|
assertTrue(numRangeFilter.includesMax());
|
||||||
|
|
||||||
|
String xml2 = "<NumericRangeFilter fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23' includeUpper='false' precisionStep='2' />";
|
||||||
|
Document doc2 = getDocumentFromString(xml2);
|
||||||
|
|
||||||
|
Filter filter2 = filterBuilder.getFilter(doc2.getDocumentElement());
|
||||||
|
assertTrue(filter2 instanceof NumericRangeFilter<?>);
|
||||||
|
|
||||||
|
NumericRangeFilter<Float> numRangeFilter2 = (NumericRangeFilter) filter2;
|
||||||
|
assertEquals(Float.valueOf(-2.321432f), numRangeFilter2.getMin());
|
||||||
|
assertEquals(Float.valueOf(32432.23f), numRangeFilter2.getMax());
|
||||||
|
assertEquals("AGE", numRangeFilter2.getField());
|
||||||
|
assertTrue(numRangeFilter2.includesMin());
|
||||||
|
assertFalse(numRangeFilter2.includesMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Document getDocumentFromString(String str)
|
||||||
|
throws SAXException, IOException, ParserConfigurationException {
|
||||||
|
InputStream is = new ByteArrayInputStream(str.getBytes());
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
factory.setNamespaceAware(true);
|
||||||
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
Document doc = builder.parse(is);
|
||||||
|
is.close();
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,161 +17,162 @@ package org.apache.lucene.xmlparser.builders;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
|
||||||
import org.apache.lucene.util.LuceneTestCase;
|
|
||||||
|
|
||||||
import org.apache.lucene.search.NumericRangeQuery;
|
import org.apache.lucene.search.NumericRangeQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
import org.apache.lucene.xmlparser.ParserException;
|
import org.apache.lucene.xmlparser.ParserException;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class TestNumericRangeQueryBuilder extends LuceneTestCase {
|
public class TestNumericRangeQueryBuilder extends LuceneTestCase {
|
||||||
|
|
||||||
public void testGetFilterHandleNumericParseErrorStrict() throws Exception {
|
public void testGetFilterHandleNumericParseErrorStrict() throws Exception {
|
||||||
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
||||||
|
|
||||||
String xml = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
|
String xml = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
|
||||||
Document doc = getDocumentFromString(xml);
|
Document doc = getDocumentFromString(xml);
|
||||||
try {
|
try {
|
||||||
filterBuilder.getQuery(doc.getDocumentElement());
|
filterBuilder.getQuery(doc.getDocumentElement());
|
||||||
} catch (ParserException e) {
|
} catch (ParserException e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fail("Expected to throw " + ParserException.class);
|
fail("Expected to throw " + ParserException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetFilterInt() throws Exception {
|
@SuppressWarnings("unchecked")
|
||||||
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
public void testGetFilterInt() throws Exception {
|
||||||
|
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
||||||
|
|
||||||
String xml = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10'/>";
|
String xml = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10'/>";
|
||||||
Document doc = getDocumentFromString(xml);
|
Document doc = getDocumentFromString(xml);
|
||||||
Query filter = filterBuilder.getQuery(doc.getDocumentElement());
|
Query filter = filterBuilder.getQuery(doc.getDocumentElement());
|
||||||
assertTrue(filter instanceof NumericRangeQuery<?>);
|
assertTrue(filter instanceof NumericRangeQuery<?>);
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
NumericRangeQuery<Integer> numRangeFilter = (NumericRangeQuery<Integer>) filter;
|
|
||||||
assertEquals(Integer.valueOf(-1), numRangeFilter.getMin());
|
|
||||||
assertEquals(Integer.valueOf(10), numRangeFilter.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter.getField());
|
|
||||||
assertTrue(numRangeFilter.includesMin());
|
|
||||||
assertTrue(numRangeFilter.includesMax());
|
|
||||||
|
|
||||||
String xml2 = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10' includeUpper='false'/>";
|
NumericRangeQuery<Integer> numRangeFilter = (NumericRangeQuery<Integer>) filter;
|
||||||
Document doc2 = getDocumentFromString(xml2);
|
assertEquals(Integer.valueOf(-1), numRangeFilter.getMin());
|
||||||
Query filter2 = filterBuilder.getQuery(doc2.getDocumentElement());
|
assertEquals(Integer.valueOf(10), numRangeFilter.getMax());
|
||||||
assertTrue(filter2 instanceof NumericRangeQuery<?>);
|
assertEquals("AGE", numRangeFilter.getField());
|
||||||
@SuppressWarnings("unchecked")
|
assertTrue(numRangeFilter.includesMin());
|
||||||
NumericRangeQuery<Integer> numRangeFilter2 = (NumericRangeQuery) filter2;
|
assertTrue(numRangeFilter.includesMax());
|
||||||
assertEquals(Integer.valueOf(-1), numRangeFilter2.getMin());
|
|
||||||
assertEquals(Integer.valueOf(10), numRangeFilter2.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter2.getField());
|
|
||||||
assertTrue(numRangeFilter2.includesMin());
|
|
||||||
assertFalse(numRangeFilter2.includesMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetFilterLong() throws Exception {
|
String xml2 = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10' includeUpper='false'/>";
|
||||||
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
Document doc2 = getDocumentFromString(xml2);
|
||||||
|
Query filter2 = filterBuilder.getQuery(doc2.getDocumentElement());
|
||||||
|
assertTrue(filter2 instanceof NumericRangeQuery<?>);
|
||||||
|
|
||||||
String xml = "<NumericRangeQuery fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000'/>";
|
NumericRangeQuery<Integer> numRangeFilter2 = (NumericRangeQuery) filter2;
|
||||||
Document doc = getDocumentFromString(xml);
|
assertEquals(Integer.valueOf(-1), numRangeFilter2.getMin());
|
||||||
Query filter = filterBuilder.getQuery(doc.getDocumentElement());
|
assertEquals(Integer.valueOf(10), numRangeFilter2.getMax());
|
||||||
assertTrue(filter instanceof NumericRangeQuery<?>);
|
assertEquals("AGE", numRangeFilter2.getField());
|
||||||
@SuppressWarnings("unchecked")
|
assertTrue(numRangeFilter2.includesMin());
|
||||||
NumericRangeQuery<Long> numRangeFilter = (NumericRangeQuery) filter;
|
assertFalse(numRangeFilter2.includesMax());
|
||||||
assertEquals(Long.valueOf(-2321L), numRangeFilter.getMin());
|
}
|
||||||
assertEquals(Long.valueOf(60000000L), numRangeFilter.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter.getField());
|
|
||||||
assertTrue(numRangeFilter.includesMin());
|
|
||||||
assertTrue(numRangeFilter.includesMax());
|
|
||||||
|
|
||||||
String xml2 = "<NumericRangeQuery fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000' includeUpper='false'/>";
|
@SuppressWarnings("unchecked")
|
||||||
Document doc2 = getDocumentFromString(xml2);
|
public void testGetFilterLong() throws Exception {
|
||||||
Query filter2 = filterBuilder.getQuery(doc2.getDocumentElement());
|
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
||||||
assertTrue(filter2 instanceof NumericRangeQuery<?>);
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
NumericRangeQuery<Long> numRangeFilter2 = (NumericRangeQuery) filter2;
|
|
||||||
assertEquals(Long.valueOf(-2321L), numRangeFilter2.getMin());
|
|
||||||
assertEquals(Long.valueOf(60000000L), numRangeFilter2.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter2.getField());
|
|
||||||
assertTrue(numRangeFilter2.includesMin());
|
|
||||||
assertFalse(numRangeFilter2.includesMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetFilterDouble() throws Exception {
|
String xml = "<NumericRangeQuery fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000'/>";
|
||||||
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
Document doc = getDocumentFromString(xml);
|
||||||
|
Query filter = filterBuilder.getQuery(doc.getDocumentElement());
|
||||||
|
assertTrue(filter instanceof NumericRangeQuery<?>);
|
||||||
|
NumericRangeQuery<Long> numRangeFilter = (NumericRangeQuery) filter;
|
||||||
|
assertEquals(Long.valueOf(-2321L), numRangeFilter.getMin());
|
||||||
|
assertEquals(Long.valueOf(60000000L), numRangeFilter.getMax());
|
||||||
|
assertEquals("AGE", numRangeFilter.getField());
|
||||||
|
assertTrue(numRangeFilter.includesMin());
|
||||||
|
assertTrue(numRangeFilter.includesMax());
|
||||||
|
|
||||||
String xml = "<NumericRangeQuery fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023'/>";
|
String xml2 = "<NumericRangeQuery fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000' includeUpper='false'/>";
|
||||||
Document doc = getDocumentFromString(xml);
|
Document doc2 = getDocumentFromString(xml2);
|
||||||
|
Query filter2 = filterBuilder.getQuery(doc2.getDocumentElement());
|
||||||
|
assertTrue(filter2 instanceof NumericRangeQuery<?>);
|
||||||
|
|
||||||
Query filter = filterBuilder.getQuery(doc.getDocumentElement());
|
NumericRangeQuery<Long> numRangeFilter2 = (NumericRangeQuery) filter2;
|
||||||
assertTrue(filter instanceof NumericRangeQuery<?>);
|
assertEquals(Long.valueOf(-2321L), numRangeFilter2.getMin());
|
||||||
@SuppressWarnings("unchecked")
|
assertEquals(Long.valueOf(60000000L), numRangeFilter2.getMax());
|
||||||
NumericRangeQuery<Double> numRangeFilter = (NumericRangeQuery) filter;
|
assertEquals("AGE", numRangeFilter2.getField());
|
||||||
assertEquals(Double.valueOf(-23.21d), numRangeFilter.getMin());
|
assertTrue(numRangeFilter2.includesMin());
|
||||||
assertEquals(Double.valueOf(60000.00023d), numRangeFilter.getMax());
|
assertFalse(numRangeFilter2.includesMax());
|
||||||
assertEquals("AGE", numRangeFilter.getField());
|
}
|
||||||
assertTrue(numRangeFilter.includesMin());
|
|
||||||
assertTrue(numRangeFilter.includesMax());
|
|
||||||
|
|
||||||
String xml2 = "<NumericRangeQuery fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023' includeUpper='false'/>";
|
@SuppressWarnings("unchecked")
|
||||||
Document doc2 = getDocumentFromString(xml2);
|
public void testGetFilterDouble() throws Exception {
|
||||||
Query filter2 = filterBuilder.getQuery(doc2.getDocumentElement());
|
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
||||||
assertTrue(filter2 instanceof NumericRangeQuery<?>);
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
NumericRangeQuery<Double> numRangeFilter2 = (NumericRangeQuery) filter2;
|
|
||||||
assertEquals(Double.valueOf(-23.21d), numRangeFilter2.getMin());
|
|
||||||
assertEquals(Double.valueOf(60000.00023d), numRangeFilter2.getMax());
|
|
||||||
assertEquals("AGE", numRangeFilter2.getField());
|
|
||||||
assertTrue(numRangeFilter2.includesMin());
|
|
||||||
assertFalse(numRangeFilter2.includesMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetFilterFloat() throws Exception {
|
String xml = "<NumericRangeQuery fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023'/>";
|
||||||
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
Document doc = getDocumentFromString(xml);
|
||||||
|
|
||||||
String xml = "<NumericRangeQuery fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23'/>";
|
Query filter = filterBuilder.getQuery(doc.getDocumentElement());
|
||||||
Document doc = getDocumentFromString(xml);
|
assertTrue(filter instanceof NumericRangeQuery<?>);
|
||||||
|
|
||||||
Query filter = filterBuilder.getQuery(doc.getDocumentElement());
|
NumericRangeQuery<Double> numRangeFilter = (NumericRangeQuery) filter;
|
||||||
assertTrue(filter instanceof NumericRangeQuery<?>);
|
assertEquals(Double.valueOf(-23.21d), numRangeFilter.getMin());
|
||||||
@SuppressWarnings("unchecked")
|
assertEquals(Double.valueOf(60000.00023d), numRangeFilter.getMax());
|
||||||
NumericRangeQuery<Float> numRangeFilter = (NumericRangeQuery) filter;
|
assertEquals("AGE", numRangeFilter.getField());
|
||||||
assertEquals(Float.valueOf(-2.321432f), numRangeFilter.getMin());
|
assertTrue(numRangeFilter.includesMin());
|
||||||
assertEquals(Float.valueOf(32432.23f), numRangeFilter.getMax());
|
assertTrue(numRangeFilter.includesMax());
|
||||||
assertEquals("AGE", numRangeFilter.getField());
|
|
||||||
assertTrue(numRangeFilter.includesMin());
|
|
||||||
assertTrue(numRangeFilter.includesMax());
|
|
||||||
|
|
||||||
String xml2 = "<NumericRangeQuery fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23' includeUpper='false' precisionStep='2' />";
|
String xml2 = "<NumericRangeQuery fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023' includeUpper='false'/>";
|
||||||
Document doc2 = getDocumentFromString(xml2);
|
Document doc2 = getDocumentFromString(xml2);
|
||||||
|
Query filter2 = filterBuilder.getQuery(doc2.getDocumentElement());
|
||||||
|
assertTrue(filter2 instanceof NumericRangeQuery<?>);
|
||||||
|
|
||||||
Query filter2 = filterBuilder.getQuery(doc2.getDocumentElement());
|
NumericRangeQuery<Double> numRangeFilter2 = (NumericRangeQuery) filter2;
|
||||||
assertTrue(filter2 instanceof NumericRangeQuery<?>);
|
assertEquals(Double.valueOf(-23.21d), numRangeFilter2.getMin());
|
||||||
@SuppressWarnings("unchecked")
|
assertEquals(Double.valueOf(60000.00023d), numRangeFilter2.getMax());
|
||||||
NumericRangeQuery<Float> numRangeFilter2 = (NumericRangeQuery) filter2;
|
assertEquals("AGE", numRangeFilter2.getField());
|
||||||
assertEquals(Float.valueOf(-2.321432f), numRangeFilter2.getMin());
|
assertTrue(numRangeFilter2.includesMin());
|
||||||
assertEquals(Float.valueOf(32432.23f), numRangeFilter2.getMax());
|
assertFalse(numRangeFilter2.includesMax());
|
||||||
assertEquals("AGE", numRangeFilter2.getField());
|
}
|
||||||
assertTrue(numRangeFilter2.includesMin());
|
|
||||||
assertFalse(numRangeFilter2.includesMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Document getDocumentFromString(String str)
|
@SuppressWarnings("unchecked")
|
||||||
throws SAXException, IOException, ParserConfigurationException {
|
public void testGetFilterFloat() throws Exception {
|
||||||
InputStream is = new ByteArrayInputStream(str.getBytes());
|
NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
||||||
factory.setNamespaceAware(true);
|
String xml = "<NumericRangeQuery fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23'/>";
|
||||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
Document doc = getDocumentFromString(xml);
|
||||||
Document doc = builder.parse(is);
|
|
||||||
is.close();
|
Query filter = filterBuilder.getQuery(doc.getDocumentElement());
|
||||||
return doc;
|
assertTrue(filter instanceof NumericRangeQuery<?>);
|
||||||
}
|
|
||||||
|
NumericRangeQuery<Float> numRangeFilter = (NumericRangeQuery) filter;
|
||||||
|
assertEquals(Float.valueOf(-2.321432f), numRangeFilter.getMin());
|
||||||
|
assertEquals(Float.valueOf(32432.23f), numRangeFilter.getMax());
|
||||||
|
assertEquals("AGE", numRangeFilter.getField());
|
||||||
|
assertTrue(numRangeFilter.includesMin());
|
||||||
|
assertTrue(numRangeFilter.includesMax());
|
||||||
|
|
||||||
|
String xml2 = "<NumericRangeQuery fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23' includeUpper='false' precisionStep='2' />";
|
||||||
|
Document doc2 = getDocumentFromString(xml2);
|
||||||
|
|
||||||
|
Query filter2 = filterBuilder.getQuery(doc2.getDocumentElement());
|
||||||
|
assertTrue(filter2 instanceof NumericRangeQuery<?>);
|
||||||
|
|
||||||
|
NumericRangeQuery<Float> numRangeFilter2 = (NumericRangeQuery) filter2;
|
||||||
|
assertEquals(Float.valueOf(-2.321432f), numRangeFilter2.getMin());
|
||||||
|
assertEquals(Float.valueOf(32432.23f), numRangeFilter2.getMax());
|
||||||
|
assertEquals("AGE", numRangeFilter2.getField());
|
||||||
|
assertTrue(numRangeFilter2.includesMin());
|
||||||
|
assertFalse(numRangeFilter2.includesMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Document getDocumentFromString(String str)
|
||||||
|
throws SAXException, IOException, ParserConfigurationException {
|
||||||
|
InputStream is = new ByteArrayInputStream(str.getBytes());
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
factory.setNamespaceAware(true);
|
||||||
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
Document doc = builder.parse(is);
|
||||||
|
is.close();
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue