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/06 15:11:43 UTC
[08/58] lucenenet git commit: WIP on QueryParsers.Flexible
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/StandardQueryTreeBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/StandardQueryTreeBuilder.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/StandardQueryTreeBuilder.cs
new file mode 100644
index 0000000..f40040f
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/StandardQueryTreeBuilder.cs
@@ -0,0 +1,60 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Builders;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Standard.Nodes;
+using Lucene.Net.Search;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Builders
+{
+ /// <summary>
+ /// This query tree builder only defines the necessary map to build a
+ /// {@link Query} tree object. It should be used to generate a {@link Query} tree
+ /// object from a query node tree processed by a
+ /// {@link StandardQueryNodeProcessorPipeline}.
+ /// </summary>
+ /// <seealso cref="QueryTreeBuilder"/>
+ /// <seealso cref="StandardQueryNodeProcessorPipeline"/>
+ public class StandardQueryTreeBuilder : QueryTreeBuilder, IStandardQueryBuilder
+ {
+ public StandardQueryTreeBuilder()
+ {
+ SetBuilder(typeof(GroupQueryNode), new GroupQueryNodeBuilder());
+ SetBuilder(typeof(FieldQueryNode), new FieldQueryNodeBuilder());
+ SetBuilder(typeof(BooleanQueryNode), new BooleanQueryNodeBuilder());
+ SetBuilder(typeof(FuzzyQueryNode), new FuzzyQueryNodeBuilder());
+ SetBuilder(typeof(NumericQueryNode), new DummyQueryNodeBuilder());
+ SetBuilder(typeof(NumericRangeQueryNode), new NumericRangeQueryNodeBuilder());
+ SetBuilder(typeof(BoostQueryNode), new BoostQueryNodeBuilder());
+ SetBuilder(typeof(ModifierQueryNode), new ModifierQueryNodeBuilder());
+ SetBuilder(typeof(WildcardQueryNode), new WildcardQueryNodeBuilder());
+ SetBuilder(typeof(TokenizedPhraseQueryNode), new PhraseQueryNodeBuilder());
+ SetBuilder(typeof(MatchNoDocsQueryNode), new MatchNoDocsQueryNodeBuilder());
+ SetBuilder(typeof(PrefixWildcardQueryNode),
+ new PrefixWildcardQueryNodeBuilder());
+ SetBuilder(typeof(TermRangeQueryNode), new TermRangeQueryNodeBuilder());
+ SetBuilder(typeof(RegexpQueryNode), new RegexpQueryNodeBuilder());
+ SetBuilder(typeof(SlopQueryNode), new SlopQueryNodeBuilder());
+ SetBuilder(typeof(StandardBooleanQueryNode),
+ new StandardBooleanQueryNodeBuilder());
+ SetBuilder(typeof(MultiPhraseQueryNode), new MultiPhraseQueryNodeBuilder());
+ SetBuilder(typeof(MatchAllDocsQueryNode), new MatchAllDocsQueryNodeBuilder());
+
+ }
+
+ public override object Build(IQueryNode queryNode)
+ {
+ return base.Build(queryNode);
+ }
+ /// <summary>
+ /// LUCENENET specific overload for supporting IStandardQueryBuilder
+ /// </summary>
+ Query IStandardQueryBuilder.Build(IQueryNode queryNode)
+ {
+ return (Query)Build(queryNode);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/TermRangeQueryNodeBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/TermRangeQueryNodeBuilder.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/TermRangeQueryNodeBuilder.cs
new file mode 100644
index 0000000..f619137
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/TermRangeQueryNodeBuilder.cs
@@ -0,0 +1,69 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Builders;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Core.Util;
+using Lucene.Net.QueryParsers.Flexible.Standard.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Standard.Processors;
+using Lucene.Net.Search;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Builders
+{
+ /// <summary>
+ /// Builds a {@link TermRangeQuery} object from a {@link TermRangeQueryNode}
+ /// object.
+ /// </summary>
+ public class TermRangeQueryNodeBuilder : IStandardQueryBuilder
+ {
+ public TermRangeQueryNodeBuilder()
+ {
+ // empty constructor
+ }
+
+
+ public virtual Query Build(IQueryNode queryNode)
+ {
+ TermRangeQueryNode rangeNode = (TermRangeQueryNode)queryNode;
+ FieldQueryNode upper = (FieldQueryNode)rangeNode.UpperBound;
+ FieldQueryNode lower = (FieldQueryNode)rangeNode.LowerBound;
+
+ string field = StringUtils.ToString(rangeNode.Field);
+ string lowerText = lower.GetTextAsString();
+ string upperText = upper.GetTextAsString();
+
+ if (lowerText.Length == 0)
+ {
+ lowerText = null;
+ }
+
+ if (upperText.Length == 0)
+ {
+ upperText = null;
+ }
+
+ TermRangeQuery rangeQuery = TermRangeQuery.NewStringRange(field, lowerText, upperText, rangeNode
+ .IsLowerInclusive, rangeNode.IsUpperInclusive);
+
+ MultiTermQuery.RewriteMethod method = (MultiTermQuery.RewriteMethod)queryNode
+ .GetTag(MultiTermRewriteMethodProcessor.TAG_ID);
+ if (method != null)
+ {
+ rangeQuery.SetRewriteMethod(method);
+ }
+
+ return rangeQuery;
+
+ }
+
+ /// <summary>
+ /// LUCENENET specific overload for supporting IQueryBuilder
+ /// </summary>
+ object IQueryBuilder.Build(IQueryNode queryNode)
+ {
+ return Build(queryNode);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/WildcardQueryNodeBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/WildcardQueryNodeBuilder.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/WildcardQueryNodeBuilder.cs
new file mode 100644
index 0000000..eb74378
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Builders/WildcardQueryNodeBuilder.cs
@@ -0,0 +1,51 @@
+\ufeffusing Lucene.Net.Index;
+using Lucene.Net.QueryParsers.Flexible.Core.Builders;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Standard.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Standard.Processors;
+using Lucene.Net.Search;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Builders
+{
+ /// <summary>
+ /// Builds a {@link WildcardQuery} object from a {@link WildcardQueryNode}
+ /// object.
+ /// </summary>
+ public class WildcardQueryNodeBuilder : IStandardQueryBuilder
+ {
+ public WildcardQueryNodeBuilder()
+ {
+ // empty constructor
+ }
+
+
+ public virtual Query Build(IQueryNode queryNode)
+ {
+ WildcardQueryNode wildcardNode = (WildcardQueryNode)queryNode;
+
+ WildcardQuery q = new WildcardQuery(new Term(wildcardNode.GetFieldAsString(),
+ wildcardNode.GetTextAsString()));
+
+ MultiTermQuery.RewriteMethod method = (MultiTermQuery.RewriteMethod)queryNode.GetTag(MultiTermRewriteMethodProcessor.TAG_ID);
+ if (method != null)
+ {
+ q.SetRewriteMethod(method);
+ }
+
+ return q;
+ }
+
+ /// <summary>
+ /// LUCENENET specific overload for supporting IQueryBuilder
+ /// </summary>
+ object IQueryBuilder.Build(IQueryNode queryNode)
+ {
+ return Build(queryNode);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/CommonQueryParserConfiguration.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/CommonQueryParserConfiguration.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/CommonQueryParserConfiguration.cs
index 35ec103..e2f5548 100644
--- a/src/Lucene.Net.QueryParser/Flexible/Standard/CommonQueryParserConfiguration.cs
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/CommonQueryParserConfiguration.cs
@@ -101,6 +101,6 @@ namespace Lucene.Net.QueryParsers.Flexible.Standard
/// Sets the default <see cref="T:DateTools.Resolution"/> used for certain field when
/// no <see cref="T:DateTools.Resolution"/> is defined for this field.
/// </summary>
- void SetDateResolution(DateTools.Resolution dateResolution);
+ void SetDateResolution(DateTools.Resolution dateResolution); // LUCENENET TODO: Make into property set
}
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FieldBoostMapFCListener.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FieldBoostMapFCListener.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FieldBoostMapFCListener.cs
new file mode 100644
index 0000000..02db0f5
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FieldBoostMapFCListener.cs
@@ -0,0 +1,47 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Config;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Config
+{
+ /// <summary>
+ /// This listener listens for every field configuration request and assign a
+ /// {@link ConfigurationKeys#BOOST} to the
+ /// equivalent {@link FieldConfig} based on a defined map: fieldName -> boostValue stored in
+ /// {@link ConfigurationKeys#FIELD_BOOST_MAP}.
+ /// </summary>
+ /// <seealso cref="ConfigurationKeys#FIELD_BOOST_MAP"/>
+ /// <seealso cref="ConfigurationKeys#BOOST"/>
+ /// <seealso cref="FieldConfig"/>
+ /// <seealso cref="IFieldConfigListener"/>
+ public class FieldBoostMapFCListener : IFieldConfigListener
+ {
+ private QueryConfigHandler config = null;
+
+ public FieldBoostMapFCListener(QueryConfigHandler config)
+ {
+ this.config = config;
+ }
+
+
+ public virtual void BuildFieldConfig(FieldConfig fieldConfig)
+ {
+ IDictionary<string, float?> fieldBoostMap = this.config.Get(ConfigurationKeys.FIELD_BOOST_MAP);
+
+ if (fieldBoostMap != null)
+ {
+ float? boost;// = fieldBoostMap.Get(fieldConfig.GetField());
+ fieldBoostMap.TryGetValue(fieldConfig.GetField(), out boost);
+
+ if (boost != null)
+ {
+ fieldConfig.Set(ConfigurationKeys.BOOST, boost);
+ }
+
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FieldDateResolutionFCListener.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FieldDateResolutionFCListener.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FieldDateResolutionFCListener.cs
new file mode 100644
index 0000000..10c8403
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FieldDateResolutionFCListener.cs
@@ -0,0 +1,55 @@
+\ufeffusing Lucene.Net.Documents;
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Config
+{
+ /// <summary>
+ /// This listener listens for every field configuration request and assign a
+ /// {@link ConfigurationKeys#DATE_RESOLUTION} to the equivalent {@link FieldConfig} based
+ /// on a defined map: fieldName -> {@link Resolution} stored in
+ /// {@link ConfigurationKeys#FIELD_DATE_RESOLUTION_MAP}.
+ /// </summary>
+ /// <seealso cref="ConfigurationKeys#DATE_RESOLUTION"/>
+ /// <seealso cref="ConfigurationKeys#FIELD_DATE_RESOLUTION_MAP"/>
+ /// <seealso cref="FieldConfig"/>
+ /// <seealso cref="IFieldConfigListener"/>
+ public class FieldDateResolutionFCListener : IFieldConfigListener
+ {
+ private QueryConfigHandler config = null;
+
+ public FieldDateResolutionFCListener(QueryConfigHandler config)
+ {
+ this.config = config;
+ }
+
+
+ public virtual void BuildFieldConfig(FieldConfig fieldConfig)
+ {
+ DateTools.Resolution? dateRes = null;
+ IDictionary<string, DateTools.Resolution?> dateResMap = this.config.Get(ConfigurationKeys.FIELD_DATE_RESOLUTION_MAP);
+
+ if (dateResMap != null)
+ {
+ dateResMap.TryGetValue(fieldConfig.GetField(), out dateRes);
+
+ //dateRes = dateResMap.Get(
+ // fieldConfig.GetField());
+ }
+
+ if (dateRes == null)
+ {
+ dateRes = this.config.Get(ConfigurationKeys.DATE_RESOLUTION);
+ }
+
+ if (dateRes != null)
+ {
+ fieldConfig.Set(ConfigurationKeys.DATE_RESOLUTION, dateRes.Value);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FuzzyConfig.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FuzzyConfig.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FuzzyConfig.cs
new file mode 100644
index 0000000..1077329
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/FuzzyConfig.cs
@@ -0,0 +1,41 @@
+\ufeffusing Lucene.Net.Search;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Config
+{
+ /// <summary>
+ /// Configuration parameters for {@link FuzzyQuery}s
+ /// </summary>
+ public class FuzzyConfig
+ {
+ private int prefixLength = FuzzyQuery.DefaultPrefixLength;
+
+ private float minSimilarity = FuzzyQuery.DefaultMinSimilarity;
+
+ public FuzzyConfig() { }
+
+ public int GetPrefixLength()
+ {
+ return prefixLength;
+ }
+
+ public void SetPrefixLength(int prefixLength)
+ {
+ this.prefixLength = prefixLength;
+ }
+
+ public float GetMinSimilarity()
+ {
+ return minSimilarity;
+ }
+
+ public void SetMinSimilarity(float minSimilarity)
+ {
+ this.minSimilarity = minSimilarity;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumberDateFormat.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumberDateFormat.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumberDateFormat.cs
new file mode 100644
index 0000000..c7f9f63
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumberDateFormat.cs
@@ -0,0 +1,60 @@
+\ufeff// LUCENENET TODO: Do we need this class?
+
+//using System;
+//using System.Collections.Generic;
+//using System.Linq;
+//using System.Text;
+//using System.Threading.Tasks;
+
+//namespace Lucene.Net.QueryParsers.Flexible.Standard.Config
+//{
+// /// <summary>
+// /// This {@link Format} parses {@link Long} into date strings and vice-versa. It
+// /// uses the given {@link DateFormat} to parse and format dates, but before, it
+// /// converts {@link Long} to {@link Date} objects or vice-versa.
+// /// </summary>
+// public class NumberDateFormat : NumberFormat
+// {
+// //private static readonly long serialVersionUID = 964823936071308283L;
+
+// private readonly DateFormat dateFormat;
+
+// /**
+// * Constructs a {@link NumberDateFormat} object using the given {@link DateFormat}.
+// *
+// * @param dateFormat {@link DateFormat} used to parse and format dates
+// */
+// public NumberDateFormat(DateFormat dateFormat)
+// {
+// this.dateFormat = dateFormat;
+// }
+
+
+// public override StringBuilder format(double number, StringBuilder toAppendTo,
+// FieldPosition pos)
+// {
+// return dateFormat.format(new Date((long)number), toAppendTo, pos);
+// }
+
+
+// public override StringBuilder format(long number, StringBuilder toAppendTo,
+// FieldPosition pos)
+// {
+// return dateFormat.format(new Date(number), toAppendTo, pos);
+// }
+
+
+// public override /*Number*/ object Parse(string source, ParsePosition parsePosition)
+// {
+// DateTime date = dateFormat.parse(source, parsePosition);
+// return (date == null) ? null : date.getTime();
+// }
+
+
+// public override StringBuffer format(object number, StringBuilder toAppendTo,
+// FieldPosition pos)
+// {
+// return dateFormat.format(number, toAppendTo, pos);
+// }
+// }
+//}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumericConfig.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumericConfig.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumericConfig.cs
new file mode 100644
index 0000000..b73ac0b
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumericConfig.cs
@@ -0,0 +1,155 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static Lucene.Net.Documents.FieldType;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Config
+{
+ /// <summary>
+ /// This class holds the configuration used to parse numeric queries and create
+ /// {@link NumericRangeQuery}s.
+ /// </summary>
+ /// <seealso cref="NumericRangeQuery"/>
+ /// <seealso cref="NumberFormat"/>
+ public class NumericConfig
+ {
+ private int precisionStep;
+
+ private /*NumberFormat*/ string format;
+
+ private NumericType type;
+
+ /**
+ * Constructs a {@link NumericConfig} object.
+ *
+ * @param precisionStep
+ * the precision used to index the numeric values
+ * @param format
+ * the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ * @param type
+ * the numeric type used to index the numeric values
+ *
+ * @see NumericConfig#setPrecisionStep(int)
+ * @see NumericConfig#setNumberFormat(NumberFormat)
+ * @see #setType(org.apache.lucene.document.FieldType.NumericType)
+ */
+ public NumericConfig(int precisionStep, /*NumberFormat*/ string format,
+ NumericType type)
+ {
+ SetPrecisionStep(precisionStep);
+ SetNumberFormat(format);
+ SetType(type);
+
+ }
+
+ /**
+ * Returns the precision used to index the numeric values
+ *
+ * @return the precision used to index the numeric values
+ *
+ * @see NumericRangeQuery#getPrecisionStep()
+ */
+ public int GetPrecisionStep()
+ {
+ return precisionStep;
+ }
+
+ /**
+ * Sets the precision used to index the numeric values
+ *
+ * @param precisionStep
+ * the precision used to index the numeric values
+ *
+ * @see NumericRangeQuery#getPrecisionStep()
+ */
+ public void SetPrecisionStep(int precisionStep)
+ {
+ this.precisionStep = precisionStep;
+ }
+
+ /**
+ * Returns the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ *
+ * @return the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ */
+ public /*NumberFormat*/ string GetNumberFormat()
+ {
+ return format;
+ }
+
+ /**
+ * Returns the numeric type used to index the numeric values
+ *
+ * @return the numeric type used to index the numeric values
+ */
+ public NumericType GetType()
+ {
+ return type;
+ }
+
+ /**
+ * Sets the numeric type used to index the numeric values
+ *
+ * @param type the numeric type used to index the numeric values
+ */
+ public void SetType(NumericType type)
+ {
+
+ //if (type == null)
+ //{
+ // throw new ArgumentException("type cannot be null!");
+ //}
+
+ this.type = type;
+
+ }
+
+ /**
+ * Sets the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ *
+ * @param format
+ * the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}, cannot be <code>null</code>
+ */
+ public void SetNumberFormat(/*NumberFormat*/ string format)
+ {
+
+ if (format == null)
+ {
+ throw new ArgumentException("format cannot be null!");
+ }
+
+ this.format = format;
+
+ }
+
+
+ public override bool Equals(object obj)
+ {
+
+ if (obj == this) return true;
+
+ if (obj is NumericConfig)
+ {
+ NumericConfig other = (NumericConfig)obj;
+
+ if (this.precisionStep == other.precisionStep
+ && this.type == other.type
+ && (this.format == other.format || (this.format.Equals(other.format))))
+ {
+ return true;
+ }
+
+ }
+
+ return false;
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumericFieldConfigListener.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumericFieldConfigListener.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumericFieldConfigListener.cs
new file mode 100644
index 0000000..65c4c2b
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/NumericFieldConfigListener.cs
@@ -0,0 +1,59 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Config;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Config
+{
+ /// <summary>
+ /// This listener is used to listen to {@link FieldConfig} requests in
+ /// {@link QueryConfigHandler} and add {@link ConfigurationKeys#NUMERIC_CONFIG}
+ /// based on the {@link ConfigurationKeys#NUMERIC_CONFIG_MAP} set in the
+ /// {@link QueryConfigHandler}.
+ /// </summary>
+ /// <seealso cref="NumericConfig"/>
+ /// <seealso cref="QueryConfigHandler"/>
+ /// <seealso cref="ConfigurationKeys#NUMERIC_CONFIG"/>
+ /// <seealso cref="ConfigurationKeys#NUMERIC_CONFIG_MAP"/>
+ public class NumericFieldConfigListener : IFieldConfigListener
+ {
+ private readonly QueryConfigHandler config;
+
+ /**
+ * Construcs a {@link NumericFieldConfigListener} object using the given {@link QueryConfigHandler}.
+ *
+ * @param config the {@link QueryConfigHandler} it will listen too
+ */
+ public NumericFieldConfigListener(QueryConfigHandler config)
+ {
+ if (config == null)
+ {
+ throw new ArgumentException("config cannot be null!");
+ }
+
+ this.config = config;
+ }
+
+ public virtual void BuildFieldConfig(FieldConfig fieldConfig)
+ {
+ IDictionary<string, NumericConfig> numericConfigMap = config
+ .Get(ConfigurationKeys.NUMERIC_CONFIG_MAP);
+
+ if (numericConfigMap != null)
+ {
+ //NumericConfig numericConfig = numericConfigMap
+ // .Get(fieldConfig.GetField());
+ NumericConfig numericConfig;
+
+
+ //if (numericConfig != null)
+ if (numericConfigMap.TryGetValue(fieldConfig.GetField(), out numericConfig) && numericConfig != null)
+ {
+ fieldConfig.Set(ConfigurationKeys.NUMERIC_CONFIG, numericConfig);
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Config/StandardQueryConfigHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Config/StandardQueryConfigHandler.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/StandardQueryConfigHandler.cs
new file mode 100644
index 0000000..a3e10af
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Config/StandardQueryConfigHandler.cs
@@ -0,0 +1,200 @@
+\ufeffusing Lucene.Net.Analysis;
+using Lucene.Net.Documents;
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using Lucene.Net.Search;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static Lucene.Net.QueryParsers.Flexible.Standard.Config.StandardQueryConfigHandler;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Config
+{
+ /// <summary>
+ /// This query configuration handler is used for almost every processor defined
+ /// in the {@link StandardQueryNodeProcessorPipeline} processor pipeline. It holds
+ /// configuration methods that reproduce the configuration methods that could be set on the old
+ /// lucene 2.4 QueryParser class.
+ /// </summary>
+ /// <seealso cref="StandardQueryNodeProcessorPipeline"/>
+ public class StandardQueryConfigHandler : QueryConfigHandler
+ {
+
+
+ public StandardQueryConfigHandler()
+ {
+ // Add listener that will build the FieldConfig.
+ AddFieldConfigListener(new FieldBoostMapFCListener(this));
+ AddFieldConfigListener(new FieldDateResolutionFCListener(this));
+ AddFieldConfigListener(new NumericFieldConfigListener(this));
+
+ // Default Values
+ Set(ConfigurationKeys.ALLOW_LEADING_WILDCARD, false); // default in 2.9
+ Set(ConfigurationKeys.ANALYZER, null); //default value 2.4
+ Set(ConfigurationKeys.DEFAULT_OPERATOR, Operator.OR);
+ Set(ConfigurationKeys.PHRASE_SLOP, 0); //default value 2.4
+ Set(ConfigurationKeys.LOWERCASE_EXPANDED_TERMS, true); //default value 2.4
+ Set(ConfigurationKeys.ENABLE_POSITION_INCREMENTS, false); //default value 2.4
+ Set(ConfigurationKeys.FIELD_BOOST_MAP, new LinkedHashMap<string, float?>());
+ Set(ConfigurationKeys.FUZZY_CONFIG, new FuzzyConfig());
+ Set(ConfigurationKeys.LOCALE, CultureInfo.InvariantCulture);
+ Set(ConfigurationKeys.MULTI_TERM_REWRITE_METHOD, MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
+ Set(ConfigurationKeys.FIELD_DATE_RESOLUTION_MAP, new HashMap<string, DateTools.Resolution?>());
+
+ }
+ }
+
+ /**
+ * Class holding keys for StandardQueryNodeProcessorPipeline options.
+ */
+ public sealed class ConfigurationKeys
+ {
+
+ /**
+ * Key used to set whether position increments is enabled
+ *
+ * @see StandardQueryParser#setEnablePositionIncrements(boolean)
+ * @see StandardQueryParser#getEnablePositionIncrements()
+ */
+ public readonly static ConfigurationKey<bool?> ENABLE_POSITION_INCREMENTS = ConfigurationKey.NewInstance<bool?>();
+
+ /**
+ * Key used to set whether expanded terms should be lower-cased
+ *
+ * @see StandardQueryParser#setLowercaseExpandedTerms(boolean)
+ * @see StandardQueryParser#getLowercaseExpandedTerms()
+ */
+ public readonly static ConfigurationKey<bool?> LOWERCASE_EXPANDED_TERMS = ConfigurationKey.NewInstance<bool?>();
+
+ /**
+ * Key used to set whether leading wildcards are supported
+ *
+ * @see StandardQueryParser#setAllowLeadingWildcard(boolean)
+ * @see StandardQueryParser#getAllowLeadingWildcard()
+ */
+ public readonly static ConfigurationKey<bool?> ALLOW_LEADING_WILDCARD = ConfigurationKey.NewInstance<bool?>();
+
+ /**
+ * Key used to set the {@link Analyzer} used for terms found in the query
+ *
+ * @see StandardQueryParser#setAnalyzer(Analyzer)
+ * @see StandardQueryParser#getAnalyzer()
+ */
+ public readonly static ConfigurationKey<Analyzer> ANALYZER = ConfigurationKey.NewInstance<Analyzer>();
+
+ /**
+ * Key used to set the default boolean operator
+ *
+ * @see StandardQueryParser#setDefaultOperator(org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.Operator)
+ * @see StandardQueryParser#getDefaultOperator()
+ */
+ public readonly static ConfigurationKey<Operator?> DEFAULT_OPERATOR = ConfigurationKey.NewInstance<Operator?>();
+
+ /**
+ * Key used to set the default phrase slop
+ *
+ * @see StandardQueryParser#setPhraseSlop(int)
+ * @see StandardQueryParser#getPhraseSlop()
+ */
+ public readonly static ConfigurationKey<int?> PHRASE_SLOP = ConfigurationKey.NewInstance<int?>();
+
+ /**
+ * Key used to set the {@link Locale} used when parsing the query
+ *
+ * @see StandardQueryParser#setLocale(Locale)
+ * @see StandardQueryParser#getLocale()
+ */
+ public readonly static ConfigurationKey<CultureInfo> LOCALE = ConfigurationKey.NewInstance<CultureInfo>();
+
+ public readonly static ConfigurationKey<TimeZoneInfo> TIMEZONE = ConfigurationKey.NewInstance<TimeZoneInfo>();
+
+ /**
+ * Key used to set the {@link RewriteMethod} used when creating queries
+ *
+ * @see StandardQueryParser#setMultiTermRewriteMethod(org.apache.lucene.search.MultiTermQuery.RewriteMethod)
+ * @see StandardQueryParser#getMultiTermRewriteMethod()
+ */
+ public readonly static ConfigurationKey<MultiTermQuery.RewriteMethod> MULTI_TERM_REWRITE_METHOD = ConfigurationKey.NewInstance<MultiTermQuery.RewriteMethod>();
+
+ /**
+ * Key used to set the fields a query should be expanded to when the field
+ * is <code>null</code>
+ *
+ * @see StandardQueryParser#setMultiFields(CharSequence[])
+ * @see StandardQueryParser#getMultiFields(CharSequence[])
+ */
+ public readonly static ConfigurationKey<string[]> MULTI_FIELDS = ConfigurationKey.NewInstance<string[]>();
+
+ /**
+ * Key used to set a field to boost map that is used to set the boost for each field
+ *
+ * @see StandardQueryParser#setFieldsBoost(Map)
+ * @see StandardQueryParser#getFieldsBoost()
+ */
+ public readonly static ConfigurationKey<IDictionary<string, float?>> FIELD_BOOST_MAP = ConfigurationKey.NewInstance<IDictionary<string, float?>>();
+
+ /**
+ * Key used to set a field to {@link Resolution} map that is used
+ * to normalize each date field value.
+ *
+ * @see StandardQueryParser#setDateResolutionMap(Map)
+ * @see StandardQueryParser#getDateResolutionMap()
+ */
+ public readonly static ConfigurationKey<IDictionary<string, DateTools.Resolution?>> FIELD_DATE_RESOLUTION_MAP = ConfigurationKey.NewInstance<IDictionary<string, DateTools.Resolution?>>();
+
+ /**
+ * Key used to set the {@link FuzzyConfig} used to create fuzzy queries.
+ *
+ * @see StandardQueryParser#setFuzzyMinSim(float)
+ * @see StandardQueryParser#setFuzzyPrefixLength(int)
+ * @see StandardQueryParser#getFuzzyMinSim()
+ * @see StandardQueryParser#getFuzzyPrefixLength()
+ */
+ public readonly static ConfigurationKey<FuzzyConfig> FUZZY_CONFIG = ConfigurationKey.NewInstance<FuzzyConfig>();
+
+ /**
+ * Key used to set default {@link Resolution}.
+ *
+ * @see StandardQueryParser#setDateResolution(org.apache.lucene.document.DateTools.Resolution)
+ * @see StandardQueryParser#getDateResolution()
+ */
+ public readonly static ConfigurationKey<DateTools.Resolution> DATE_RESOLUTION = ConfigurationKey.NewInstance<DateTools.Resolution>();
+
+ /**
+ * Key used to set the boost value in {@link FieldConfig} objects.
+ *
+ * @see StandardQueryParser#setFieldsBoost(Map)
+ * @see StandardQueryParser#getFieldsBoost()
+ */
+ public readonly static ConfigurationKey<float?> BOOST = ConfigurationKey.NewInstance<float?>();
+
+ /**
+ * Key used to set a field to its {@link NumericConfig}.
+ *
+ * @see StandardQueryParser#setNumericConfigMap(Map)
+ * @see StandardQueryParser#getNumericConfigMap()
+ */
+ public readonly static ConfigurationKey<NumericConfig> NUMERIC_CONFIG = ConfigurationKey.NewInstance<NumericConfig>();
+
+ /**
+ * Key used to set the {@link NumericConfig} in {@link FieldConfig} for numeric fields.
+ *
+ * @see StandardQueryParser#setNumericConfigMap(Map)
+ * @see StandardQueryParser#getNumericConfigMap()
+ */
+ public readonly static ConfigurationKey<IDictionary<string, NumericConfig>> NUMERIC_CONFIG_MAP = ConfigurationKey.NewInstance<IDictionary<string, NumericConfig>>();
+
+ }
+
+ /**
+ * Boolean Operator: AND or OR
+ */
+ public enum Operator
+ {
+ AND,
+ OR
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/AbstractRangeQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/AbstractRangeQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/AbstractRangeQueryNode.cs
new file mode 100644
index 0000000..85fa044
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/AbstractRangeQueryNode.cs
@@ -0,0 +1,260 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Core.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// This class should be extended by nodes intending to represent range queries.
+ /// </summary>
+ /// <typeparam name="T">the type of the range query bounds (lower and upper)</typeparam>
+ public class AbstractRangeQueryNode<T> : QueryNodeImpl, IRangeQueryNode<IFieldableNode>, IAbstractRangeQueryNode where T : IFieldableNode /*IFieldValuePairQueryNode<?>*/
+ { /*IRangeQueryNode<IFieldValuePairQueryNode<?>>*/
+
+ private bool lowerInclusive, upperInclusive;
+
+ /**
+ * Constructs an {@link AbstractRangeQueryNode}, it should be invoked only by
+ * its extenders.
+ */
+ protected AbstractRangeQueryNode()
+ {
+ SetLeaf(false);
+ Allocate();
+ }
+
+ /**
+ * Gets or Sets the field associated with this node.
+ *
+ * @return the field associated with this node
+ *
+ * @see FieldableNode
+ */
+
+ public virtual string Field
+ {
+ get
+ {
+ string field = null;
+ T lower = (T)LowerBound;
+ T upper = (T)UpperBound;
+
+ if (lower != null)
+ {
+ field = lower.Field;
+
+ }
+ else if (upper != null)
+ {
+ field = upper.Field;
+ }
+
+ return field;
+ }
+ set
+ {
+ T lower = (T)LowerBound;
+ T upper = (T)UpperBound;
+
+ if (lower != null)
+ {
+ lower.Field = value;
+ }
+
+ if (upper != null)
+ {
+ upper.Field = value;
+ }
+ }
+ }
+
+ /**
+ * Sets the field associated with this node.
+ *
+ * @param fieldName the field associated with this node
+ */
+ // @Override
+ //public void setField(CharSequence fieldName)
+ // {
+ // T lower = getLowerBound();
+ // T upper = getUpperBound();
+
+ // if (lower != null)
+ // {
+ // lower.setField(fieldName);
+ // }
+
+ // if (upper != null)
+ // {
+ // upper.setField(fieldName);
+ // }
+
+ // }
+
+ /**
+ * Returns the lower bound node.
+ *
+ * @return the lower bound node.
+ */
+ public virtual IFieldableNode LowerBound
+ {
+ get { return (IFieldableNode)GetChildren()[0]; }
+ }
+
+ /**
+ * Returns the upper bound node.
+ *
+ * @return the upper bound node.
+ */
+ public virtual IFieldableNode UpperBound
+ {
+ get { return (IFieldableNode)GetChildren()[1]; }
+ }
+
+ /**
+ * Returns whether the lower bound is inclusive or exclusive.
+ *
+ * @return <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ */
+
+ public virtual bool IsLowerInclusive
+ {
+ get { return lowerInclusive; }
+ }
+
+ /**
+ * Returns whether the upper bound is inclusive or exclusive.
+ *
+ * @return <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ */
+ public virtual bool IsUpperInclusive
+ {
+ get { return upperInclusive; }
+ }
+
+ /**
+ * Sets the lower and upper bounds.
+ *
+ * @param lower the lower bound, <code>null</code> if lower bound is open
+ * @param upper the upper bound, <code>null</code> if upper bound is open
+ * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ *
+ * @see #getLowerBound()
+ * @see #getUpperBound()
+ * @see #isLowerInclusive()
+ * @see #isUpperInclusive()
+ */
+ public void SetBounds(T lower, T upper, bool lowerInclusive,
+ bool upperInclusive)
+ {
+
+ if (lower != null && upper != null)
+ {
+ string lowerField = StringUtils.ToString(lower.Field);
+ string upperField = StringUtils.ToString(upper.Field);
+
+ if ((upperField != null || lowerField != null)
+ && ((upperField != null && !upperField.Equals(lowerField)) || !lowerField
+ .Equals(upperField)))
+ {
+ throw new ArgumentException(
+ "lower and upper bounds should have the same field name!");
+ }
+
+ this.lowerInclusive = lowerInclusive;
+ this.upperInclusive = upperInclusive;
+
+ List<IQueryNode> children = new List<IQueryNode>(2);
+ children.Add(lower);
+ children.Add(upper);
+
+ Set(children);
+
+ }
+
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ T lower = (T)LowerBound;
+ T upper = (T)UpperBound;
+
+ if (lowerInclusive)
+ {
+ sb.Append('[');
+
+ }
+ else
+ {
+ sb.Append('{');
+ }
+
+ if (lower != null)
+ {
+ sb.Append(lower.ToQueryString(escapeSyntaxParser));
+
+ }
+ else
+ {
+ sb.Append("...");
+ }
+
+ sb.Append(' ');
+
+ if (upper != null)
+ {
+ sb.Append(upper.ToQueryString(escapeSyntaxParser));
+
+ }
+ else
+ {
+ sb.Append("...");
+ }
+
+ if (upperInclusive)
+ {
+ sb.Append(']');
+
+ }
+ else
+ {
+ sb.Append('}');
+ }
+
+ return sb.ToString();
+
+ }
+
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder("<").Append(GetType().AssemblyQualifiedName);
+ sb.Append(" lowerInclusive=").Append(IsLowerInclusive);
+ sb.Append(" upperInclusive=").Append(IsUpperInclusive);
+ sb.Append(">\n\t");
+ sb.Append(UpperBound).Append("\n\t");
+ sb.Append(LowerBound).Append("\n");
+ sb.Append("</").Append(GetType().AssemblyQualifiedName).Append(">\n");
+
+ return sb.ToString();
+
+ }
+ }
+
+ /// <summary>
+ /// LUCENENET specific interface used to identify
+ /// an AbstractRangeQueryNode without referring to
+ /// its generic closing type
+ /// </summary>
+ public interface IAbstractRangeQueryNode
+ { }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/BooleanModifierNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/BooleanModifierNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/BooleanModifierNode.cs
new file mode 100644
index 0000000..31f7853
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/BooleanModifierNode.cs
@@ -0,0 +1,23 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// A {@link BooleanModifierNode} has the same behaviour as
+ /// {@link ModifierQueryNode}, it only indicates that this modifier was added by
+ /// {@link GroupQueryNodeProcessor} and not by the user.
+ /// </summary>
+ /// <seealso cref="ModifierQueryNode"/>
+ public class BooleanModifierNode : ModifierQueryNode
+ {
+ public BooleanModifierNode(IQueryNode node, Modifier mod)
+ : base(node, mod)
+ {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/MultiPhraseQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/MultiPhraseQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/MultiPhraseQueryNode.cs
new file mode 100644
index 0000000..f111313
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/MultiPhraseQueryNode.cs
@@ -0,0 +1,104 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// A {@link MultiPhraseQueryNode} indicates that its children should be used to
+ /// build a {@link MultiPhraseQuery} instead of {@link PhraseQuery}.
+ /// </summary>
+ public class MultiPhraseQueryNode : QueryNodeImpl, IFieldableNode
+ {
+ public MultiPhraseQueryNode()
+ {
+ SetLeaf(false);
+ Allocate();
+
+ }
+
+ public override string ToString()
+ {
+ if (GetChildren() == null || GetChildren().Count == 0)
+ return "<multiPhrase/>";
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<multiPhrase>");
+ foreach (IQueryNode child in GetChildren())
+ {
+ sb.Append("\n");
+ sb.Append(child.ToString());
+ }
+ sb.Append("\n</multiPhrase>");
+ return sb.ToString();
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (GetChildren() == null || GetChildren().Count == 0)
+ return "";
+
+ StringBuilder sb = new StringBuilder();
+ string filler = "";
+ foreach (IQueryNode child in GetChildren())
+ {
+ sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+ filler = ",";
+ }
+
+ return "[MTP[" + sb.ToString() + "]]";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ MultiPhraseQueryNode clone = (MultiPhraseQueryNode)base.CloneTree();
+
+ // nothing to do
+
+ return clone;
+ }
+
+
+ public virtual string Field
+ {
+ get
+ {
+ IList<IQueryNode> children = GetChildren();
+
+ if (children == null || children.Count == 0)
+ {
+ return null;
+
+ }
+ else
+ {
+ return ((IFieldableNode)children[0]).Field;
+ }
+ }
+ set
+ {
+ IList<IQueryNode> children = GetChildren();
+
+ if (children != null)
+ {
+
+ foreach (IQueryNode child in children)
+ {
+
+ if (child is IFieldableNode)
+ {
+ ((IFieldableNode)child).Field = value;
+ }
+
+ }
+ }
+ }
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/NumericQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/NumericQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/NumericQueryNode.cs
new file mode 100644
index 0000000..0375858
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/NumericQueryNode.cs
@@ -0,0 +1,146 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// This query node represents a field query that holds a numeric value. It is
+ /// similar to {@link FieldQueryNode}, however the {@link #getValue()} returns a
+ /// {@link Number}.
+ /// </summary>
+ /// <seealso cref="NumericConfig"/>
+ public class NumericQueryNode : QueryNodeImpl, IFieldValuePairQueryNode<object> // LUCENENET TODO: Can we use Decimal??
+ {
+ private /*NumberFormat*/ string numberFormat;
+
+ private string field;
+
+ private /*Number*/ object value;
+
+ /**
+ * Creates a {@link NumericQueryNode} object using the given field,
+ * {@link Number} value and {@link NumberFormat} used to convert the value to
+ * {@link String}.
+ *
+ * @param field the field associated with this query node
+ * @param value the value hold by this node
+ * @param numberFormat the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public NumericQueryNode(string field, /*Number*/ object value,
+ /*NumberFormat*/ string numberFormat)
+ : base()
+ {
+ SetNumberFormat(numberFormat);
+ Field = field;
+ Value = value;
+
+ }
+
+ /**
+ * Returns the field associated with this node.
+ *
+ * @return the field associated with this node
+ */
+
+ public virtual string Field
+ {
+ get { return this.field; }
+ set { this.field = value; }
+ }
+
+ /**
+ * Sets the field associated with this node.
+ *
+ * @param fieldName the field associated with this node
+ */
+ // @Override
+ //public void setField(CharSequence fieldName)
+ // {
+ // this.field = fieldName;
+ // }
+
+ /**
+ * This method is used to get the value converted to {@link String} and
+ * escaped using the given {@link EscapeQuerySyntax}.
+ *
+ * @param escaper the {@link EscapeQuerySyntax} used to escape the value {@link String}
+ *
+ * @return the value converte to {@link String} and escaped
+ */
+ protected string GetTermEscaped(IEscapeQuerySyntax escaper)
+ {
+ return escaper.Escape(new StringCharSequenceWrapper(string.Format(numberFormat, this.value)) /*numberFormat.format(this.value)*/,
+ CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.NORMAL).ToString();
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (IsDefaultField(this.field))
+ {
+ return GetTermEscaped(escapeSyntaxParser);
+ }
+ else
+ {
+ return this.field + ":" + GetTermEscaped(escapeSyntaxParser);
+ }
+ }
+
+ /**
+ * Sets the {@link NumberFormat} used to convert the value to {@link String}.
+ *
+ * @param format the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public void SetNumberFormat(/*NumberFormat*/ string format)
+ {
+ this.numberFormat = format;
+ }
+
+ /**
+ * Returns the {@link NumberFormat} used to convert the value to {@link String}.
+ *
+ * @return the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public /*NumberFormat*/ string GetNumberFormat()
+ {
+ return this.numberFormat;
+ }
+
+ /**
+ * Returns the numeric value as {@link Number}.
+ *
+ * @return the numeric value
+ */
+
+ public virtual object Value
+ {
+ get { return value; }
+ set { this.value = value; }
+ }
+
+ /**
+ * Sets the numeric value.
+ *
+ * @param value the numeric value
+ */
+ // @Override
+ //public void setValue(Number value)
+ // {
+ // this.value = value;
+ // }
+
+
+ public override string ToString()
+ {
+ return "<numeric field='" + this.field + "' number='"
+ + string.Format(numberFormat, value) + "'/>";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/NumericRangeQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/NumericRangeQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/NumericRangeQueryNode.cs
new file mode 100644
index 0000000..11dbffc
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/NumericRangeQueryNode.cs
@@ -0,0 +1,160 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core;
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using Lucene.Net.QueryParsers.Flexible.Standard.Config;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static Lucene.Net.Documents.FieldType;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// This query node represents a range query composed by {@link NumericQueryNode}
+ /// bounds, which means the bound values are {@link Number}s.
+ /// </summary>
+ /// <seealso cref="NumericQueryNode"/>
+ /// <seealso cref="AbstractRangeQueryNode{T}"/>
+ public class NumericRangeQueryNode : AbstractRangeQueryNode<NumericQueryNode>
+ {
+ public NumericConfig numericConfig;
+
+ /**
+ * Constructs a {@link NumericRangeQueryNode} object using the given
+ * {@link NumericQueryNode} as its bounds and {@link NumericConfig}.
+ *
+ * @param lower the lower bound
+ * @param upper the upper bound
+ * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ * @param numericConfig the {@link NumericConfig} that represents associated with the upper and lower bounds
+ *
+ * @see #setBounds(NumericQueryNode, NumericQueryNode, boolean, boolean, NumericConfig)
+ */
+ public NumericRangeQueryNode(NumericQueryNode lower, NumericQueryNode upper,
+ bool lowerInclusive, bool upperInclusive, NumericConfig numericConfig)
+ {
+ SetBounds(lower, upper, lowerInclusive, upperInclusive, numericConfig);
+ }
+
+ private static NumericType GetNumericDataType(/*Number*/ object number)
+ {
+
+ if (number is long)
+ {
+ return NumericType.LONG;
+ }
+ else if (number is int)
+ {
+ return NumericType.INT;
+ }
+ else if (number is double)
+ {
+ return NumericType.DOUBLE;
+ }
+ else if (number is float)
+ {
+ return NumericType.FLOAT;
+ }
+ else
+ {
+ throw new QueryNodeException(
+ new MessageImpl(
+ QueryParserMessages.NUMBER_CLASS_NOT_SUPPORTED_BY_NUMERIC_RANGE_QUERY,
+ number.GetType()));
+ }
+
+ }
+
+ /**
+ * Sets the upper and lower bounds of this range query node and the
+ * {@link NumericConfig} associated with these bounds.
+ *
+ * @param lower the lower bound
+ * @param upper the upper bound
+ * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ * @param numericConfig the {@link NumericConfig} that represents associated with the upper and lower bounds
+ *
+ */
+ public virtual void SetBounds(NumericQueryNode lower, NumericQueryNode upper,
+ bool lowerInclusive, bool upperInclusive, NumericConfig numericConfig)
+ {
+
+ if (numericConfig == null)
+ {
+ throw new ArgumentException("numericConfig cannot be null!");
+ }
+
+ NumericType? lowerNumberType, upperNumberType;
+
+ if (lower != null && lower.Value != null)
+ {
+ lowerNumberType = GetNumericDataType(lower.Value);
+ }
+ else
+ {
+ lowerNumberType = null;
+ }
+
+ if (upper != null && upper.Value != null)
+ {
+ upperNumberType = GetNumericDataType(upper.Value);
+ }
+ else
+ {
+ upperNumberType = null;
+ }
+
+ if (lowerNumberType != null
+ && !lowerNumberType.Equals(numericConfig.GetType()))
+ {
+ throw new ArgumentException(
+ "lower value's type should be the same as numericConfig type: "
+ + lowerNumberType + " != " + numericConfig.GetType());
+ }
+
+ if (upperNumberType != null
+ && !upperNumberType.Equals(numericConfig.GetType()))
+ {
+ throw new ArgumentException(
+ "upper value's type should be the same as numericConfig type: "
+ + upperNumberType + " != " + numericConfig.GetType());
+ }
+
+ base.SetBounds(lower, upper, lowerInclusive, upperInclusive);
+ this.numericConfig = numericConfig;
+
+ }
+
+ /**
+ * Returns the {@link NumericConfig} associated with the lower and upper bounds.
+ *
+ * @return the {@link NumericConfig} associated with the lower and upper bounds
+ */
+ public NumericConfig GetNumericConfig()
+ {
+ return this.numericConfig;
+ }
+
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder("<numericRange lowerInclusive='");
+
+ sb.Append(IsLowerInclusive).Append("' upperInclusive='").Append(
+ IsUpperInclusive).Append(
+ "' precisionStep='" + numericConfig.GetPrecisionStep()).Append(
+ "' type='" + numericConfig.GetType()).Append("'>\n");
+
+ sb.Append(LowerBound).Append('\n');
+ sb.Append(UpperBound).Append('\n');
+ sb.Append("</numericRange>");
+
+ return sb.ToString();
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/PrefixWildcardQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/PrefixWildcardQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/PrefixWildcardQueryNode.cs
new file mode 100644
index 0000000..d76bafe
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/PrefixWildcardQueryNode.cs
@@ -0,0 +1,74 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// A {@link PrefixWildcardQueryNode} represents wildcardquery that matches abc*
+ /// or *. This does not apply to phrases, this is a special case on the original
+ /// lucene parser. TODO: refactor the code to remove this special case from the
+ /// parser. and probably do it on a Processor
+ /// </summary>
+ public class PrefixWildcardQueryNode : WildcardQueryNode
+ {
+ /**
+ * @param field
+ * - field name
+ * @param text
+ * - value including the wildcard
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ // LUCENENET specific overload for passing text as string
+ public PrefixWildcardQueryNode(string field, string text,
+ int begin, int end)
+ : this(field, new StringCharSequenceWrapper(text), begin, end)
+ {
+ }
+
+ /**
+ * @param field
+ * - field name
+ * @param text
+ * - value including the wildcard
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ public PrefixWildcardQueryNode(string field, ICharSequence text,
+ int begin, int end)
+ : base(field, text, begin, end)
+ {
+ }
+
+ public PrefixWildcardQueryNode(FieldQueryNode fqn)
+ : this(fqn.Field, fqn.Text, fqn.GetBegin(), fqn.GetEnd())
+ {
+ }
+
+
+ public override string ToString()
+ {
+ return "<prefixWildcard field='" + this.field + "' term='" + this.text
+ + "'/>";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ PrefixWildcardQueryNode clone = (PrefixWildcardQueryNode)base.CloneTree();
+
+ // nothing to do here
+
+ return clone;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/RegexpQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/RegexpQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/RegexpQueryNode.cs
new file mode 100644
index 0000000..58b38a0
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/RegexpQueryNode.cs
@@ -0,0 +1,99 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// A {@link RegexpQueryNode} represents {@link RegexpQuery} query Examples: /[a-z]|[0-9]/
+ /// </summary>
+ public class RegexpQueryNode : QueryNodeImpl, ITextableQueryNode, IFieldableNode
+ {
+ private ICharSequence text;
+ private string field;
+
+ /**
+ * @param field
+ * - field name
+ * @param text
+ * - value that contains a regular expression
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ // LUCENENET specific overload for passing text as string
+ public RegexpQueryNode(string field, string text, int begin,
+ int end)
+ : this(field, new StringCharSequenceWrapper(text), begin, end)
+ {
+ }
+
+ /**
+ * @param field
+ * - field name
+ * @param text
+ * - value that contains a regular expression
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ public RegexpQueryNode(string field, ICharSequence text, int begin,
+ int end)
+ {
+ this.field = field;
+ this.text = text.SubSequence(begin, end);
+ }
+
+ public BytesRef TextToBytesRef()
+ {
+ return new BytesRef(text.ToString());
+ }
+
+
+ public override string ToString()
+ {
+ return "<regexp field='" + this.field + "' term='" + this.text + "'/>";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ RegexpQueryNode clone = (RegexpQueryNode)base.CloneTree();
+ clone.field = this.field;
+ clone.text = this.text;
+ return clone;
+ }
+
+
+ public virtual ICharSequence Text
+ {
+ get { return text; }
+ set { this.text = value; }
+ }
+
+ public virtual string Field
+ {
+ get { return field; }
+ set { this.field = value; }
+ }
+
+ public virtual string FieldAsString
+ {
+ get { return field.ToString(); }
+ }
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ return IsDefaultField(field) ? "/" + text + "/" : field + ":/" + text + "/";
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/StandardBooleanQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/StandardBooleanQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/StandardBooleanQueryNode.cs
new file mode 100644
index 0000000..de38d03
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/StandardBooleanQueryNode.cs
@@ -0,0 +1,32 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// A {@link StandardBooleanQueryNode} has the same behavior as
+ /// {@link BooleanQueryNode}. It only indicates if the coord should be enabled or
+ /// not for this boolean query.
+ /// </summary>
+ /// <seealso cref="Similarity#coord(int, int)"/>
+ /// <seealso cref="BooleanQuery"/>
+ public class StandardBooleanQueryNode : BooleanQueryNode
+ {
+ private bool disableCoord;
+
+ public StandardBooleanQueryNode(IList<IQueryNode> clauses, bool disableCoord)
+ : base(clauses)
+ {
+ this.disableCoord = disableCoord;
+ }
+
+ public bool IsDisableCoord
+ {
+ get { return this.disableCoord; }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/TermRangeQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/TermRangeQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/TermRangeQueryNode.cs
new file mode 100644
index 0000000..a4a35c1
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/TermRangeQueryNode.cs
@@ -0,0 +1,33 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// This query node represents a range query composed by {@link FieldQueryNode}
+ /// bounds, which means the bound values are strings.
+ /// </summary>
+ /// <seealso cref="FieldQueryNode"/>
+ /// <seealso cref="AbstractRangeQueryNode{T}"/>
+ public class TermRangeQueryNode : AbstractRangeQueryNode<FieldQueryNode>
+ {
+ /**
+ * Constructs a {@link TermRangeQueryNode} object using the given
+ * {@link FieldQueryNode} as its bounds.
+ *
+ * @param lower the lower bound
+ * @param upper the upper bound
+ * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ */
+ public TermRangeQueryNode(FieldQueryNode lower, FieldQueryNode upper,
+ bool lowerInclusive, bool upperInclusive)
+ {
+ SetBounds(lower, upper, lowerInclusive, upperInclusive);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/WildcardQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/WildcardQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/WildcardQueryNode.cs
new file mode 100644
index 0000000..4ff25eb
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Nodes/WildcardQueryNode.cs
@@ -0,0 +1,84 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Nodes
+{
+ /// <summary>
+ /// A {@link WildcardQueryNode} represents wildcard query This does not apply to
+ /// phrases. Examples: a*b*c Fl?w? m?ke*g
+ /// </summary>
+ public class WildcardQueryNode : FieldQueryNode
+ {
+ /**
+ * @param field
+ * - field name
+ * @param text
+ * - value that contains one or more wild card characters (? or *)
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ // LUCENENET specific overload for passing text as string
+ public WildcardQueryNode(string field, string text, int begin,
+ int end)
+ : this(field, new StringCharSequenceWrapper(text), begin, end)
+ {
+ }
+
+ /**
+ * @param field
+ * - field name
+ * @param text
+ * - value that contains one or more wild card characters (? or *)
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ public WildcardQueryNode(string field, ICharSequence text, int begin,
+ int end)
+ : base(field, text, begin, end)
+ {
+ }
+
+ public WildcardQueryNode(FieldQueryNode fqn)
+ : this(fqn.Field, fqn.Text, fqn.GetBegin(), fqn.GetEnd())
+ {
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escaper)
+ {
+ if (IsDefaultField(this.field))
+ {
+ return this.text.ToString();
+ }
+ else
+ {
+ return this.field + ":" + this.text;
+ }
+ }
+
+ public override string ToString()
+ {
+ return "<wildcard field='" + this.field + "' term='" + this.text + "'/>";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ WildcardQueryNode clone = (WildcardQueryNode)base.CloneTree();
+
+ // nothing to do here
+
+ return clone;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Standard/Parser/CharStream.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Standard/Parser/CharStream.cs b/src/Lucene.Net.QueryParser/Flexible/Standard/Parser/CharStream.cs
new file mode 100644
index 0000000..0e392a2
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Standard/Parser/CharStream.cs
@@ -0,0 +1,117 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Standard.Parser
+{
+ /// <summary>
+ /// This interface describes a character stream that maintains line and
+ /// column number positions of the characters. It also has the capability
+ /// to backup the stream to some extent. An implementation of this
+ /// interface is used in the TokenManager implementation generated by
+ /// JavaCCParser.
+ ///
+ /// All the methods except backup can be implemented in any fashion. backup
+ /// needs to be implemented correctly for the correct operation of the lexer.
+ /// Rest of the methods are all used to get information like line number,
+ /// column number and the String that constitutes a token and are not used
+ /// by the lexer. Hence their implementation won't affect the generated lexer's
+ /// operation.
+ /// </summary>
+ public interface ICharStream
+ {
+ /**
+ * Returns the next character from the selected input. The method
+ * of selecting the input is the responsibility of the class
+ * implementing this interface. Can throw any java.io.IOException.
+ */
+ char ReadChar();
+
+ [Obsolete]
+ /**
+ * Returns the column position of the character last read.
+ * @deprecated
+ * @see #getEndColumn
+ */
+ int GetColumn();
+
+ [Obsolete]
+ /**
+ * Returns the line number of the character last read.
+ * @deprecated
+ * @see #getEndLine
+ */
+ int GetLine();
+
+ /**
+ * Returns the column number of the last character for current token (being
+ * matched after the last call to BeginTOken).
+ */
+ int GetEndColumn();
+
+ /**
+ * Returns the line number of the last character for current token (being
+ * matched after the last call to BeginTOken).
+ */
+ int GetEndLine();
+
+ /**
+ * Returns the column number of the first character for current token (being
+ * matched after the last call to BeginTOken).
+ */
+ int GetBeginColumn();
+
+ /**
+ * Returns the line number of the first character for current token (being
+ * matched after the last call to BeginTOken).
+ */
+ int GetBeginLine();
+
+ /**
+ * Backs up the input stream by amount steps. Lexer calls this method if it
+ * had already read some characters, but could not use them to match a
+ * (longer) token. So, they will be used again as the prefix of the next
+ * token and it is the implemetation's responsibility to do this right.
+ */
+ void BackUp(int amount);
+
+ /**
+ * Returns the next character that marks the beginning of the next token.
+ * All characters must remain in the buffer between two successive calls
+ * to this method to implement backup correctly.
+ */
+ char BeginToken();
+
+ /**
+ * Returns a string made up of characters from the marked token beginning
+ * to the current buffer position. Implementations have the choice of returning
+ * anything that they want to. For example, for efficiency, one might decide
+ * to just return null, which is a valid implementation.
+ */
+ string GetImage();
+
+ /**
+ * Returns an array of characters that make up the suffix of length 'len' for
+ * the currently matched token. This is used to build up the matched string
+ * for use in actions in the case of MORE. A simple and inefficient
+ * implementation of this is as follows :
+ *
+ * {
+ * String t = GetImage();
+ * return t.substring(t.length() - len, t.length()).toCharArray();
+ * }
+ */
+ char[] GetSuffix(int len);
+
+ /**
+ * The lexer calls this function to indicate that it is done with the stream
+ * and hence implementations can free any resources held by this class.
+ * Again, the body of this function can be just empty and it will not
+ * affect the lexer's operation.
+ */
+ void Done();
+
+ }
+}