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:46 UTC
[11/58] lucenenet git commit: WIP on QueryParsers.Flexible
WIP on QueryParsers.Flexible
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/c83be6be
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/c83be6be
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/c83be6be
Branch: refs/heads/master
Commit: c83be6be537d1f9169f74308d854c11ed6026172
Parents: e8735ed
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Mon Nov 28 22:15:35 2016 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Mon Nov 28 22:15:35 2016 +0700
----------------------------------------------------------------------
src/Lucene.Net.Core/Document/FieldType.cs | 2 +-
src/Lucene.Net.Core/Support/StringSupport.cs | 10 +
.../Flexible/Core/Builders/QueryBuilder.cs | 37 +
.../Flexible/Core/Builders/QueryTreeBuilder.cs | 252 +++
.../Flexible/Core/Config/AbstractQueryConfig.cs | 114 ++
.../Flexible/Core/Config/ConfigurationKey.cs | 45 +
.../Flexible/Core/Config/FieldConfig.cs | 50 +
.../Flexible/Core/Config/FieldConfigListener.cs | 24 +
.../Flexible/Core/Config/QueryConfigHandler.cs | 69 +
.../Core/Messages/QueryParserMessages.cs | 50 +
.../Flexible/Core/Nodes/AndQueryNode.cs | 69 +
.../Flexible/Core/Nodes/AnyQueryNode.cs | 151 ++
.../Flexible/Core/Nodes/BooleanQueryNode.cs | 77 +
.../Flexible/Core/Nodes/BoostQueryNode.cs | 113 ++
.../Flexible/Core/Nodes/DeletedQueryNode.cs | 43 +
.../Flexible/Core/Nodes/FieldQueryNode.cs | 241 +++
.../Core/Nodes/FieldValuePairQueryNode.cs | 19 +
.../Flexible/Core/Nodes/FieldableNode.cs | 38 +
.../Flexible/Core/Nodes/FuzzyQueryNode.cs | 119 ++
.../Flexible/Core/Nodes/GroupQueryNode.cs | 73 +
.../Core/Nodes/MatchAllDocsQueryNode.cs | 43 +
.../Flexible/Core/Nodes/MatchNoDocsQueryNode.cs | 25 +
.../Flexible/Core/Nodes/ModifierQueryNode.cs | 172 +++
.../Core/Nodes/NoTokenFoundQueryNode.cs | 42 +
.../Flexible/Core/Nodes/OpaqueQueryNode.cs | 75 +
.../Flexible/Core/Nodes/OrQueryNode.cs | 68 +
.../Flexible/Core/Nodes/PathQueryNode.cs | 233 +++
.../Flexible/Core/Nodes/PhraseSlopQueryNode.cs | 106 ++
.../Flexible/Core/Nodes/ProximityQueryNode.cs | 288 ++++
.../Flexible/Core/Nodes/QueryNode.cs | 84 +
.../Flexible/Core/Nodes/QueryNodeImpl.cs | 292 ++++
.../Flexible/Core/Nodes/QuotedFieldQueryNode.cs | 77 +
.../Flexible/Core/Nodes/RangeQueryNode.cs | 32 +
.../Flexible/Core/Nodes/SlopQueryNode.cs | 116 ++
.../Flexible/Core/Nodes/TextableQueryNode.cs | 17 +
.../Core/Nodes/TokenizedPhraseQueryNode.cs | 103 ++
.../Flexible/Core/Nodes/ValueQueryNode.cs | 18 +
.../Flexible/Core/Parser/EscapeQuerySyntax.cs | 39 +
.../Flexible/Core/Parser/SyntaxParser.cs | 23 +
.../NoChildOptimizationQueryNodeProcessor.cs | 73 +
.../Core/Processors/QueryNodeProcessor.cs | 61 +
.../Core/Processors/QueryNodeProcessorImpl.cs | 202 +++
.../Processors/QueryNodeProcessorPipeline.cs | 425 ++++++
.../RemoveDeletedQueryNodesProcessor.cs | 102 ++
.../Flexible/Core/QueryNodeError.cs | 64 +
.../Flexible/Core/QueryNodeException.cs | 75 +
.../Flexible/Core/QueryNodeParseException.cs | 117 ++
.../Flexible/Core/QueryParserHelper.cs | 260 ++++
.../Flexible/Core/Util/QueryNodeOperation.cs | 85 ++
.../Flexible/Core/Util/StringUtils.cs | 26 +
.../Flexible/Core/Util/UnescapedCharSequence.cs | 188 +++
.../Flexible/Messages/Message.cs | 21 +
.../Flexible/Messages/MessageImpl.cs | 71 +
.../Flexible/Messages/NLS.cs | 292 ++++
.../Flexible/Messages/NLSException.cs | 24 +
.../Precedence/PrecedenceQueryParser.cs | 41 +
.../BooleanModifiersQueryNodeProcessor.cs | 127 ++
.../PrecedenceQueryNodeProcessorPipeline.cs | 46 +
.../Standard/Builders/AnyQueryNodeBuilder.cs | 80 +
.../Builders/BooleanQueryNodeBuilder.cs | 112 ++
.../Standard/Builders/BoostQueryNodeBuilder.cs | 51 +
.../Standard/Builders/DummyQueryNodeBuilder.cs | 46 +
.../Standard/Builders/FieldQueryNodeBuilder.cs | 40 +
.../Standard/Builders/FuzzyQueryNodeBuilder.cs | 48 +
.../Standard/Builders/GroupQueryNodeBuilder.cs | 42 +
.../Builders/MatchAllDocsQueryNodeBuilder.cs | 52 +
.../Builders/MatchNoDocsQueryNodeBuilder.cs | 53 +
.../Builders/ModifierQueryNodeBuilder.cs | 42 +
.../Builders/MultiPhraseQueryNodeBuilder.cs | 83 +
.../Builders/NumericRangeQueryNodeBuilder.cs | 91 ++
.../Standard/Builders/PhraseQueryNodeBuilder.cs | 59 +
.../Builders/PrefixWildcardQueryNodeBuilder.cs | 52 +
.../Standard/Builders/RegexpQueryNodeBuilder.cs | 51 +
.../Standard/Builders/SlopQueryNodeBuilder.cs | 55 +
.../Builders/StandardBooleanQueryNodeBuilder.cs | 112 ++
.../Standard/Builders/StandardQueryBuilder.cs | 22 +
.../Builders/StandardQueryTreeBuilder.cs | 60 +
.../Builders/TermRangeQueryNodeBuilder.cs | 69 +
.../Builders/WildcardQueryNodeBuilder.cs | 51 +
.../Standard/CommonQueryParserConfiguration.cs | 2 +-
.../Standard/Config/FieldBoostMapFCListener.cs | 47 +
.../Config/FieldDateResolutionFCListener.cs | 55 +
.../Flexible/Standard/Config/FuzzyConfig.cs | 41 +
.../Standard/Config/NumberDateFormat.cs | 60 +
.../Flexible/Standard/Config/NumericConfig.cs | 155 ++
.../Config/NumericFieldConfigListener.cs | 59 +
.../Config/StandardQueryConfigHandler.cs | 200 +++
.../Standard/Nodes/AbstractRangeQueryNode.cs | 260 ++++
.../Standard/Nodes/BooleanModifierNode.cs | 23 +
.../Standard/Nodes/MultiPhraseQueryNode.cs | 104 ++
.../Flexible/Standard/Nodes/NumericQueryNode.cs | 146 ++
.../Standard/Nodes/NumericRangeQueryNode.cs | 160 ++
.../Standard/Nodes/PrefixWildcardQueryNode.cs | 74 +
.../Flexible/Standard/Nodes/RegexpQueryNode.cs | 99 ++
.../Standard/Nodes/StandardBooleanQueryNode.cs | 32 +
.../Standard/Nodes/TermRangeQueryNode.cs | 33 +
.../Standard/Nodes/WildcardQueryNode.cs | 84 +
.../Flexible/Standard/Parser/CharStream.cs | 117 ++
.../Standard/Parser/EscapeQuerySyntaxImpl.cs | 438 ++++++
.../Flexible/Standard/Parser/FastCharStream.cs | 140 ++
.../Flexible/Standard/Parser/ParseException.cs | 212 +++
.../Standard/Parser/StandardSyntaxParser.cs | 1250 +++++++++++++++
.../Parser/StandardSyntaxParserConstants.cs | 129 ++
.../Parser/StandardSyntaxParserTokenManager.cs | 959 ++++++++++++
.../Flexible/Standard/Parser/Token.cs | 135 ++
.../Flexible/Standard/Parser/TokenMgrError.cs | 164 ++
.../Processors/AllowLeadingWildcardProcessor.cs | 100 ++
.../Processors/AnalyzerQueryNodeProcessor.cs | 435 ++++++
.../BooleanQuery2ModifierNodeProcessor.cs | 210 +++
...SingleChildOptimizationQueryNodeProcessor.cs | 79 +
.../Processors/BoostQueryNodeProcessor.cs | 74 +
.../DefaultPhraseSlopQueryNodeProcessor.cs | 112 ++
.../Processors/FuzzyQueryNodeProcessor.cs | 75 +
.../Processors/GroupQueryNodeProcessor.cs | 240 +++
.../LowercaseExpandedTermsQueryNodeProcessor.cs | 87 ++
.../MatchAllDocsQueryNodeProcessor.cs | 62 +
.../Processors/MultiFieldQueryNodeProcessor.cs | 130 ++
.../MultiTermRewriteMethodProcessor.cs | 64 +
.../Processors/NumericQueryNodeProcessor.cs | 150 ++
.../NumericRangeQueryNodeProcessor.cs | 164 ++
.../Processors/OpenRangeQueryNodeProcessor.cs | 69 +
.../Processors/PhraseSlopQueryNodeProcessor.cs | 61 +
.../RemoveEmptyNonLeafQueryNodeProcessor.cs | 110 ++
.../StandardQueryNodeProcessorPipeline.cs | 54 +
.../Processors/TermRangeQueryNodeProcessor.cs | 164 ++
.../Processors/WildcardQueryNodeProcessor.cs | 131 ++
.../Flexible/Standard/QueryParserUtil.cs | 202 +++
.../Flexible/Standard/StandardQueryParser.cs | 651 ++++++++
.../Lucene.Net.QueryParser.csproj | 136 ++
.../Properties/Resources.Designer.cs | 225 +++
.../Properties/Resources.resx | 177 +++
.../Core/Builders/TestQueryTreeBuilder.cs | 60 +
.../Flexible/Core/Nodes/TestQueryNode.cs | 60 +
.../Messages/MessagesTestBundle.Designer.cs | 63 +
.../Flexible/Messages/MessagesTestBundle.cs | 12 +
.../Messages/MessagesTestBundle.ja-JP.resx | 126 ++
.../Flexible/Messages/MessagesTestBundle.resx | 126 ++
.../Flexible/Messages/TestNLS.cs | 121 ++
.../Precedence/TestPrecedenceQueryParser.cs | 727 +++++++++
.../Flexible/Spans/SpanOrQueryNodeBuilder.cs | 50 +
.../Flexible/Spans/SpanTermQueryNodeBuilder.cs | 40 +
.../Flexible/Spans/SpansQueryConfigHandler.cs | 33 +
.../Flexible/Spans/SpansQueryTreeBuilder.cs | 44 +
.../Spans/SpansValidatorQueryNodeProcessor.cs | 55 +
.../Flexible/Spans/TestSpanQueryParser.cs | 238 +++
.../Spans/TestSpanQueryParserSimpleSample.cs | 113 ++
.../Flexible/Spans/UniqueFieldAttribute.cs | 22 +
.../Flexible/Spans/UniqueFieldAttributeImpl.cs | 88 ++
.../Spans/UniqueFieldQueryNodeProcessor.cs | 68 +
.../Standard/TestMultiAnalyzerQPHelper.cs | 267 ++++
.../Flexible/Standard/TestMultiFieldQPHelper.cs | 409 +++++
.../Flexible/Standard/TestNumericQueryParser.cs | 523 +++++++
.../Flexible/Standard/TestQPHelper.cs | 1443 ++++++++++++++++++
.../Flexible/Standard/TestStandardQP.cs | 235 +++
.../Lucene.Net.Tests.QueryParser.csproj | 35 +
155 files changed, 21116 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.Core/Document/FieldType.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Document/FieldType.cs b/src/Lucene.Net.Core/Document/FieldType.cs
index 75ba177..01c6e94 100644
--- a/src/Lucene.Net.Core/Document/FieldType.cs
+++ b/src/Lucene.Net.Core/Document/FieldType.cs
@@ -32,7 +32,7 @@ namespace Lucene.Net.Documents
/// Data type of the numeric value
/// @since 3.2
/// </summary>
- public enum NumericType
+ public enum NumericType // LUCENENET TODO: Move outside of FieldType class
{
/// <summary>
/// 32-bit integer numeric type </summary>
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.Core/Support/StringSupport.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Support/StringSupport.cs b/src/Lucene.Net.Core/Support/StringSupport.cs
index fc16452..b504fef 100644
--- a/src/Lucene.Net.Core/Support/StringSupport.cs
+++ b/src/Lucene.Net.Core/Support/StringSupport.cs
@@ -54,5 +54,15 @@ namespace Lucene.Net.Support
{
return Character.OffsetByCodePoints(seq, index, codePointOffset);
}
+
+
+ /// <summary>
+ /// Convenience method to wrap a string in a <see cref="StringCharSequenceWrapper"/>
+ /// so a string can be used as <see cref="ICharSequence"/> in .NET.
+ /// </summary>
+ public static ICharSequence ToCharSequence(this string str)
+ {
+ return new StringCharSequenceWrapper(str);
+ }
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryBuilder.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryBuilder.cs
new file mode 100644
index 0000000..4a572aa
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryBuilder.cs
@@ -0,0 +1,37 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.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>
+ /// This interface is used by implementors classes that builds some kind of
+ /// object from a query tree.
+ ///
+ /// <seealso cref="QueryTreeBuilder"/>
+ /// </summary>
+ public interface IQueryBuilder// <TQuery> // LUCENENET specific - made generic so we don't need to deal with cast
+ {
+ /// <summary>
+ /// Builds some kind of object from a query tree.
+ /// </summary>
+ /// <param name="queryNode">the query tree root node</param>
+ /// <returns>some object generated from the query tree</returns>
+ object Build(IQueryNode queryNode);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryTreeBuilder.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryTreeBuilder.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryTreeBuilder.cs
new file mode 100644
index 0000000..41304c3
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Builders/QueryTreeBuilder.cs
@@ -0,0 +1,252 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Standard.Parser;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.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>
+ /// This class should be used when there is a builder for each type of node.
+ ///
+ /// <para>
+ /// The type of node may be defined in 2 different ways: - by the field name,
+ /// when the node implements the <see cref="IFieldableNode"/> interface - by its class,
+ /// it keeps checking the class and all the interfaces and classes this class
+ /// implements/extends until it finds a builder for that class/interface
+ /// </para>
+ /// <para>
+ /// This class always check if there is a builder for the field name before it
+ /// checks for the node class. So, field name builders have precedence over class
+ /// builders.
+ /// </para>
+ /// <para>
+ /// When a builder is found for a node, it's called and the node is passed to the
+ /// builder. If the returned built object is not <c>null</c>, it's tagged
+ /// on the node using the tag <see cref="QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID"/>.
+ /// </para>
+ /// <para>
+ /// The children are usually built before the parent node. However, if a builder
+ /// associated to a node is an instance of <see cref="QueryTreeBuilder"/>, the node is
+ /// delegated to this builder and it's responsible to build the node and its
+ /// children.
+ /// </para>
+ /// <seealso cref="IQueryBuilder"/>
+ /// </summary>
+ public class QueryTreeBuilder : IQueryBuilder
+ {
+ /**
+ * This tag is used to tag the nodes in a query tree with the built objects
+ * produced from their own associated builder.
+ */
+ public static readonly string QUERY_TREE_BUILDER_TAGID = typeof(QueryTreeBuilder).Name;
+
+ private IDictionary<Type, IQueryBuilder> queryNodeBuilders;
+
+ private IDictionary<string, IQueryBuilder> fieldNameBuilders;
+
+ /**
+ * {@link QueryTreeBuilder} constructor.
+ */
+ public QueryTreeBuilder()
+ {
+ // empty constructor
+ }
+
+ /**
+ * Associates a field name with a builder.
+ *
+ * @param fieldName the field name
+ * @param builder the builder to be associated
+ */
+ public void SetBuilder(string fieldName, IQueryBuilder builder)
+ {
+
+ if (this.fieldNameBuilders == null)
+ {
+ this.fieldNameBuilders = new Dictionary<string, IQueryBuilder>();
+ }
+
+ this.fieldNameBuilders[fieldName] = builder;
+ }
+
+ /**
+ * Associates a class with a builder
+ *
+ * @param queryNodeClass the class
+ * @param builder the builder to be associated
+ */
+ public void SetBuilder(Type queryNodeClass,
+ IQueryBuilder builder)
+ {
+
+ if (this.queryNodeBuilders == null)
+ {
+ this.queryNodeBuilders = new Dictionary<Type, IQueryBuilder>();
+ }
+
+ this.queryNodeBuilders[queryNodeClass] = builder;
+
+ }
+
+ private void Process(IQueryNode node)
+ {
+
+ if (node != null)
+ {
+ IQueryBuilder builder = GetBuilder(node);
+
+ if (!(builder is QueryTreeBuilder))
+ {
+ IList<IQueryNode> children = node.GetChildren();
+
+ if (children != null)
+ {
+
+ foreach (IQueryNode child in children)
+ {
+ Process(child);
+ }
+
+ }
+
+ }
+
+ ProcessNode(node, builder);
+
+ }
+
+ }
+
+ private IQueryBuilder GetBuilder(IQueryNode node)
+ {
+ IQueryBuilder builder = null;
+
+ if (this.fieldNameBuilders != null && node is IFieldableNode)
+ {
+ string field = ((IFieldableNode)node).Field;
+
+ //if (field != null)
+ //{
+ // field = field.ToString();
+ //}
+
+ //builder = this.fieldNameBuilders[field];
+ this.fieldNameBuilders.TryGetValue(field, out builder);
+
+ }
+
+ if (builder == null && this.queryNodeBuilders != null)
+ {
+
+ Type clazz = node.GetType();
+
+ do
+ {
+ builder = GetQueryBuilder(clazz);
+
+ if (builder == null)
+ {
+ Type[] classes = clazz.GetInterfaces();
+
+ foreach (Type actualClass in classes)
+ {
+ builder = GetQueryBuilder(actualClass);
+
+ if (builder != null)
+ {
+ break;
+ }
+
+ }
+
+ }
+
+ } while (builder == null && (clazz = clazz.BaseType) != null);
+
+ }
+
+ return builder;
+
+ }
+
+ private void ProcessNode(IQueryNode node, IQueryBuilder builder)
+ {
+
+ if (builder == null)
+ {
+
+ throw new QueryNodeException(new MessageImpl(
+ QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR, node
+ .ToQueryString(new EscapeQuerySyntaxImpl()), node.GetType()
+ .Name));
+
+ }
+
+ object obj = builder.Build(node);
+
+ if (obj != null)
+ {
+ node.SetTag(QUERY_TREE_BUILDER_TAGID, obj);
+ }
+
+ }
+
+ private IQueryBuilder GetQueryBuilder(Type clazz)
+ {
+
+ if (typeof(IQueryNode).IsAssignableFrom(clazz))
+ {
+ IQueryBuilder result;
+ this.queryNodeBuilders.TryGetValue(clazz, out result);
+ return result;
+ //return this.queryNodeBuilders.get(clazz);
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Builds some kind of object from a query tree. Each node in the query tree
+ * is built using an specific builder associated to it.
+ *
+ * @param queryNode the query tree root node
+ *
+ * @return the built object
+ *
+ * @throws QueryNodeException if some node builder throws a
+ * {@link QueryNodeException} or if there is a node which had no
+ * builder associated to it
+ */
+
+ public virtual object Build(IQueryNode queryNode)
+ {
+ Process(queryNode);
+
+ return queryNode.GetTag(QUERY_TREE_BUILDER_TAGID);
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/AbstractQueryConfig.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/AbstractQueryConfig.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/AbstractQueryConfig.cs
new file mode 100644
index 0000000..41bc528
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/AbstractQueryConfig.cs
@@ -0,0 +1,114 @@
+\ufeffusing Lucene.Net.Support;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+ /// <summary>
+ /// This class is the base of {@link QueryConfigHandler} and {@link FieldConfig}.
+ /// It has operations to set, unset and get configuration values.
+ /// <para>
+ /// Each configuration is is a key->value pair. The key should be an unique
+ /// {@link ConfigurationKey} instance and it also holds the value's type.
+ /// </para>
+ /// <seealso cref="ConfigurationKey"/>
+ /// </summary>
+ public abstract class AbstractQueryConfig
+ {
+ private readonly IDictionary<ConfigurationKey, object> configMap = new Dictionary<ConfigurationKey, object>();
+
+ internal AbstractQueryConfig()
+ {
+ // although this class is public, it can only be constructed from package
+ }
+
+ /**
+ * Returns the value held by the given key.
+ *
+ * @param <T> the value's type
+ *
+ * @param key the key, cannot be <code>null</code>
+ *
+ * @return the value held by the given key
+ */
+ public T Get<T>(ConfigurationKey<T> key)
+ {
+
+ if (key == null)
+ {
+ throw new ArgumentException("key cannot be null!");
+ }
+ object result;
+ this.configMap.TryGetValue(key, out result);
+ return result == null ? default(T) : (T)result;
+ //return (T)this.configMap.get(key);
+
+ }
+
+ /**
+ * Returns true if there is a value set with the given key, otherwise false.
+ *
+ * @param <T> the value's type
+ * @param key the key, cannot be <code>null</code>
+ * @return true if there is a value set with the given key, otherwise false
+ */
+ public bool has<T>(ConfigurationKey<T> key)
+ {
+
+ if (key == null)
+ {
+ throw new ArgumentException("key cannot be null!");
+ }
+
+ return this.configMap.ContainsKey(key);
+
+ }
+
+ /**
+ * Sets a key and its value.
+ *
+ * @param <T> the value's type
+ * @param key the key, cannot be <code>null</code>
+ * @param value value to set
+ */
+ public void Set<T>(ConfigurationKey<T> key, T value)
+ {
+
+ if (key == null)
+ {
+ throw new ArgumentException("key cannot be null!");
+ }
+
+ if (value == null)
+ {
+ Unset(key);
+
+ }
+ else
+ {
+ this.configMap[key] = value;
+ }
+
+ }
+
+ /**
+ * Unsets the given key and its value.
+ *
+ * @param <T> the value's type
+ * @param key the key
+ * @return true if the key and value was set and removed, otherwise false
+ */
+ public bool Unset<T>(ConfigurationKey<T> key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentException("key cannot be null!");
+ }
+
+ return this.configMap.Remove(key);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/ConfigurationKey.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/ConfigurationKey.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/ConfigurationKey.cs
new file mode 100644
index 0000000..5a18314
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/ConfigurationKey.cs
@@ -0,0 +1,45 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+ /// <summary>
+ /// An instance of this class represents a key that is used to retrieve a value
+ /// from {@link AbstractQueryConfig}. It also holds the value's type, which is
+ /// defined in the generic argument.
+ /// </summary>
+ /// <seealso cref="AbstractQueryConfig"/>
+ /// <typeparam name="T"></typeparam>
+ public sealed class ConfigurationKey<T> : ConfigurationKey
+ {
+ internal ConfigurationKey() { }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param <T> the value's type
+ *
+ * @return a new instance
+ */
+ //public static ConfigurationKey<T> NewInstance()
+ //{
+ // return new ConfigurationKey<T>();
+ //}
+ }
+
+ /// <summary>
+ /// LUCENENET specific class used to access the NewInstance
+ /// static method without referring to the ConfigurationKey{T}'s
+ /// generic closing type.
+ /// </summary>
+ public abstract class ConfigurationKey
+ {
+ public static ConfigurationKey<T> NewInstance<T>()
+ {
+ return new ConfigurationKey<T>();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfig.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfig.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfig.cs
new file mode 100644
index 0000000..1633f53
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfig.cs
@@ -0,0 +1,50 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+ /// <summary>
+ /// This class represents a field configuration.
+ /// </summary>
+ public class FieldConfig : AbstractQueryConfig
+ {
+ private string fieldName;
+
+ /**
+ * Constructs a {@link FieldConfig}
+ *
+ * @param fieldName the field name, it cannot be null
+ * @throws IllegalArgumentException if the field name is null
+ */
+ public FieldConfig(string fieldName)
+ {
+
+ if (fieldName == null)
+ {
+ throw new ArgumentException("field name should not be null!");
+ }
+
+ this.fieldName = fieldName;
+
+ }
+
+ /**
+ * Returns the field name this configuration represents.
+ *
+ * @return the field name
+ */
+ public string GetField()
+ {
+ return this.fieldName;
+ }
+
+ public override string ToString()
+ {
+ return "<fieldconfig name=\"" + this.fieldName + "\" configurations=\""
+ + base.ToString() + "\"/>";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfigListener.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfigListener.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfigListener.cs
new file mode 100644
index 0000000..4a0972d
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/FieldConfigListener.cs
@@ -0,0 +1,24 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Config
+{
+ /// <summary>
+ /// This interface should be implemented by classes that wants to listen for
+ /// field configuration requests. The implementation receives a
+ /// {@link FieldConfig} object and may add/change its configuration.
+ /// </summary>
+ /// <seealso cref="FieldConfig"/>
+ /// <seealso cref="QueryConfigHandler"/>
+ public interface IFieldConfigListener
+ {
+ /// <summary>
+ /// This method is called ever time a field configuration is requested.
+ /// </summary>
+ /// <param name="fieldConfig">the field configuration requested, should never be null</param>
+ void BuildFieldConfig(FieldConfig fieldConfig);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Config/QueryConfigHandler.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Config/QueryConfigHandler.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Config/QueryConfigHandler.cs
new file mode 100644
index 0000000..ac55d91
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Config/QueryConfigHandler.cs
@@ -0,0 +1,69 @@
+\ufeffusing 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.Core.Config
+{
+ /// <summary>
+ /// This class can be used to hold any query configuration and no field
+ /// configuration. For field configuration, it creates an empty
+ /// {@link FieldConfig} object and delegate it to field config listeners,
+ /// these are responsible for setting up all the field configuration.
+ /// <para>
+ /// {@link QueryConfigHandler} should be extended by classes that intends to
+ /// provide configuration to {@link QueryNodeProcessor} objects.
+ /// </para>
+ /// <para>
+ /// The class that extends {@link QueryConfigHandler} should also provide
+ /// {@link FieldConfig} objects for each collection field.
+ /// </para>
+ /// </summary>
+ /// <seealso cref="FieldConfig"/>
+ /// <seealso cref="IFieldConfigListener"/>
+ /// <seealso cref="QueryConfigHandler"/>
+ public abstract class QueryConfigHandler : AbstractQueryConfig
+ {
+ private readonly LinkedList<IFieldConfigListener> listeners = new LinkedList<IFieldConfigListener>();
+
+ /**
+ * Returns an implementation of
+ * {@link FieldConfig} for a specific field name. If the implemented
+ * {@link QueryConfigHandler} does not know a specific field name, it may
+ * return <code>null</code>, indicating there is no configuration for that
+ * field.
+ *
+ * @param fieldName
+ * the field name
+ * @return a {@link FieldConfig} object containing the field name
+ * configuration or <code>null</code>, if the implemented
+ * {@link QueryConfigHandler} has no configuration for that field
+ */
+ public virtual FieldConfig GetFieldConfig(string fieldName)
+ {
+ FieldConfig fieldConfig = new FieldConfig(StringUtils.ToString(fieldName));
+
+ foreach (IFieldConfigListener listener in this.listeners)
+ {
+ listener.BuildFieldConfig(fieldConfig);
+ }
+
+ return fieldConfig;
+
+ }
+
+ /**
+ * Adds a listener. The added listeners are called in the order they are
+ * added.
+ *
+ * @param listener
+ * the listener to be added
+ */
+ public virtual void AddFieldConfigListener(IFieldConfigListener listener)
+ {
+ this.listeners.AddLast(listener);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Messages/QueryParserMessages.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Messages/QueryParserMessages.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Messages/QueryParserMessages.cs
new file mode 100644
index 0000000..7378f45
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Messages/QueryParserMessages.cs
@@ -0,0 +1,50 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Messages
+{
+ /// <summary>
+ /// Flexible Query Parser message bundle class
+ /// </summary>
+ public class QueryParserMessages : NLS
+ {
+ private static readonly string BUNDLE_NAME = typeof(QueryParserMessages).Name;
+
+ private QueryParserMessages()
+ {
+ // Do not instantiate
+ }
+
+ static QueryParserMessages()
+ {
+ // register all string ids with NLS class and initialize static string
+ // values
+ NLS.InitializeMessages(BUNDLE_NAME, typeof(QueryParserMessages));
+ }
+
+ // static string must match the strings in the property files.
+ public static string INVALID_SYNTAX;
+ public static string INVALID_SYNTAX_CANNOT_PARSE;
+ public static string INVALID_SYNTAX_FUZZY_LIMITS;
+ public static string INVALID_SYNTAX_FUZZY_EDITS;
+ public static string INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION;
+ public static string INVALID_SYNTAX_ESCAPE_CHARACTER;
+ public static string INVALID_SYNTAX_ESCAPE_NONE_HEX_UNICODE;
+ public static string NODE_ACTION_NOT_SUPPORTED;
+ public static string PARAMETER_VALUE_NOT_SUPPORTED;
+ public static string LUCENE_QUERY_CONVERSION_ERROR;
+ public static string EMPTY_MESSAGE;
+ public static string WILDCARD_NOT_SUPPORTED;
+ public static string TOO_MANY_BOOLEAN_CLAUSES;
+ public static string LEADING_WILDCARD_NOT_ALLOWED;
+ public static string COULD_NOT_PARSE_NUMBER;
+ public static string NUMBER_CLASS_NOT_SUPPORTED_BY_NUMERIC_RANGE_QUERY;
+ public static string UNSUPPORTED_NUMERIC_DATA_TYPE;
+ public static string NUMERIC_CANNOT_BE_EMPTY;
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AndQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AndQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AndQueryNode.cs
new file mode 100644
index 0000000..fa2b365
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AndQueryNode.cs
@@ -0,0 +1,69 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link AndQueryNode} represents an AND boolean operation performed on a
+ /// list of nodes.
+ /// </summary>
+ public class AndQueryNode : BooleanQueryNode
+ {
+ /**
+ * @param clauses
+ * - the query nodes to be and'ed
+ */
+ public AndQueryNode(IList<IQueryNode> clauses)
+ : base(clauses)
+ {
+ if ((clauses == null) || (clauses.Count == 0))
+ {
+ throw new ArgumentException(
+ "AND query must have at least one clause");
+ }
+ }
+
+
+ public override string ToString()
+ {
+ if (GetChildren() == null || GetChildren().Count == 0)
+ return "<boolean operation='and'/>";
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<boolean operation='and'>");
+ foreach (IQueryNode child in GetChildren())
+ {
+ sb.Append("\n");
+ sb.Append(child.ToString());
+
+ }
+ sb.Append("\n</boolean>");
+ 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 = " AND ";
+ }
+
+ // in case is root or the parent is a group node avoid parenthesis
+ if ((GetParent() != null && GetParent() is GroupQueryNode)
+ || IsRoot())
+ return sb.ToString();
+ else
+ return "( " + sb.ToString() + " )";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AnyQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AnyQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AnyQueryNode.cs
new file mode 100644
index 0000000..da91a96
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/AnyQueryNode.cs
@@ -0,0 +1,151 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link AnyQueryNode} represents an ANY operator performed on a list of
+ /// nodes.
+ /// </summary>
+ public class AnyQueryNode : AndQueryNode
+ {
+ private string field = null;
+ private int minimumMatchingmElements = 0;
+
+ /**
+ * @param clauses
+ * - the query nodes to be or'ed
+ */
+ public AnyQueryNode(IList<IQueryNode> clauses, string field,
+ int minimumMatchingElements)
+ : base(clauses)
+ {
+ this.field = field;
+ this.minimumMatchingmElements = minimumMatchingElements;
+
+ if (clauses != null)
+ {
+
+ foreach (IQueryNode clause in clauses)
+ {
+
+ if (clause is FieldQueryNode)
+ {
+
+ if (clause is QueryNodeImpl)
+ {
+ ((QueryNodeImpl)clause).toQueryStringIgnoreFields = true;
+ }
+
+ if (clause is IFieldableNode)
+ {
+ ((IFieldableNode)clause).Field = field;
+ }
+
+ }
+ }
+
+ }
+
+ }
+
+ public int GetMinimumMatchingElements()
+ {
+ return this.minimumMatchingmElements;
+ }
+
+ /**
+ * returns null if the field was not specified
+ *
+ * @return the field
+ */
+ public string GetField()
+ {
+ return this.field;
+ }
+
+ /**
+ * returns - null if the field was not specified
+ *
+ * @return the field as a String
+ */
+ public string GetFieldAsString()
+ {
+ if (this.field == null)
+ return null;
+ else
+ return this.field.ToString();
+ }
+
+ /**
+ * @param field
+ * - the field to set
+ */
+ public void setField(string field)
+ {
+ this.field = field;
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ AnyQueryNode clone = (AnyQueryNode)base.CloneTree();
+
+ clone.field = this.field;
+ clone.minimumMatchingmElements = this.minimumMatchingmElements;
+
+ return clone;
+ }
+
+
+ public override string ToString()
+ {
+ if (GetChildren() == null || GetChildren().Count == 0)
+ return "<any field='" + this.field + "' matchelements="
+ + this.minimumMatchingmElements + "/>";
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<any field='" + this.field + "' matchelements="
+ + this.minimumMatchingmElements + ">");
+ foreach (IQueryNode clause in GetChildren())
+ {
+ sb.Append("\n");
+ sb.Append(clause.ToString());
+ }
+ sb.Append("\n</any>");
+ return sb.ToString();
+ }
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ string anySTR = "ANY " + this.minimumMatchingmElements;
+
+ StringBuilder sb = new StringBuilder();
+ if (GetChildren() == null || GetChildren().Count == 0)
+ {
+ // no childs case
+ }
+ else
+ {
+ string filler = "";
+ foreach (IQueryNode clause in GetChildren())
+ {
+ sb.Append(filler).Append(clause.ToQueryString(escapeSyntaxParser));
+ filler = " ";
+ }
+ }
+
+ if (IsDefaultField(this.field))
+ {
+ return "( " + sb.ToString() + " ) " + anySTR;
+ }
+ else
+ {
+ return this.field + ":(( " + sb.ToString() + " ) " + anySTR + ")";
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BooleanQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BooleanQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BooleanQueryNode.cs
new file mode 100644
index 0000000..de68cbd
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BooleanQueryNode.cs
@@ -0,0 +1,77 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link BooleanQueryNode} represents a list of elements which do not have an
+ /// explicit boolean operator defined between them. It can be used to express a
+ /// boolean query that intends to use the default boolean operator.
+ /// </summary>
+ public class BooleanQueryNode : QueryNodeImpl
+ {
+ /**
+ * @param clauses
+ * - the query nodes to be and'ed
+ */
+ public BooleanQueryNode(IList<IQueryNode> clauses)
+ {
+ SetLeaf(false);
+ Allocate();
+ Set(clauses);
+ }
+
+
+ public override string ToString()
+ {
+ if (GetChildren() == null || GetChildren().Count == 0)
+ return "<boolean operation='default'/>";
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<boolean operation='default'>");
+ foreach (IQueryNode child in GetChildren())
+ {
+ sb.Append("\n");
+ sb.Append(child.ToString());
+ }
+ sb.Append("\n</boolean>");
+ 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 = " ";
+ }
+
+ // in case is root or the parent is a group node avoid parenthesis
+ if ((GetParent() != null && GetParent() is GroupQueryNode)
+ || IsRoot())
+ return sb.ToString();
+ else
+ return "( " + sb.ToString() + " )";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ BooleanQueryNode clone = (BooleanQueryNode)base.CloneTree();
+
+ // nothing to do here
+
+ return clone;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BoostQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BoostQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BoostQueryNode.cs
new file mode 100644
index 0000000..0b27d31
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/BoostQueryNode.cs
@@ -0,0 +1,113 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+ /// <summary>
+ /// A {@link BoostQueryNode} boosts the QueryNode tree which is under this node.
+ /// So, it must only and always have one child.
+ ///
+ /// The boost value may vary from 0.0 to 1.0.
+ /// </summary>
+ public class BoostQueryNode : QueryNodeImpl
+ {
+ private float value = 0;
+
+ /**
+ * Constructs a boost node
+ *
+ * @param query
+ * the query to be boosted
+ * @param value
+ * the boost value, it may vary from 0.0 to 1.0
+ */
+ public BoostQueryNode(IQueryNode query, float value)
+ {
+ if (query == null)
+ {
+ throw new QueryNodeError(new MessageImpl(
+ QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
+ }
+
+ this.value = value;
+ SetLeaf(false);
+ Allocate();
+ Add(query);
+ }
+
+ /**
+ * Returns the single child which this node boosts.
+ *
+ * @return the single child which this node boosts
+ */
+ public IQueryNode GetChild()
+ {
+ IList<IQueryNode> children = GetChildren();
+
+ if (children == null || children.Count == 0)
+ {
+ return null;
+ }
+
+ return children[0];
+
+ }
+
+ /**
+ * Returns the boost value. It may vary from 0.0 to 1.0.
+ *
+ * @return the boost value
+ */
+ public float GetValue()
+ {
+ return this.value;
+ }
+
+ /**
+ * Returns the boost value parsed to a string.
+ *
+ * @return the parsed value
+ */
+ private string GetValueString()
+ {
+ float f = this.value;
+ if (f == (long)f)
+ return "" + (long)f;
+ else
+ return "" + f;
+
+ }
+
+
+ public override string ToString()
+ {
+ return "<boost value='" + GetValueString() + "'>" + "\n"
+ + GetChild().ToString() + "\n</boost>";
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (GetChild() == null)
+ return "";
+ return GetChild().ToQueryString(escapeSyntaxParser) + "^"
+ + GetValueString();
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ BoostQueryNode clone = (BoostQueryNode)base.CloneTree();
+
+ clone.value = this.value;
+
+ return clone;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/DeletedQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/DeletedQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/DeletedQueryNode.cs
new file mode 100644
index 0000000..84694cb
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/DeletedQueryNode.cs
@@ -0,0 +1,43 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link DeletedQueryNode} represents a node that was deleted from the query
+ /// node tree. It can be removed from the tree using the
+ /// {@link RemoveDeletedQueryNodesProcessor} processor.
+ /// </summary>
+ public class DeletedQueryNode : QueryNodeImpl
+ {
+ public DeletedQueryNode()
+ {
+ // empty constructor
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escaper)
+ {
+ return "[DELETEDCHILD]";
+ }
+
+
+ public override string ToString()
+ {
+ return "<deleted/>";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ DeletedQueryNode clone = (DeletedQueryNode)base.CloneTree();
+
+ return clone;
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldQueryNode.cs
new file mode 100644
index 0000000..cad1c8a
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldQueryNode.cs
@@ -0,0 +1,241 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link FieldQueryNode} represents a element that contains field/text tuple
+ /// </summary>
+ public class FieldQueryNode : QueryNodeImpl, IFieldValuePairQueryNode<string>, ITextableQueryNode
+ {
+ /**
+ * The term's field
+ */
+ protected string field;
+
+ /**
+ * The term's text.
+ */
+ protected ICharSequence text;
+
+ /**
+ * The term's begin position.
+ */
+ protected int begin;
+
+ /**
+ * The term's end position.
+ */
+ protected int end;
+
+ /**
+ * The term's position increment.
+ */
+ protected int positionIncrement;
+
+ /**
+ * @param field
+ * - field name
+ * @param text
+ * - value
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ // LUCENENET specific overload for passing text as string
+ public FieldQueryNode(string field, string text, int begin,
+ int end)
+ : this(field, new StringCharSequenceWrapper(text), begin, end)
+ {
+ }
+
+ /**
+ * @param field
+ * - field name
+ * @param text
+ * - value
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ public FieldQueryNode(string field, ICharSequence text, int begin,
+ int end)
+ {
+ this.field = field;
+ this.text = text;
+ this.begin = begin;
+ this.end = end;
+ this.SetLeaf(true);
+
+ }
+
+ protected string GetTermEscaped(IEscapeQuerySyntax escaper)
+ {
+ return escaper.Escape(this.text, CultureInfo.InvariantCulture /*Locale.getDefault()*/, EscapeQuerySyntax.Type.NORMAL).ToString();
+ }
+
+ protected string GetTermEscapeQuoted(IEscapeQuerySyntax escaper)
+ {
+ return escaper.Escape(this.text, CultureInfo.InvariantCulture /*Locale.getDefault()*/, EscapeQuerySyntax.Type.STRING).ToString();
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escaper)
+ {
+ if (IsDefaultField(this.field))
+ {
+ return GetTermEscaped(escaper);
+ }
+ else
+ {
+ return this.field + ":" + GetTermEscaped(escaper);
+ }
+ }
+
+
+ public override string ToString()
+ {
+ return "<field start='" + this.begin + "' end='" + this.end + "' field='"
+ + this.field + "' text='" + this.text + "'/>";
+ }
+
+ /**
+ * @return the term
+ */
+ public string GetTextAsString()
+ {
+ if (this.text == null)
+ return null;
+ else
+ return this.text.ToString();
+ }
+
+ /**
+ * returns null if the field was not specified in the query string
+ *
+ * @return the field
+ */
+ public string GetFieldAsString()
+ {
+ if (this.field == null)
+ return null;
+ else
+ return this.field.ToString();
+ }
+
+ public int GetBegin()
+ {
+ return this.begin;
+ }
+
+ public void SetBegin(int begin)
+ {
+ this.begin = begin;
+ }
+
+ public int GetEnd()
+ {
+ return this.end;
+ }
+
+ public void setEnd(int end)
+ {
+ this.end = end;
+ }
+
+ public virtual string Field
+ {
+ get { return this.field; }
+ set { this.field = value; }
+ }
+
+ // @Override
+ //public CharSequence getField()
+ // {
+ // return this.field;
+ // }
+
+ // @Override
+ //public void setField(CharSequence field)
+ // {
+ // this.field = field;
+ // }
+
+ public int GetPositionIncrement()
+ {
+ return this.positionIncrement;
+ }
+
+ public void SetPositionIncrement(int pi)
+ {
+ this.positionIncrement = pi;
+ }
+
+ public virtual ICharSequence Text
+ {
+ get { return this.text; }
+ set { this.text = value; }
+ }
+
+ ///**
+ // * Returns the term.
+ // *
+ // * @return The "original" form of the term.
+ // */
+
+ //public override string GetText()
+ //{
+ // return this.text;
+ //}
+
+ ///**
+ // * @param text
+ // * the text to set
+ // */
+
+ //public override void SetText(string text)
+ //{
+ // this.text = text;
+ //}
+
+
+ public override IQueryNode CloneTree()
+ {
+ FieldQueryNode fqn = (FieldQueryNode)base.CloneTree();
+ fqn.begin = this.begin;
+ fqn.end = this.end;
+ fqn.field = this.field;
+ fqn.text = this.text;
+ fqn.positionIncrement = this.positionIncrement;
+ fqn.toQueryStringIgnoreFields = this.toQueryStringIgnoreFields;
+
+ return fqn;
+
+ }
+
+ public virtual string Value
+ {
+ get { return Text.ToString(); }
+ set { Text = new StringCharSequenceWrapper(value); }
+ }
+
+ //public override string GetValue()
+ //{
+ // return GetText();
+ //}
+
+
+ //public override void SetValue(string value)
+ //{
+ // SetText(value);
+ //}
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldValuePairQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldValuePairQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldValuePairQueryNode.cs
new file mode 100644
index 0000000..d6d4e32
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldValuePairQueryNode.cs
@@ -0,0 +1,19 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+ /// <summary>
+ /// This interface should be implemented by {@link QueryNode} that holds a field
+ /// and an arbitrary value.
+ /// </summary>
+ /// <seealso cref="IFieldableNode"/>
+ /// <seealso cref="IValueQueryNode{T}"/>
+ /// <typeparam name="T"></typeparam>
+ public interface IFieldValuePairQueryNode<T> : IFieldableNode, IValueQueryNode<T>
+ {
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldableNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldableNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldableNode.cs
new file mode 100644
index 0000000..e9b6439
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FieldableNode.cs
@@ -0,0 +1,38 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+ /// <summary>
+ /// A query node implements {@link FieldableNode} interface to indicate that its
+ /// children and itself are associated to a specific field.
+ ///
+ /// If it has any children which also implements this interface, it must ensure
+ /// the children are associated to the same field.
+ /// </summary>
+ public interface IFieldableNode : IQueryNode
+ {
+ /// <summary>
+ /// Gets or Sets the field associated to the node and every node under it.
+ /// </summary>
+ string Field { get; set; }
+
+ // /**
+ //* Returns the field associated to the node and every node under it.
+ //*
+ //* @return the field name
+ //*/
+ // string GetField();
+
+ // /**
+ // * Associates the node to a field.
+ // *
+ // * @param fieldName
+ // * the field name
+ // */
+ // void SetField(string fieldName);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FuzzyQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FuzzyQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FuzzyQueryNode.cs
new file mode 100644
index 0000000..8f64793
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/FuzzyQueryNode.cs
@@ -0,0 +1,119 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link FuzzyQueryNode} represents a element that contains
+ /// field/text/similarity tuple
+ /// </summary>
+ public class FuzzyQueryNode : FieldQueryNode
+ {
+ private float similarity;
+
+ private int prefixLength;
+
+ /**
+ * @param field
+ * Name of the field query will use.
+ * @param termStr
+ * Term token to use for building term for the query
+ */
+ /**
+ * @param field
+ * - Field name
+ * @param term
+ * - Value
+ * @param minSimilarity
+ * - similarity value
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ // LUCENENET specific overload for string term
+ public FuzzyQueryNode(string field, string term,
+ float minSimilarity, int begin, int end)
+ : this(field, term.ToCharSequence(), minSimilarity, begin, end)
+ {
+ }
+
+ /**
+ * @param field
+ * - Field name
+ * @param term
+ * - Value
+ * @param minSimilarity
+ * - similarity value
+ * @param begin
+ * - position in the query string
+ * @param end
+ * - position in the query string
+ */
+ public FuzzyQueryNode(string field, ICharSequence term,
+ float minSimilarity, int begin, int end)
+ : base(field, term, begin, end)
+ {
+ this.similarity = minSimilarity;
+ SetLeaf(true);
+ }
+
+ public void SetPrefixLength(int prefixLength)
+ {
+ this.prefixLength = prefixLength;
+ }
+
+ public int GetPrefixLength()
+ {
+ return this.prefixLength;
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escaper)
+ {
+ if (IsDefaultField(this.field))
+ {
+ return GetTermEscaped(escaper) + "~" + this.similarity;
+ }
+ else
+ {
+ return this.field + ":" + GetTermEscaped(escaper) + "~" + this.similarity;
+ }
+ }
+
+
+ public override string ToString()
+ {
+ return "<fuzzy field='" + this.field + "' similarity='" + this.similarity
+ + "' term='" + this.text + "'/>";
+ }
+
+ public void SetSimilarity(float similarity)
+ {
+ this.similarity = similarity;
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ FuzzyQueryNode clone = (FuzzyQueryNode)base.CloneTree();
+
+ clone.similarity = this.similarity;
+
+ return clone;
+ }
+
+ /**
+ * @return the similarity
+ */
+ public float GetSimilarity()
+ {
+ return this.similarity;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/GroupQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/GroupQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/GroupQueryNode.cs
new file mode 100644
index 0000000..246b30c
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/GroupQueryNode.cs
@@ -0,0 +1,73 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+ /// <summary>
+ /// A {@link GroupQueryNode} represents a location where the original user typed
+ /// real parenthesis on the query string. This class is useful for queries like:
+ /// a) a AND b OR c b) ( a AND b) OR c
+ ///
+ /// Parenthesis might be used to define the boolean operation precedence.
+ /// </summary>
+ public class GroupQueryNode : QueryNodeImpl
+ {
+ /**
+ * This QueryNode is used to identify parenthesis on the original query string
+ */
+ public GroupQueryNode(IQueryNode query)
+ {
+ if (query == null)
+ {
+ throw new QueryNodeError(new MessageImpl(
+ QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "query", "null"));
+ }
+
+ Allocate();
+ SetLeaf(false);
+ Add(query);
+ }
+
+ public IQueryNode GetChild()
+ {
+ return GetChildren()[0];
+ }
+
+
+ public override string ToString()
+ {
+ return "<group>" + "\n" + GetChild().ToString() + "\n</group>";
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (GetChild() == null)
+ return "";
+
+ return "( " + GetChild().ToQueryString(escapeSyntaxParser) + " )";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ GroupQueryNode clone = (GroupQueryNode)base.CloneTree();
+
+ return clone;
+ }
+
+ public void setChild(IQueryNode child)
+ {
+ List<IQueryNode> list = new List<IQueryNode>();
+ list.Add(child);
+ this.Set(list);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs
new file mode 100644
index 0000000..0a0ffa8
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchAllDocsQueryNode.cs
@@ -0,0 +1,43 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link MatchAllDocsQueryNode} indicates that a query node tree or subtree
+ /// will match all documents if executed in the index.
+ /// </summary>
+ public class MatchAllDocsQueryNode : QueryNodeImpl
+ {
+ public MatchAllDocsQueryNode()
+ {
+ // empty constructor
+ }
+
+
+ public override string ToString()
+ {
+ return "<matchAllDocs field='*' term='*'/>";
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ return "*:*";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ MatchAllDocsQueryNode clone = (MatchAllDocsQueryNode)base.CloneTree();
+
+ // nothing to clone
+
+ return clone;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
new file mode 100644
index 0000000..e8cfadd
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/MatchNoDocsQueryNode.cs
@@ -0,0 +1,25 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+ /// <summary>
+ /// A {@link MatchNoDocsQueryNode} indicates that a query node tree or subtree
+ /// will not match any documents if executed in the index.
+ /// </summary>
+ public class MatchNoDocsQueryNode : DeletedQueryNode
+ {
+ public MatchNoDocsQueryNode()
+ {
+ // empty constructor
+ }
+
+ public override string ToString()
+ {
+ return "<matchNoDocsQueryNode/>";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/ModifierQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/ModifierQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/ModifierQueryNode.cs
new file mode 100644
index 0000000..900f117
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/ModifierQueryNode.cs
@@ -0,0 +1,172 @@
+\ufeffusing Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+ /// <summary>
+ /// A {@link ModifierQueryNode} indicates the modifier value (+,-,?,NONE) for
+ /// each term on the query string. For example "+t1 -t2 t3" will have a tree of:
+ /// <blockquote>
+ /// <BooleanQueryNode> <ModifierQueryNode modifier="MOD_REQ"> <t1/>
+ /// </ModifierQueryNode> <ModifierQueryNode modifier="MOD_NOT"> <t2/>
+ /// </ModifierQueryNode> <t3/> </BooleanQueryNode>
+ /// </blockquote>
+ /// </summary>
+ public class ModifierQueryNode : QueryNodeImpl
+ {
+
+ // LUCENENET NOTE: Modifier enum moved outside of this class
+
+
+
+ private Modifier modifier = Modifier.MOD_NONE;
+
+ /**
+ * Used to store the modifier value on the original query string
+ *
+ * @param query
+ * - QueryNode subtree
+ * @param mod
+ * - Modifier Value
+ */
+ public ModifierQueryNode(IQueryNode query, Modifier mod)
+ {
+ if (query == null)
+ {
+ throw new QueryNodeError(new MessageImpl(
+ QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "query", "null"));
+ }
+
+ Allocate();
+ SetLeaf(false);
+ Add(query);
+ this.modifier = mod;
+ }
+
+ public IQueryNode GetChild()
+ {
+ return GetChildren()[0];
+ }
+
+ public Modifier GetModifier()
+ {
+ return this.modifier;
+ }
+
+
+ public override string ToString()
+ {
+ return "<modifier operation='" + this.modifier.ToString() + "'>" + "\n"
+ + GetChild().ToString() + "\n</modifier>";
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (GetChild() == null)
+ return "";
+
+ String leftParenthensis = "";
+ String rightParenthensis = "";
+
+ if (GetChild() != null && GetChild() is ModifierQueryNode)
+ {
+ leftParenthensis = "(";
+ rightParenthensis = ")";
+ }
+
+ if (GetChild() is BooleanQueryNode)
+ {
+ return this.modifier.ToLargeString() + leftParenthensis
+ + GetChild().ToQueryString(escapeSyntaxParser) + rightParenthensis;
+ }
+ else
+ {
+ return this.modifier.ToDigitString() + leftParenthensis
+ + GetChild().ToQueryString(escapeSyntaxParser) + rightParenthensis;
+ }
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ ModifierQueryNode clone = (ModifierQueryNode)base.CloneTree();
+
+ clone.modifier = this.modifier;
+
+ return clone;
+ }
+
+ public void setChild(IQueryNode child)
+ {
+ List<IQueryNode> list = new List<IQueryNode>();
+ list.Add(child);
+ this.Set(list);
+ }
+ }
+
+ /**
+ * Modifier type: such as required (REQ), prohibited (NOT)
+ */
+ public enum Modifier
+ {
+ MOD_NONE,
+ MOD_NOT,
+ MOD_REQ
+ }
+
+ public static class ModifierExtensions
+ {
+ // LUCENENET TODO: Work out how to override ToString() (or test this) so this string can be made
+ //public static string ToString()
+ //{
+ // switch (this)
+ // {
+ // case MOD_NONE:
+ // return "MOD_NONE";
+ // case MOD_NOT:
+ // return "MOD_NOT";
+ // case MOD_REQ:
+ // return "MOD_REQ";
+ // }
+ // // this code is never executed
+ // return "MOD_DEFAULT";
+ //}
+
+ public static string ToDigitString(this Modifier modifier)
+ {
+ switch (modifier)
+ {
+ case Modifier.MOD_NONE:
+ return "";
+ case Modifier.MOD_NOT:
+ return "-";
+ case Modifier.MOD_REQ:
+ return "+";
+ }
+ // this code is never executed
+ return "";
+ }
+
+ public static string ToLargeString(this Modifier modifier)
+ {
+ switch (modifier)
+ {
+ case Modifier.MOD_NONE:
+ return "";
+ case Modifier.MOD_NOT:
+ return "NOT ";
+ case Modifier.MOD_REQ:
+ return "+";
+ }
+ // this code is never executed
+ return "";
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
new file mode 100644
index 0000000..d321df8
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
@@ -0,0 +1,42 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link NoTokenFoundQueryNode} is used if a term is convert into no tokens
+ /// by the tokenizer/lemmatizer/analyzer (null).
+ /// </summary>
+ public class NoTokenFoundQueryNode : DeletedQueryNode
+ {
+ //public NoTokenFoundQueryNode()
+ //{
+ //}
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escaper)
+ {
+ return "[NTF]";
+ }
+
+
+ public override string ToString()
+ {
+ return "<notokenfound/>";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ NoTokenFoundQueryNode clone = (NoTokenFoundQueryNode)base.CloneTree();
+
+ // nothing to do here
+
+ return clone;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OpaqueQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OpaqueQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OpaqueQueryNode.cs
new file mode 100644
index 0000000..fcae411
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OpaqueQueryNode.cs
@@ -0,0 +1,75 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link OpaqueQueryNode} is used for specify values that are not supposed to
+ /// be parsed by the parser. For example: and XPATH query in the middle of a
+ /// query string a b @xpath:'/bookstore/book[1]/title' c d
+ /// </summary>
+ public class OpaqueQueryNode : QueryNodeImpl
+ {
+ private string schema = null;
+
+ private string value = null;
+
+ /**
+ * @param schema
+ * - schema identifier
+ * @param value
+ * - value that was not parsed
+ */
+ public OpaqueQueryNode(string schema, string value)
+ {
+ this.SetLeaf(true);
+
+ this.schema = schema;
+ this.value = value;
+
+ }
+
+
+ public override string ToString()
+ {
+ return "<opaque schema='" + this.schema + "' value='" + this.value + "'/>";
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ return "@" + this.schema + ":'" + this.value + "'";
+ }
+
+
+ public override IQueryNode CloneTree()
+ {
+ OpaqueQueryNode clone = (OpaqueQueryNode)base.CloneTree();
+
+ clone.schema = this.schema;
+ clone.value = this.value;
+
+ return clone;
+ }
+
+ /**
+ * @return the schema
+ */
+ public string GetSchema()
+ {
+ return this.schema;
+ }
+
+ /**
+ * @return the value
+ */
+ public string GetValue()
+ {
+ return this.value;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c83be6be/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
new file mode 100644
index 0000000..edd3577
--- /dev/null
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/OrQueryNode.cs
@@ -0,0 +1,68 @@
+\ufeffusing 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.Core.Nodes
+{
+ /// <summary>
+ /// A {@link OrQueryNode} represents an OR boolean operation performed on a list
+ /// of nodes.
+ /// </summary>
+ public class OrQueryNode : BooleanQueryNode
+ {
+ /**
+ * @param clauses
+ * - the query nodes to be or'ed
+ */
+ public OrQueryNode(IList<IQueryNode> clauses)
+ : base(clauses)
+ {
+ if ((clauses == null) || (clauses.Count == 0))
+ {
+ throw new ArgumentException(
+ "OR query must have at least one clause");
+ }
+ }
+
+ public override string ToString()
+ {
+ if (GetChildren() == null || GetChildren().Count == 0)
+ return "<boolean operation='or'/>";
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<boolean operation='or'>");
+ foreach (IQueryNode child in GetChildren())
+ {
+ sb.Append("\n");
+ sb.Append(child.ToString());
+
+ }
+ sb.Append("\n</boolean>");
+ return sb.ToString();
+ }
+
+
+ public override string ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (GetChildren() == null || GetChildren().Count == 0)
+ return "";
+
+ StringBuilder sb = new StringBuilder();
+ string filler = "";
+ for (IEnumerator<IQueryNode> it = GetChildren().GetEnumerator(); it.MoveNext();)
+ {
+ sb.Append(filler).Append(it.Current.ToQueryString(escapeSyntaxParser));
+ filler = " OR ";
+ }
+
+ // in case is root or the parent is a group node avoid parenthesis
+ if ((GetParent() != null && GetParent() is GroupQueryNode)
+ || IsRoot())
+ return sb.ToString();
+ else
+ return "( " + sb.ToString() + " )";
+ }
+ }
+}