You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2016/12/07 13:48:25 UTC
[07/11] lucenenet git commit: Ported QueryParser.Xml + tests
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/Builders/TermsQueryBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/Builders/TermsQueryBuilder.cs b/src/Lucene.Net.QueryParser/Xml/Builders/TermsQueryBuilder.cs
new file mode 100644
index 0000000..521b21a
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/Builders/TermsQueryBuilder.cs
@@ -0,0 +1,77 @@
+\ufeffusing Lucene.Net.Analysis;
+using Lucene.Net.Analysis.Tokenattributes;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Util;
+using System;
+using System.IO;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml.Builders
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Builds a <see cref="BooleanQuery"/> from all of the terms found in the XML element using the choice of analyzer
+ /// </summary>
+ public class TermsQueryBuilder : IQueryBuilder
+ {
+ private readonly Analyzer analyzer;
+
+ public TermsQueryBuilder(Analyzer analyzer)
+ {
+ this.analyzer = analyzer;
+ }
+
+ public virtual Query GetQuery(XmlElement e)
+ {
+ string fieldName = DOMUtils.GetAttributeWithInheritanceOrFail(e, "fieldName");
+ string text = DOMUtils.GetNonBlankTextOrFail(e);
+
+ BooleanQuery bq = new BooleanQuery(DOMUtils.GetAttribute(e, "disableCoord", false));
+ bq.MinimumNumberShouldMatch = DOMUtils.GetAttribute(e, "minimumNumberShouldMatch", 0);
+ TokenStream ts = null;
+ try
+ {
+ ts = analyzer.TokenStream(fieldName, text);
+ ITermToBytesRefAttribute termAtt = ts.AddAttribute<ITermToBytesRefAttribute>();
+ Term term = null;
+ BytesRef bytes = termAtt.BytesRef;
+ ts.Reset();
+ while (ts.IncrementToken())
+ {
+ termAtt.FillBytesRef();
+ term = new Term(fieldName, BytesRef.DeepCopyOf(bytes));
+ bq.Add(new BooleanClause(new TermQuery(term), BooleanClause.Occur.SHOULD));
+ }
+ ts.End();
+ }
+ catch (IOException ioe)
+ {
+ throw new Exception("Error constructing terms from index:" + ioe);
+ }
+ finally
+ {
+ IOUtils.CloseWhileHandlingException(ts);
+ }
+
+ bq.Boost = DOMUtils.GetAttribute(e, "boost", 1.0f);
+ return bq;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/Builders/UserInputQueryBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/Builders/UserInputQueryBuilder.cs b/src/Lucene.Net.QueryParser/Xml/Builders/UserInputQueryBuilder.cs
new file mode 100644
index 0000000..40d34e7
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/Builders/UserInputQueryBuilder.cs
@@ -0,0 +1,100 @@
+\ufeffusing Lucene.Net.Analysis;
+using Lucene.Net.QueryParsers.Classic;
+using Lucene.Net.Search;
+using Lucene.Net.Util;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml.Builders
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// <see cref="UserInputQueryBuilder"/> uses 1 of 2 strategies for thread-safe parsing:
+ /// 1) Synchronizing access to "Parse" calls on a previously supplied <see cref="QueryParser"/>
+ /// or..
+ /// 2) creating a new <see cref="QueryParser"/> object for each parse request
+ /// </summary>
+ public class UserInputQueryBuilder : IQueryBuilder
+ {
+ private QueryParser unSafeParser;
+ private Analyzer analyzer;
+ private string defaultField;
+
+ /// <summary>
+ /// This constructor has the disadvantage of not being able to change choice of default field name
+ /// </summary>
+ /// <param name="parser">thread un-safe query parser</param>
+ public UserInputQueryBuilder(QueryParser parser)
+ {
+ this.unSafeParser = parser;
+ }
+
+ public UserInputQueryBuilder(string defaultField, Analyzer analyzer)
+ {
+ this.analyzer = analyzer;
+ this.defaultField = defaultField;
+ }
+
+ /// <summary>
+ /// (non-Javadoc)
+ /// @see org.apache.lucene.xmlparser.QueryObjectBuilder#process(org.w3c.dom.Element)
+ /// </summary>
+ /// <param name="e"></param>
+ /// <returns></returns>
+ public virtual Query GetQuery(XmlElement e)
+ {
+ string text = DOMUtils.GetText(e);
+ try
+ {
+ Query q = null;
+ if (unSafeParser != null)
+ {
+ //synchronize on unsafe parser
+ lock (unSafeParser)
+ {
+ q = unSafeParser.Parse(text);
+ }
+ }
+ else
+ {
+ string fieldName = DOMUtils.GetAttribute(e, "fieldName", defaultField);
+ //Create new parser
+ QueryParser parser = CreateQueryParser(fieldName, analyzer);
+ q = parser.Parse(text);
+ }
+ q.Boost = DOMUtils.GetAttribute(e, "boost", 1.0f);
+ return q;
+ }
+ catch (ParseException e1)
+ {
+ throw new ParserException(e1.Message);
+ }
+ }
+
+ /// <summary>
+ /// Method to create a <see cref="QueryParser"/> - designed to be overridden
+ /// </summary>
+ /// <returns><see cref="QueryParser"/></returns>
+ protected virtual QueryParser CreateQueryParser(string fieldName, Analyzer analyzer)
+ {
+#pragma warning disable 612, 618
+ return new QueryParser(LuceneVersion.LUCENE_CURRENT, fieldName, analyzer);
+#pragma warning restore 612, 618
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/CoreParser.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/CoreParser.cs b/src/Lucene.Net.QueryParser/Xml/CoreParser.cs
new file mode 100644
index 0000000..30f0ff8
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/CoreParser.cs
@@ -0,0 +1,185 @@
+\ufeffusing Lucene.Net.Analysis;
+using Lucene.Net.QueryParsers.Classic;
+using Lucene.Net.QueryParsers.Xml.Builders;
+using Lucene.Net.Search;
+using System;
+using System.IO;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Assembles a <see cref="IQueryBuilder"/> which uses only core Lucene Query objects
+ /// </summary>
+ public class CoreParser : IQueryBuilder
+ {
+ protected Analyzer analyzer;
+ protected QueryParser parser;
+ protected QueryBuilderFactory queryFactory;
+ protected FilterBuilderFactory filterFactory;
+ //Controls the max size of the LRU cache used for QueryFilter objects parsed.
+ public static int maxNumCachedFilters = 20;
+
+ /// <summary>
+ /// Construct an XML parser that uses a single instance <see cref="QueryParser"/> for handling
+ /// UserQuery tags - all parse operations are synchronised on this parser
+ /// </summary>
+ /// <param name="analyzer"></param>
+ /// <param name="parser">A <see cref="QueryParser"/> which will be synchronized on during parse calls.</param>
+ public CoreParser(Analyzer analyzer, QueryParser parser)
+ : this(null, analyzer, parser)
+ {
+ }
+
+ /// <summary>
+ /// Constructs an XML parser that creates a <see cref="QueryParser"/> for each UserQuery request.
+ /// </summary>
+ /// <param name="defaultField">The default field name used by <see cref="QueryParser"/>s constructed for UserQuery tags</param>
+ /// <param name="analyzer"></param>
+ 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());
+ queryFactory.AddBuilder("DisjunctionMaxQuery", new DisjunctionMaxQueryBuilder(queryFactory));
+ 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);
+ 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(Stream xmlStream)
+ {
+ return GetQuery(ParseXML(xmlStream).DocumentElement);
+ }
+
+ public void AddQueryBuilder(string nodeName, IQueryBuilder builder)
+ {
+ queryFactory.AddBuilder(nodeName, builder);
+ }
+
+ public void AddFilterBuilder(string nodeName, IFilterBuilder builder)
+ {
+ filterFactory.AddBuilder(nodeName, builder);
+ }
+
+ private static XmlDocument ParseXML(Stream pXmlFile)
+ {
+ XmlDocument doc = new XmlDocument();
+ try
+ {
+ doc.Load(pXmlFile);
+ }
+ catch (Exception se)
+ {
+ throw new ParserException("Error parsing XML stream:" + se, se);
+ }
+ return doc;
+ }
+
+ // LUCENENET specific overload for TextReader
+ private static XmlDocument ParseXML(TextReader pXmlFile)
+ {
+ XmlDocument doc = new XmlDocument();
+ try
+ {
+ doc.Load(pXmlFile);
+ }
+ catch (Exception se)
+ {
+ throw new ParserException("Error parsing XML stream:" + se, se);
+ }
+ return doc;
+ }
+
+ // LUCENENET specific overload for XmlReader
+ private static XmlDocument ParseXML(XmlReader pXmlFile)
+ {
+ XmlDocument doc = new XmlDocument();
+ try
+ {
+ doc.Load(pXmlFile);
+ }
+ catch (Exception se)
+ {
+ throw new ParserException("Error parsing XML stream:" + se, se);
+ }
+ return doc;
+ }
+
+ public virtual Query GetQuery(XmlElement e)
+ {
+ return queryFactory.GetQuery(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/CorePlusExtensionsParser.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/CorePlusExtensionsParser.cs b/src/Lucene.Net.QueryParser/Xml/CorePlusExtensionsParser.cs
new file mode 100644
index 0000000..4c6b77f
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/CorePlusExtensionsParser.cs
@@ -0,0 +1,64 @@
+\ufeffusing Lucene.Net.Analysis;
+using Lucene.Net.QueryParsers.Classic;
+using Lucene.Net.QueryParsers.Xml.Builders;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Assembles a <see cref="QueryBuilder"/> which uses <see cref="Query"/> objects from
+ /// Lucene's <c>sandbox</c> and <c>queries</c>
+ /// modules in addition to core queries.
+ /// </summary>
+ public class CorePlusExtensionsParser : CoreParser
+ {
+ /// <summary>
+ /// Construct an XML parser that uses a single instance <see cref="QueryParser"/> for handling
+ /// UserQuery tags - all parse operations are synchronized on this parser
+ /// </summary>
+ /// <param name="analyzer"></param>
+ /// <param name="parser">A <see cref="QueryParser"/> which will be synchronized on during parse calls.</param>
+ public CorePlusExtensionsParser(Analyzer analyzer, QueryParser parser)
+ : this(null, analyzer, parser)
+ {
+ }
+
+ /// <summary>
+ /// Constructs an XML parser that creates a <see cref="QueryParser"/> for each UserQuery request.
+ /// </summary>
+ /// <param name="defaultField">The default field name used by <see cref="QueryParser"/>s constructed for UserQuery tags</param>
+ /// <param name="analyzer"></param>
+ public CorePlusExtensionsParser(string defaultField, Analyzer analyzer)
+ : this(defaultField, analyzer, null)
+ {
+ }
+
+ private CorePlusExtensionsParser(string defaultField, Analyzer analyzer, QueryParser parser)
+ : base(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));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/DOMUtils.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/DOMUtils.cs b/src/Lucene.Net.QueryParser/Xml/DOMUtils.cs
new file mode 100644
index 0000000..3e3379e
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/DOMUtils.cs
@@ -0,0 +1,276 @@
+\ufeffusing System;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Helper methods for parsing XML
+ /// </summary>
+ public class DOMUtils
+ {
+ public static XmlElement GetChildByTagOrFail(XmlElement e, string name)
+ {
+ XmlElement kid = GetChildByTagName(e, name);
+ if (null == kid)
+ {
+ throw new ParserException(e.ToString() + " missing \"" + name
+ + "\" child element");
+ }
+ return kid;
+ }
+
+ public static XmlElement GetFirstChildOrFail(XmlElement e)
+ {
+ XmlElement kid = GetFirstChildElement(e);
+ if (null == kid)
+ {
+ throw new ParserException(e.ToString()
+ + " does not contain a child element");
+ }
+ return kid;
+ }
+
+ public static string GetAttributeOrFail(XmlElement e, string name)
+ {
+ string v = e.GetAttribute(name);
+ if (null == v)
+ {
+ throw new ParserException(e.ToString() + " missing \"" + name
+ + "\" attribute");
+ }
+ return v;
+ }
+
+ public static string GetAttributeWithInheritanceOrFail(XmlElement e, string name)
+ {
+ string v = GetAttributeWithInheritance(e, name);
+ if (null == v)
+ {
+ throw new ParserException(e.ToString() + " missing \"" + name
+ + "\" attribute");
+ }
+ return v;
+ }
+
+ public static string GetNonBlankTextOrFail(XmlElement e)
+ {
+ string v = GetText(e);
+ if (null != v)
+ v = v.Trim();
+ if (null == v || 0 == v.Length)
+ {
+ throw new ParserException(e.ToString() + " has no text");
+ }
+ return v;
+ }
+
+ /// <summary>Convenience method where there is only one child <see cref="XmlElement"/> of a given name</summary>
+ public static XmlElement GetChildByTagName(XmlElement e, string name)
+ {
+ for (XmlNode kid = e.FirstChild; kid != null; kid = kid.NextSibling)
+ {
+ if ((kid.NodeType == XmlNodeType.Element) && (name.Equals(kid.Name)))
+ {
+ return (XmlElement)kid;
+ }
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// Returns an attribute value from this node, or first parent node with this attribute defined
+ /// </summary>
+ /// <param name="element"></param>
+ /// <param name="attributeName"></param>
+ /// <returns>A non-zero-length value if defined, otherwise null</returns>
+ public static string GetAttributeWithInheritance(XmlElement element, string attributeName)
+ {
+ string result = element.GetAttribute(attributeName);
+ if ((result == null) || ("".Equals(result)))
+ {
+ XmlNode n = element.ParentNode;
+ if ((n == element) || (n == null))
+ {
+ return null;
+ }
+ if (n is XmlElement)
+ {
+ XmlElement parent = (XmlElement)n;
+ return GetAttributeWithInheritance(parent, attributeName);
+ }
+ return null; //we reached the top level of the document without finding attribute
+ }
+ return result;
+ }
+
+
+ /// <summary>Convenience method where there is only one child <see cref="XmlElement"/> of a given name</summary>
+ public static string GetChildTextByTagName(XmlElement e, string tagName)
+ {
+ XmlElement child = GetChildByTagName(e, tagName);
+ return child != null ? GetText(child) : null;
+ }
+
+ /// <summary>Convenience method to append a new child with text</summary>
+ public static XmlElement InsertChild(XmlElement parent, string tagName, string text)
+ {
+ XmlElement child = parent.OwnerDocument.CreateElement(tagName);
+ parent.AppendChild(child);
+ if (text != null)
+ {
+ child.AppendChild(child.OwnerDocument.CreateTextNode(text));
+ }
+ return child;
+ }
+
+ public static string GetAttribute(XmlElement element, string attributeName, string deflt)
+ {
+ string result = element.GetAttribute(attributeName);
+ return (result == null) || ("".Equals(result)) ? deflt : result;
+ }
+
+ public static float GetAttribute(XmlElement element, string attributeName, float deflt)
+ {
+ string result = element.GetAttribute(attributeName);
+ return (result == null) || ("".Equals(result)) ? deflt : Convert.ToSingle(result);
+ }
+
+ public static int GetAttribute(XmlElement element, string attributeName, int deflt)
+ {
+ string result = element.GetAttribute(attributeName);
+ return (result == null) || ("".Equals(result)) ? deflt : Convert.ToInt32(result);
+ }
+
+ public static bool GetAttribute(XmlElement element, string attributeName,
+ bool deflt)
+ {
+ string result = element.GetAttribute(attributeName);
+ return (result == null) || ("".Equals(result)) ? deflt : Convert.ToBoolean(result);
+ }
+
+ /* Returns text of node and all child nodes - without markup */
+ //MH changed to Node from Element 25/11/2005
+
+ public static string GetText(XmlNode e)
+ {
+ StringBuilder sb = new StringBuilder();
+ GetTextBuffer(e, sb);
+ return sb.ToString();
+ }
+
+ public static XmlElement GetFirstChildElement(XmlElement element)
+ {
+ for (XmlNode kid = element.FirstChild; kid != null; kid = kid.NextSibling)
+ {
+ if (kid.NodeType == XmlNodeType.Element)
+ {
+ return (XmlElement)kid;
+ }
+ }
+ return null;
+ }
+
+ private static void GetTextBuffer(XmlNode e, StringBuilder sb)
+ {
+ for (XmlNode kid = e.FirstChild; kid != null; kid = kid.NextSibling)
+ {
+ switch (kid.NodeType)
+ {
+ case XmlNodeType.Text:
+ {
+ sb.Append(kid.Value);
+ break;
+ }
+ case XmlNodeType.Element:
+ {
+ GetTextBuffer(kid, sb);
+ break;
+ }
+ case XmlNodeType.EntityReference:
+ {
+ GetTextBuffer(kid, sb);
+ break;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Helper method to parse an XML file into a DOM tree, given a <see cref="TextReader"/>.
+ /// </summary>
+ /// <param name="input">reader of the XML file to be parsed</param>
+ /// <returns>an <see cref="XmlDocument"/> object</returns>
+ public static XmlDocument LoadXML(TextReader input)
+ {
+ XmlDocument result = new XmlDocument();
+ try
+ {
+ result.Load(input);
+ }
+ catch (Exception se)
+ {
+ throw new Exception("Error parsing file:" + se, se);
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Helper method to parse an XML file into a DOM tree, given a <see cref="Stream"/>.
+ /// </summary>
+ /// <param name="input">reader of the XML file to be parsed</param>
+ /// <returns>an <see cref="XmlDocument"/> object</returns>
+ // LUCENENET specific
+ public static XmlDocument LoadXML(Stream input)
+ {
+ XmlDocument result = new XmlDocument();
+ try
+ {
+ result.Load(input);
+ }
+ catch (Exception se)
+ {
+ throw new Exception("Error parsing file:" + se, se);
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Helper method to parse an XML file into a DOM tree, given an <see cref="XmlReader"/>.
+ /// </summary>
+ /// <param name="input">reader of the XML file to be parsed</param>
+ /// <returns>an <see cref="XmlDocument"/> object</returns>
+ // LUCENENET specific
+ public static XmlDocument LoadXML(XmlReader input)
+ {
+ XmlDocument result = new XmlDocument();
+ try
+ {
+ result.Load(input);
+ }
+ catch (Exception se)
+ {
+ throw new Exception("Error parsing file:" + se, se);
+ }
+ return result;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/FilterBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/FilterBuilder.cs b/src/Lucene.Net.QueryParser/Xml/FilterBuilder.cs
new file mode 100644
index 0000000..772de16
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/FilterBuilder.cs
@@ -0,0 +1,30 @@
+\ufeffusing Lucene.Net.Search;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Interface for building <see cref="Filter"/>s
+ /// </summary>
+ public interface IFilterBuilder
+ {
+ Filter GetFilter(XmlElement e);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/FilterBuilderFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/FilterBuilderFactory.cs b/src/Lucene.Net.QueryParser/Xml/FilterBuilderFactory.cs
new file mode 100644
index 0000000..701638e
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/FilterBuilderFactory.cs
@@ -0,0 +1,53 @@
+\ufeffusing Lucene.Net.Search;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Factory for <see cref="IFilterBuilder"/>
+ /// </summary>
+ public class FilterBuilderFactory : IFilterBuilder
+ {
+ IDictionary<string, IFilterBuilder> builders = new Dictionary<string, IFilterBuilder>();
+
+ public virtual Filter GetFilter(XmlElement n)
+ {
+ IFilterBuilder builder;
+ if (!builders.TryGetValue(n.Name, out builder) || builder == null)
+ {
+ throw new ParserException("No FilterBuilder defined for node " + n.Name);
+ }
+ return builder.GetFilter(n);
+ }
+
+ public void AddBuilder(string nodeName, IFilterBuilder builder)
+ {
+ builders[nodeName] = builder;
+ }
+
+ public IFilterBuilder GetFilterBuilder(string nodeName)
+ {
+ IFilterBuilder result;
+ builders.TryGetValue(nodeName, out result);
+ return result;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/ParserException.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/ParserException.cs b/src/Lucene.Net.QueryParser/Xml/ParserException.cs
new file mode 100644
index 0000000..97be757
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/ParserException.cs
@@ -0,0 +1,49 @@
+\ufeffusing System;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Thrown when the xml queryparser encounters
+ /// invalid syntax/configuration.
+ /// </summary>
+ [Serializable]
+ public class ParserException : Exception
+ {
+ public ParserException()
+ : base()
+ {
+ }
+
+ public ParserException(String message)
+ : base(message)
+ {
+ }
+
+ public ParserException(String message, Exception cause)
+ : base(message, cause)
+ {
+ }
+
+ public ParserException(Exception cause)
+ : base(cause.Message, cause)
+ {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/QueryBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/QueryBuilder.cs b/src/Lucene.Net.QueryParser/Xml/QueryBuilder.cs
new file mode 100644
index 0000000..3c9df84
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/QueryBuilder.cs
@@ -0,0 +1,31 @@
+\ufeffusing Lucene.Net.Search;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Implemented by objects that produce Lucene Query objects from XML streams. Implementations are
+ /// expected to be thread-safe so that they can be used to simultaneously parse multiple XML documents.
+ /// </summary>
+ public interface IQueryBuilder
+ {
+ Query GetQuery(XmlElement e);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/QueryBuilderFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/QueryBuilderFactory.cs b/src/Lucene.Net.QueryParser/Xml/QueryBuilderFactory.cs
new file mode 100644
index 0000000..3b85766
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/QueryBuilderFactory.cs
@@ -0,0 +1,53 @@
+\ufeffusing Lucene.Net.Search;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// Factory for <see cref="IQueryBuilder"/>
+ /// </summary>
+ public class QueryBuilderFactory : IQueryBuilder
+ {
+ IDictionary<string, IQueryBuilder> builders = new Dictionary<string, IQueryBuilder>();
+
+ public virtual Query GetQuery(XmlElement n)
+ {
+ IQueryBuilder builder;
+ if (!builders.TryGetValue(n.Name, out builder) || builder == null)
+ {
+ throw new ParserException("No QueryObjectBuilder defined for node " + n.Name);
+ }
+ return builder.GetQuery(n);
+ }
+
+ public void AddBuilder(string nodeName, IQueryBuilder builder)
+ {
+ builders[nodeName] = builder;
+ }
+
+ public IQueryBuilder GetQueryBuilder(string nodeName)
+ {
+ IQueryBuilder result;
+ builders.TryGetValue(nodeName, out result);
+ return result;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.QueryParser/Xml/QueryTemplateManager.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Xml/QueryTemplateManager.cs b/src/Lucene.Net.QueryParser/Xml/QueryTemplateManager.cs
new file mode 100644
index 0000000..ee05624
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Xml/QueryTemplateManager.cs
@@ -0,0 +1,191 @@
+\ufeffusing System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Xml.Xsl;
+
+namespace Lucene.Net.QueryParsers.Xml
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /// <summary>
+ /// 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
+ /// and changing how user input is turned into Lucene queries.
+ /// Database applications often adopt similar practices by externalizing SQL in template files that can
+ /// 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
+ /// re-use compiled stylesheets for fast use (e.g. in a server environment)
+ /// </summary>
+ public class QueryTemplateManager
+ {
+ IDictionary<string, XslCompiledTransform> compiledTemplatesCache = new Dictionary<string, XslCompiledTransform>();
+ XslCompiledTransform defaultCompiledTemplates = null;
+
+ public QueryTemplateManager()
+ {
+ }
+
+ public QueryTemplateManager(Stream xslIs)
+ {
+ AddDefaultQueryTemplate(xslIs);
+ }
+
+ public void AddDefaultQueryTemplate(Stream xslIs)
+ {
+ defaultCompiledTemplates = GetTemplates(xslIs);
+ }
+
+ public void AddQueryTemplate(string name, Stream xslIs)
+ {
+ compiledTemplatesCache[name] = GetTemplates(xslIs);
+ }
+
+ public string GetQueryAsXmlString(IDictionary<string, string> formProperties, string queryTemplateName)
+ {
+ XslCompiledTransform ts = compiledTemplatesCache[queryTemplateName];
+ return GetQueryAsXmlString(formProperties, ts);
+ }
+
+ public XmlDocument GetQueryAsDOM(IDictionary<string, string> formProperties, string queryTemplateName)
+ {
+ XslCompiledTransform ts = compiledTemplatesCache[queryTemplateName];
+ return GetQueryAsDOM(formProperties, ts);
+ }
+
+ public string GetQueryAsXmlString(IDictionary<string, string> formProperties)
+ {
+ return GetQueryAsXmlString(formProperties, defaultCompiledTemplates);
+ }
+
+ public XmlDocument GetQueryAsDOM(IDictionary<string, string> formProperties)
+ {
+ return GetQueryAsDOM(formProperties, defaultCompiledTemplates);
+ }
+
+ /// <summary>
+ /// Fast means of constructing query using a precompiled stylesheet
+ /// </summary>
+ public static string GetQueryAsXmlString(IDictionary<string, string> formProperties, XslCompiledTransform template)
+ {
+ // TODO: Suppress XML header with encoding (as Strings have no encoding)
+ using (var stream = new MemoryStream())
+ {
+ TransformCriteria(formProperties, template, stream);
+ using (StreamReader reader = new StreamReader(stream))
+ {
+ return reader.ReadToEnd();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Slow means of constructing query parsing a stylesheet from an input stream
+ /// </summary>
+ public static string GetQueryAsXmlString(IDictionary<string, string> formProperties, Stream xslIs)
+ {
+ // TODO: Suppress XML header with encoding (as Strings have no encoding)
+ using (var stream = new MemoryStream())
+ {
+ TransformCriteria(formProperties, xslIs, stream);
+ using (StreamReader reader = new StreamReader(stream))
+ {
+ return reader.ReadToEnd();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Fast means of constructing query using a cached,precompiled stylesheet
+ /// </summary>
+ public static XmlDocument GetQueryAsDOM(IDictionary<string, string> formProperties, XslCompiledTransform template)
+ {
+ XmlDocument result = new XmlDocument();
+ using (var stream = new MemoryStream())
+ {
+ TransformCriteria(formProperties, template, stream);
+ stream.Position = 0;
+ result.Load(stream);
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Slow means of constructing query - parses stylesheet from input stream
+ /// </summary>
+ public static XmlDocument GetQueryAsDOM(IDictionary<string, string> formProperties, Stream xslIs)
+ {
+ XmlDocument result = new XmlDocument();
+ using (var stream = new MemoryStream())
+ {
+ TransformCriteria(formProperties, xslIs, stream);
+ stream.Position = 0;
+ result.Load(stream);
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Slower transformation using an uncompiled stylesheet (suitable for development environment)
+ /// </summary>
+ public static void TransformCriteria(IDictionary<string, string> formProperties, Stream xslIs, Stream result)
+ {
+ XmlDocument xslDoc = new XmlDocument();
+ xslDoc.Load(xslIs);
+
+ XslCompiledTransform transformer = new XslCompiledTransform();
+ transformer.Load(xslDoc);
+
+ TransformCriteria(formProperties, transformer, result);
+ }
+
+ /// <summary>
+ /// Fast transformation using a pre-compiled stylesheet (suitable for production environments)
+ /// </summary>
+ public static void TransformCriteria(IDictionary<string, string> formProperties, XslCompiledTransform transformer, Stream result)
+ {
+ XmlDocument doc = new XmlDocument();
+ XmlElement root = doc.CreateElement("Document");
+ doc.AppendChild(root);
+
+ foreach (var prop in formProperties)
+ {
+ string propName = prop.Key;
+ string value = prop.Value;
+ if ((value != null) && (value.Length > 0))
+ {
+ DOMUtils.InsertChild(root, propName, value);
+ }
+ }
+
+ transformer.Transform(doc, null, result);
+ }
+
+ /// <summary>
+ /// Parses a query stylesheet for repeated use
+ /// </summary>
+ public static XslCompiledTransform GetTemplates(Stream xslIs)
+ {
+ using (var reader = XmlReader.Create(xslIs))
+ {
+ XslCompiledTransform xslt = new XslCompiledTransform();
+ xslt.Load(reader);
+ return xslt;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Lucene.Net.Tests.QueryParser.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Lucene.Net.Tests.QueryParser.csproj b/src/Lucene.Net.Tests.QueryParser/Lucene.Net.Tests.QueryParser.csproj
index 6a9d560..b33a18d 100644
--- a/src/Lucene.Net.Tests.QueryParser/Lucene.Net.Tests.QueryParser.csproj
+++ b/src/Lucene.Net.Tests.QueryParser/Lucene.Net.Tests.QueryParser.csproj
@@ -86,6 +86,10 @@
<Compile Include="Surround\Query\Test02Boolean.cs" />
<Compile Include="Surround\Query\Test03Distance.cs" />
<Compile Include="Util\QueryParserTestBase.cs" />
+ <Compile Include="Xml\Builders\TestNumericRangeFilterBuilder.cs" />
+ <Compile Include="Xml\Builders\TestNumericRangeQueryBuilder.cs" />
+ <Compile Include="Xml\TestParser.cs" />
+ <Compile Include="Xml\TestQueryTemplateManager.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@@ -118,6 +122,33 @@
<LastGenOutput>MessagesTestBundleBundle.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Xml\albumBooleanQuery.xsl" />
+ <EmbeddedResource Include="Xml\albumFilteredQuery.xsl" />
+ <EmbeddedResource Include="Xml\albumLuceneClassicQuery.xsl" />
+ <EmbeddedResource Include="Xml\BooleanFilter.xml" />
+ <EmbeddedResource Include="Xml\BooleanQuery.xml" />
+ <EmbeddedResource Include="Xml\BoostingQuery.xml" />
+ <EmbeddedResource Include="Xml\BoostingTermQuery.xml" />
+ <EmbeddedResource Include="Xml\CachedFilter.xml" />
+ <EmbeddedResource Include="Xml\ConstantScoreQuery.xml" />
+ <EmbeddedResource Include="Xml\DisjunctionMaxQuery.xml" />
+ <EmbeddedResource Include="Xml\DuplicateFilterQuery.xml" />
+ <EmbeddedResource Include="Xml\FuzzyLikeThisQuery.xml" />
+ <EmbeddedResource Include="Xml\LikeThisQuery.xml" />
+ <EmbeddedResource Include="Xml\MatchAllDocsQuery.xml" />
+ <EmbeddedResource Include="Xml\NestedBooleanQuery.xml" />
+ <EmbeddedResource Include="Xml\NumericRangeFilterQuery.xml" />
+ <EmbeddedResource Include="Xml\NumericRangeQueryQuery.xml" />
+ <EmbeddedResource Include="Xml\RangeFilterQuery.xml" />
+ <EmbeddedResource Include="Xml\reuters21578.txt" />
+ <EmbeddedResource Include="Xml\SpanQuery.xml" />
+ <EmbeddedResource Include="Xml\TermQuery.xml" />
+ <EmbeddedResource Include="Xml\TermsFilterQuery.xml" />
+ <EmbeddedResource Include="Xml\TermsQuery.xml" />
+ <EmbeddedResource Include="Xml\UserInputQuery.xml" />
+ <EmbeddedResource Include="Xml\UserInputQueryCustomField.xml" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Util/QueryParserTestBase.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Util/QueryParserTestBase.cs b/src/Lucene.Net.Tests.QueryParser/Util/QueryParserTestBase.cs
index 698ba35..e6c4621 100644
--- a/src/Lucene.Net.Tests.QueryParser/Util/QueryParserTestBase.cs
+++ b/src/Lucene.Net.Tests.QueryParser/Util/QueryParserTestBase.cs
@@ -1004,7 +1004,7 @@ namespace Lucene.Net.QueryParsers.Util
}
// LUCENETODO: convert this from DateField to DateUtil
- // public void testLocalDateFormat() throws IOException, ParseException {
+ // public void TestLocalDateFormat() throws IOException, ParseException {
// Directory ramDir = newDirectory();
// IndexWriter iw = new IndexWriter(ramDir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random, MockTokenizer.WHITESPACE, false)));
// addDateDoc("a", 2005, 12, 2, 10, 15, 33, iw);
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/BooleanFilter.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/BooleanFilter.xml b/src/Lucene.Net.Tests.QueryParser/Xml/BooleanFilter.xml
new file mode 100644
index 0000000..b601d79
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/BooleanFilter.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<FilteredQuery>
+ <Query>
+ <MatchAllDocsQuery/>
+ </Query>
+
+ <Filter>
+ <!--
+ This query illustrates how a BooleanFilter can be used to combine
+ multiple filters in the same way BooleanQueries can be combined
+ with must, should and mustnot clauses
+ -->
+ <BooleanFilter>
+ <Clause occurs="should">
+ <RangeFilter fieldName="date" lowerTerm="19870409" upperTerm="19870412"/>
+ </Clause>
+ <Clause occurs="mustNot">
+ <TermsFilter fieldName="contents">Emcore</TermsFilter>
+ </Clause>
+ </BooleanFilter>
+
+ </Filter>
+
+</FilteredQuery>
+
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/BooleanQuery.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/BooleanQuery.xml b/src/Lucene.Net.Tests.QueryParser/Xml/BooleanQuery.xml
new file mode 100644
index 0000000..bba1d34
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/BooleanQuery.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<BooleanQuery fieldName="contents">
+ <Clause occurs="should">
+ <TermQuery>merger</TermQuery>
+ </Clause>
+ <Clause occurs="mustnot">
+ <TermQuery>sumitomo</TermQuery>
+ </Clause>
+ <Clause occurs="must">
+ <TermQuery>bank</TermQuery>
+ </Clause>
+</BooleanQuery>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/BoostingQuery.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/BoostingQuery.xml b/src/Lucene.Net.Tests.QueryParser/Xml/BoostingQuery.xml
new file mode 100644
index 0000000..10cfa88
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/BoostingQuery.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<BoostingQuery>
+ <!-- Find docs about banks, preferably merger info and preferably not "World bank" -->
+ <Query>
+ <BooleanQuery fieldName="contents">
+ <Clause occurs="should">
+ <TermQuery>merger</TermQuery>
+ </Clause>
+ <Clause occurs="must">
+ <TermQuery>bank</TermQuery>
+ </Clause>
+ </BooleanQuery>
+ </Query>
+ <BoostQuery boost="0.01">
+ <UserQuery>"world bank"</UserQuery>
+ </BoostQuery>
+</BoostingQuery>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/BoostingTermQuery.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/BoostingTermQuery.xml b/src/Lucene.Net.Tests.QueryParser/Xml/BoostingTermQuery.xml
new file mode 100644
index 0000000..65bbd61
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/BoostingTermQuery.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<BoostingTermQuery fieldName="contents">sumitomo</BoostingTermQuery>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/Builders/TestNumericRangeFilterBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/Builders/TestNumericRangeFilterBuilder.cs b/src/Lucene.Net.Tests.QueryParser/Xml/Builders/TestNumericRangeFilterBuilder.cs
new file mode 100644
index 0000000..5295916
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/Builders/TestNumericRangeFilterBuilder.cs
@@ -0,0 +1,217 @@
+\ufeffusing Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml.Builders
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class TestNumericRangeFilterBuilder : LuceneTestCase
+ {
+ [Test]
+ public void TestGetFilterHandleNumericParseErrorStrict()
+ {
+ NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
+ filterBuilder.SetStrictMode(true);
+
+ String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+ try
+ {
+ filterBuilder.GetFilter(doc.DocumentElement);
+ }
+#pragma warning disable 168
+ catch (ParserException e)
+#pragma warning restore 168
+ {
+ return;
+ }
+ fail("Expected to throw " + typeof(ParserException));
+ }
+
+ [Test]
+ public void TestGetFilterHandleNumericParseError()
+ {
+ NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
+ filterBuilder.SetStrictMode(false);
+
+ String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+ Filter filter = filterBuilder.GetFilter(doc.DocumentElement);
+ Store.Directory ramDir = NewDirectory();
+ IndexWriter writer = new IndexWriter(ramDir, NewIndexWriterConfig(TEST_VERSION_CURRENT, null));
+ writer.Commit();
+ try
+ {
+ AtomicReader reader = SlowCompositeReaderWrapper.Wrap(DirectoryReader.Open(ramDir));
+ try
+ {
+ assertNull(filter.GetDocIdSet(reader.AtomicContext, reader.LiveDocs));
+ }
+ finally
+ {
+ reader.Dispose();
+ }
+ }
+ finally
+ {
+ writer.Commit();
+ writer.Dispose();
+ ramDir.Dispose();
+ }
+ }
+
+ [Test]
+ public void TestGetFilterInt()
+ {
+ NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
+ filterBuilder.SetStrictMode(true);
+
+ String xml = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+ Filter filter = filterBuilder.GetFilter(doc.DocumentElement);
+ assertTrue(filter is NumericRangeFilter<int>);
+
+ NumericRangeFilter<int> numRangeFilter = (NumericRangeFilter<int>)filter;
+ assertEquals(Convert.ToInt32(-1), numRangeFilter.Min);
+ assertEquals(Convert.ToInt32(10), numRangeFilter.Max);
+ assertEquals("AGE", numRangeFilter.Field);
+ assertTrue(numRangeFilter.IncludesMin());
+ assertTrue(numRangeFilter.IncludesMax());
+
+ String xml2 = "<NumericRangeFilter fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10' includeUpper='false'/>";
+ XmlDocument doc2 = GetDocumentFromString(xml2);
+ Filter filter2 = filterBuilder.GetFilter(doc2.DocumentElement);
+ assertTrue(filter2 is NumericRangeFilter<int>);
+
+ NumericRangeFilter<int> numRangeFilter2 = (NumericRangeFilter<int>)filter2;
+ assertEquals(Convert.ToInt32(-1), numRangeFilter2.Min);
+ assertEquals(Convert.ToInt32(10), numRangeFilter2.Max);
+ assertEquals("AGE", numRangeFilter2.Field);
+ assertTrue(numRangeFilter2.IncludesMin());
+ assertFalse(numRangeFilter2.IncludesMax());
+ }
+
+ [Test]
+ public void TestGetFilterLong()
+ {
+ NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
+ filterBuilder.SetStrictMode(true);
+
+ String xml = "<NumericRangeFilter fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+ Filter filter = filterBuilder.GetFilter(doc.DocumentElement);
+ assertTrue(filter is NumericRangeFilter<long>);
+
+ NumericRangeFilter<long> numRangeFilter = (NumericRangeFilter<long>)filter;
+ assertEquals(Convert.ToInt64(-2321L), numRangeFilter.Min);
+ assertEquals(Convert.ToInt64(60000000L), numRangeFilter.Max);
+ assertEquals("AGE", numRangeFilter.Field);
+ assertTrue(numRangeFilter.IncludesMin());
+ assertTrue(numRangeFilter.IncludesMax());
+
+ String xml2 = "<NumericRangeFilter fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000' includeUpper='false'/>";
+ XmlDocument doc2 = GetDocumentFromString(xml2);
+ Filter filter2 = filterBuilder.GetFilter(doc2.DocumentElement);
+ assertTrue(filter2 is NumericRangeFilter<long>);
+ NumericRangeFilter<long> numRangeFilter2 = (NumericRangeFilter<long>)filter2;
+ assertEquals(Convert.ToInt64(-2321L), numRangeFilter2.Min);
+ assertEquals(Convert.ToInt64(60000000L), numRangeFilter2.Max);
+ assertEquals("AGE", numRangeFilter2.Field);
+ assertTrue(numRangeFilter2.IncludesMin());
+ assertFalse(numRangeFilter2.IncludesMax());
+ }
+
+ [Test]
+ public void TestGetFilterDouble()
+ {
+ NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
+ filterBuilder.SetStrictMode(true);
+
+ String xml = "<NumericRangeFilter fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+
+ Filter filter = filterBuilder.GetFilter(doc.DocumentElement);
+ assertTrue(filter is NumericRangeFilter<double>);
+
+ NumericRangeFilter<double> numRangeFilter = (NumericRangeFilter<double>)filter;
+ assertEquals(Convert.ToDouble(-23.21d), numRangeFilter.Min);
+ assertEquals(Convert.ToDouble(60000.00023d), numRangeFilter.Max);
+ assertEquals("AGE", numRangeFilter.Field);
+ assertTrue(numRangeFilter.IncludesMin());
+ assertTrue(numRangeFilter.IncludesMax());
+
+ String xml2 = "<NumericRangeFilter fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023' includeUpper='false'/>";
+ XmlDocument doc2 = GetDocumentFromString(xml2);
+ Filter filter2 = filterBuilder.GetFilter(doc2.DocumentElement);
+ assertTrue(filter2 is NumericRangeFilter<double>);
+
+ NumericRangeFilter<double> numRangeFilter2 = (NumericRangeFilter<double>)filter2;
+ assertEquals(Convert.ToDouble(-23.21d), numRangeFilter2.Min);
+ assertEquals(Convert.ToDouble(60000.00023d), numRangeFilter2.Max);
+ assertEquals("AGE", numRangeFilter2.Field);
+ assertTrue(numRangeFilter2.IncludesMin());
+ assertFalse(numRangeFilter2.IncludesMax());
+ }
+
+ [Test]
+ public void TestGetFilterFloat()
+ {
+ NumericRangeFilterBuilder filterBuilder = new NumericRangeFilterBuilder();
+ filterBuilder.SetStrictMode(true);
+
+ String xml = "<NumericRangeFilter fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+
+ Filter filter = filterBuilder.GetFilter(doc.DocumentElement);
+ assertTrue(filter is NumericRangeFilter<float>);
+
+ NumericRangeFilter<float> numRangeFilter = (NumericRangeFilter<float>)filter;
+ assertEquals(Convert.ToSingle(-2.321432f), numRangeFilter.Min);
+ assertEquals(Convert.ToSingle(32432.23f), numRangeFilter.Max);
+ assertEquals("AGE", numRangeFilter.Field);
+ assertTrue(numRangeFilter.IncludesMin());
+ assertTrue(numRangeFilter.IncludesMax());
+
+ String xml2 = "<NumericRangeFilter fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23' includeUpper='false' precisionStep='2' />";
+ XmlDocument doc2 = GetDocumentFromString(xml2);
+
+ Filter filter2 = filterBuilder.GetFilter(doc2.DocumentElement);
+ assertTrue(filter2 is NumericRangeFilter<float>);
+
+ NumericRangeFilter<float> numRangeFilter2 = (NumericRangeFilter<float>)filter2;
+ assertEquals(Convert.ToSingle(-2.321432f), numRangeFilter2.Min);
+ assertEquals(Convert.ToSingle(32432.23f), numRangeFilter2.Max);
+ assertEquals("AGE", numRangeFilter2.Field);
+ assertTrue(numRangeFilter2.IncludesMin());
+ assertFalse(numRangeFilter2.IncludesMax());
+ }
+
+ private static XmlDocument GetDocumentFromString(String str)
+ {
+ XmlDocument result = new XmlDocument();
+ result.LoadXml(str);
+ return result;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/Builders/TestNumericRangeQueryBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/Builders/TestNumericRangeQueryBuilder.cs b/src/Lucene.Net.Tests.QueryParser/Xml/Builders/TestNumericRangeQueryBuilder.cs
new file mode 100644
index 0000000..4d6e84d
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/Builders/TestNumericRangeQueryBuilder.cs
@@ -0,0 +1,177 @@
+\ufeffusing Lucene.Net.Search;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using System;
+using System.Xml;
+
+namespace Lucene.Net.QueryParsers.Xml.Builders
+{
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ public class TestNumericRangeQueryBuilder : LuceneTestCase
+ {
+ [Test]
+ public void TestGetFilterHandleNumericParseErrorStrict()
+ {
+ NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
+
+ String xml = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='NaN'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+ try
+ {
+ filterBuilder.GetQuery(doc.DocumentElement);
+ }
+#pragma warning disable 168
+ catch (ParserException e)
+#pragma warning restore 168
+ {
+ return;
+ }
+ fail("Expected to throw " + typeof(ParserException));
+ }
+
+ [Test]
+ public void TestGetFilterInt()
+ {
+ NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
+
+ String xml = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+ Query filter = filterBuilder.GetQuery(doc.DocumentElement);
+ assertTrue(filter is NumericRangeQuery<int>);
+
+ NumericRangeQuery<int> numRangeFilter = (NumericRangeQuery<int>)filter;
+ assertEquals(Convert.ToInt32(-1), numRangeFilter.Min);
+ assertEquals(Convert.ToInt32(10), numRangeFilter.Max);
+ assertEquals("AGE", numRangeFilter.Field);
+ assertTrue(numRangeFilter.IncludesMin());
+ assertTrue(numRangeFilter.IncludesMax());
+
+ String xml2 = "<NumericRangeQuery fieldName='AGE' type='int' lowerTerm='-1' upperTerm='10' includeUpper='false'/>";
+ XmlDocument doc2 = GetDocumentFromString(xml2);
+ Query filter2 = filterBuilder.GetQuery(doc2.DocumentElement);
+ assertTrue(filter2 is NumericRangeQuery<int>);
+
+ NumericRangeQuery<int> numRangeFilter2 = (NumericRangeQuery<int>)filter2;
+ assertEquals(Convert.ToInt32(-1), numRangeFilter2.Min);
+ assertEquals(Convert.ToInt32(10), numRangeFilter2.Max);
+ assertEquals("AGE", numRangeFilter2.Field);
+ assertTrue(numRangeFilter2.IncludesMin());
+ assertFalse(numRangeFilter2.IncludesMax());
+ }
+
+ [Test]
+ public void TestGetFilterLong()
+ {
+ NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
+
+ String xml = "<NumericRangeQuery fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+ Query filter = filterBuilder.GetQuery(doc.DocumentElement);
+ assertTrue(filter is NumericRangeQuery<long>);
+ NumericRangeQuery<long> numRangeFilter = (NumericRangeQuery<long>)filter;
+ assertEquals(Convert.ToInt64(-2321L), numRangeFilter.Min);
+ assertEquals(Convert.ToInt64(60000000L), numRangeFilter.Max);
+ assertEquals("AGE", numRangeFilter.Field);
+ assertTrue(numRangeFilter.IncludesMin());
+ assertTrue(numRangeFilter.IncludesMax());
+
+ String xml2 = "<NumericRangeQuery fieldName='AGE' type='LoNg' lowerTerm='-2321' upperTerm='60000000' includeUpper='false'/>";
+ XmlDocument doc2 = GetDocumentFromString(xml2);
+ Query filter2 = filterBuilder.GetQuery(doc2.DocumentElement);
+ assertTrue(filter2 is NumericRangeQuery<long>);
+
+ NumericRangeQuery<long> numRangeFilter2 = (NumericRangeQuery<long>)filter2;
+ assertEquals(Convert.ToInt64(-2321L), numRangeFilter2.Min);
+ assertEquals(Convert.ToInt64(60000000L), numRangeFilter2.Max);
+ assertEquals("AGE", numRangeFilter2.Field);
+ assertTrue(numRangeFilter2.IncludesMin());
+ assertFalse(numRangeFilter2.IncludesMax());
+ }
+
+ [Test]
+ public void TestGetFilterDouble()
+ {
+ NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
+
+ String xml = "<NumericRangeQuery fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+
+ Query filter = filterBuilder.GetQuery(doc.DocumentElement);
+ assertTrue(filter is NumericRangeQuery<double>);
+
+ NumericRangeQuery<double> numRangeFilter = (NumericRangeQuery<double>)filter;
+ assertEquals(Convert.ToDouble(-23.21d), numRangeFilter.Min);
+ assertEquals(Convert.ToDouble(60000.00023d), numRangeFilter.Max);
+ assertEquals("AGE", numRangeFilter.Field);
+ assertTrue(numRangeFilter.IncludesMin());
+ assertTrue(numRangeFilter.IncludesMax());
+
+ String xml2 = "<NumericRangeQuery fieldName='AGE' type='doubLe' lowerTerm='-23.21' upperTerm='60000.00023' includeUpper='false'/>";
+ XmlDocument doc2 = GetDocumentFromString(xml2);
+ Query filter2 = filterBuilder.GetQuery(doc2.DocumentElement);
+ assertTrue(filter2 is NumericRangeQuery<double>);
+
+ NumericRangeQuery<double> numRangeFilter2 = (NumericRangeQuery<double>)filter2;
+ assertEquals(Convert.ToDouble(-23.21d), numRangeFilter2.Min);
+ assertEquals(Convert.ToDouble(60000.00023d), numRangeFilter2.Max);
+ assertEquals("AGE", numRangeFilter2.Field);
+ assertTrue(numRangeFilter2.IncludesMin());
+ assertFalse(numRangeFilter2.IncludesMax());
+ }
+
+ [Test]
+ public void TestGetFilterFloat()
+ {
+ NumericRangeQueryBuilder filterBuilder = new NumericRangeQueryBuilder();
+
+ String xml = "<NumericRangeQuery fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23'/>";
+ XmlDocument doc = GetDocumentFromString(xml);
+
+ Query filter = filterBuilder.GetQuery(doc.DocumentElement);
+ assertTrue(filter is NumericRangeQuery<float>);
+
+ NumericRangeQuery<float> numRangeFilter = (NumericRangeQuery<float>)filter;
+ assertEquals(Convert.ToSingle(-2.321432f), numRangeFilter.Min);
+ assertEquals(Convert.ToSingle(32432.23f), numRangeFilter.Max);
+ assertEquals("AGE", numRangeFilter.Field);
+ assertTrue(numRangeFilter.IncludesMin());
+ assertTrue(numRangeFilter.IncludesMax());
+
+ String xml2 = "<NumericRangeQuery fieldName='AGE' type='FLOAT' lowerTerm='-2.321432' upperTerm='32432.23' includeUpper='false' precisionStep='2' />";
+ XmlDocument doc2 = GetDocumentFromString(xml2);
+
+ Query filter2 = filterBuilder.GetQuery(doc2.DocumentElement);
+ assertTrue(filter2 is NumericRangeQuery<float>);
+
+ NumericRangeQuery<float> numRangeFilter2 = (NumericRangeQuery<float>)filter2;
+ assertEquals(Convert.ToSingle(-2.321432f), numRangeFilter2.Min);
+ assertEquals(Convert.ToSingle(32432.23f), numRangeFilter2.Max);
+ assertEquals("AGE", numRangeFilter2.Field);
+ assertTrue(numRangeFilter2.IncludesMin());
+ assertFalse(numRangeFilter2.IncludesMax());
+ }
+
+ private static XmlDocument GetDocumentFromString(String str)
+ {
+ XmlDocument result = new XmlDocument();
+ result.LoadXml(str);
+ return result;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/CachedFilter.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/CachedFilter.xml b/src/Lucene.Net.Tests.QueryParser/Xml/CachedFilter.xml
new file mode 100644
index 0000000..7d10711
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/CachedFilter.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<FilteredQuery>
+ <Query>
+ <BooleanQuery fieldName="contents">
+ <Clause occurs="should">
+ <TermQuery>merger</TermQuery>
+ </Clause>
+ <Clause occurs="mustnot">
+ <TermQuery >sumitomo</TermQuery>
+ </Clause>
+ </BooleanQuery>
+ </Query>
+
+ <Filter>
+ <!--
+ CachedFilter elements can contain any Query or Filter.
+ CachedFilters are cached in an LRU Cache keyed on the contained query/filter object.
+ Using this will speed up overall performance for repeated uses of the same expensive
+ query/filter. The sorts of queries 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. 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 millions of document ids from disk which can more usefully be cached as a
+ QueryFilter bitset.
+
+ 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.
+
+ The CoreParser.maxNumCachedFilters property can be used to control the size
+ of the LRU Cache established during the construction of CoreParser instances.
+ -->
+ <CachedFilter>
+ <!-- Example query to be cached for fast, repeated use -->
+ <TermQuery fieldName="contents">bank</TermQuery>
+ <!-- Alternatively, a filter object can be cached ....
+ <RangeFilter fieldName="date" lowerTerm="19870409" upperTerm="19870412"/>
+ -->
+ </CachedFilter>
+ </Filter>
+
+</FilteredQuery>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/ConstantScoreQuery.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/ConstantScoreQuery.xml b/src/Lucene.Net.Tests.QueryParser/Xml/ConstantScoreQuery.xml
new file mode 100644
index 0000000..c5994d1
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/ConstantScoreQuery.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<ConstantScoreQuery>
+ <RangeFilter fieldName="date" lowerTerm="19870409" upperTerm="19870412"/>
+</ConstantScoreQuery>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/DisjunctionMaxQuery.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/DisjunctionMaxQuery.xml b/src/Lucene.Net.Tests.QueryParser/Xml/DisjunctionMaxQuery.xml
new file mode 100644
index 0000000..eb47816
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/DisjunctionMaxQuery.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<DisjunctionMaxQuery>
+ <TermQuery fieldName="a">merger</TermQuery>
+ <DisjunctionMaxQuery tieBreaker="1.2">
+ <TermQuery fieldName="b">verger</TermQuery>
+ </DisjunctionMaxQuery>
+</DisjunctionMaxQuery>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/DuplicateFilterQuery.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/DuplicateFilterQuery.xml b/src/Lucene.Net.Tests.QueryParser/Xml/DuplicateFilterQuery.xml
new file mode 100644
index 0000000..c5002c7
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/DuplicateFilterQuery.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<FilteredQuery>
+ <Query>
+ <BooleanQuery fieldName="contents">
+ <Clause occurs="should">
+ <TermQuery>money</TermQuery>
+ </Clause>
+ <Clause occurs="must">
+ <TermQuery fieldName="date">19870408</TermQuery>
+ </Clause>
+ </BooleanQuery>
+ </Query>
+ <Filter>
+ <!-- Filters to last document with this date -->
+ <DuplicateFilter fieldName="date" keepMode="last"/>
+ </Filter>
+
+</FilteredQuery>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/2ae0b1bb/src/Lucene.Net.Tests.QueryParser/Xml/FuzzyLikeThisQuery.xml
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Tests.QueryParser/Xml/FuzzyLikeThisQuery.xml b/src/Lucene.Net.Tests.QueryParser/Xml/FuzzyLikeThisQuery.xml
new file mode 100644
index 0000000..2d11b4e
--- /dev/null
+++ b/src/Lucene.Net.Tests.QueryParser/Xml/FuzzyLikeThisQuery.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<FuzzyLikeThisQuery>
+ <!-- Matches on misspelt "Sumitomo" bank -->
+ <Field fieldName="contents">
+ Sumitimo bank
+ </Field>
+</FuzzyLikeThisQuery>