You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by mh...@apache.org on 2013/10/07 01:47:59 UTC
[11/16] git commit: Finish QueryParsers.Flexible.Core namespace
Finish QueryParsers.Flexible.Core namespace
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/539a6ded
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/539a6ded
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/539a6ded
Branch: refs/heads/branch_4x
Commit: 539a6ded7d8350ea56a753848831f19581a21777
Parents: c9e9c54
Author: Paul Irwin <pa...@gmail.com>
Authored: Fri Oct 4 13:32:27 2013 -0400
Committer: Paul Irwin <pa...@gmail.com>
Committed: Sat Oct 5 16:37:28 2013 -0400
----------------------------------------------------------------------
.../QueryParsers/Contrib.QueryParsers.csproj | 16 ++
.../Flexible/Core/Nodes/FieldQueryNode.cs | 2 +-
.../Flexible/Core/Nodes/IRangeQueryNode.cs | 20 ++
.../Core/Nodes/NoTokenFoundQueryNode.cs | 37 ++++
.../Flexible/Core/Nodes/OpaqueQueryNode.cs | 56 ++++++
.../Flexible/Core/Nodes/OrQueryNode.cs | 58 ++++++
.../Flexible/Core/Nodes/PathQueryNode.cs | 125 ++++++++++++
.../Flexible/Core/Nodes/PhraseSlopQueryNode.cs | 93 +++++++++
.../Flexible/Core/Nodes/ProximityQueryNode.cs | 196 +++++++++++++++++++
.../Flexible/Core/Nodes/QuotedFieldQueryNode.cs | 43 ++++
.../Flexible/Core/Nodes/SlopQueryNode.cs | 93 +++++++++
.../Core/Nodes/TokenizedPhraseQueryNode.cs | 92 +++++++++
.../Flexible/Core/Parser/ISyntaxParser.cs | 2 +-
.../Core/Processors/IQueryNodeProcessor.cs | 17 ++
.../NoChildOptimizationQueryNodeProcessor.cs | 52 +++++
.../Core/Processors/QueryNodeProcessor.cs | 131 +++++++++++++
.../Processors/QueryNodeProcessorPipeline.cs | 180 +++++++++++++++++
.../RemoveDeletedQueryNodesProcessor.cs | 82 ++++++++
.../Flexible/Core/QueryParserHelper.cs | 107 ++++++++++
19 files changed, 1400 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
index 2fcb669..59815b4 100644
--- a/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
+++ b/src/contrib/QueryParsers/Contrib.QueryParsers.csproj
@@ -64,6 +64,7 @@
<Compile Include="Flexible\Core\Config\IFieldConfigListener.cs" />
<Compile Include="Flexible\Core\Config\QueryConfigHandler.cs" />
<Compile Include="Flexible\Core\Nodes\FuzzyQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\IRangeQueryNode.cs" />
<Compile Include="Flexible\Core\Nodes\ITextableQueryNode.cs" />
<Compile Include="Flexible\Core\Messages\QueryParserMessages.cs" />
<Compile Include="Flexible\Core\Nodes\AndQueryNode.cs" />
@@ -80,12 +81,27 @@
<Compile Include="Flexible\Core\Nodes\MatchAllDocsQueryNode.cs" />
<Compile Include="Flexible\Core\Nodes\MatchNoDocsQueryNode.cs" />
<Compile Include="Flexible\Core\Nodes\ModifierQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\NoTokenFoundQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\OpaqueQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\OrQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\PathQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\PhraseSlopQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\ProximityQueryNode.cs" />
<Compile Include="Flexible\Core\Nodes\QueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\QuotedFieldQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\SlopQueryNode.cs" />
+ <Compile Include="Flexible\Core\Nodes\TokenizedPhraseQueryNode.cs" />
<Compile Include="Flexible\Core\Parser\IEscapeQuerySyntax.cs" />
<Compile Include="Flexible\Core\Parser\ISyntaxParser.cs" />
+ <Compile Include="Flexible\Core\Processors\IQueryNodeProcessor.cs" />
+ <Compile Include="Flexible\Core\Processors\NoChildOptimizationQueryNodeProcessor.cs" />
+ <Compile Include="Flexible\Core\Processors\QueryNodeProcessor.cs" />
+ <Compile Include="Flexible\Core\Processors\QueryNodeProcessorPipeline.cs" />
+ <Compile Include="Flexible\Core\Processors\RemoveDeletedQueryNodesProcessor.cs" />
<Compile Include="Flexible\Core\QueryNodeError.cs" />
<Compile Include="Flexible\Core\QueryNodeException.cs" />
<Compile Include="Flexible\Core\QueryNodeParseException.cs" />
+ <Compile Include="Flexible\Core\QueryParserHelper.cs" />
<Compile Include="Flexible\Core\Util\QueryNodeOperation.cs" />
<Compile Include="Flexible\Core\Util\StringUtils.cs" />
<Compile Include="Flexible\Core\Util\UnescapedCharSequence.cs" />
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
index 41d9ceb..e05841a 100644
--- a/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/FieldQueryNode.cs
@@ -35,7 +35,7 @@ namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
return escaper.Escape(new StringCharSequenceWrapper(this.text), CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.NORMAL);
}
- protected ICharSequence GetTermEscapeQuoted(EscapeQuerySyntax escaper)
+ protected ICharSequence GetTermEscapeQuoted(IEscapeQuerySyntax escaper)
{
return escaper.Escape(new StringCharSequenceWrapper(this.text), CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.STRING);
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/IRangeQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/IRangeQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/IRangeQueryNode.cs
new file mode 100644
index 0000000..c9042a5
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/IRangeQueryNode.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
+{
+ public interface IRangeQueryNode<T> : IFieldableNode
+ where T : IFieldValuePairQueryNode<T>
+ {
+ T LowerBound { get; }
+
+ T UpperBound { get; }
+
+ bool IsLowerInclusive { get; }
+
+ bool IsUpperInclusive { get; }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
new file mode 100644
index 0000000..f145843
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/NoTokenFoundQueryNode.cs
@@ -0,0 +1,37 @@
+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.Core.Nodes
+{
+ public class NoTokenFoundQueryNode : DeletedQueryNode
+ {
+ public NoTokenFoundQueryNode()
+ : base()
+ {
+ }
+
+ public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ return new StringCharSequenceWrapper("[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/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/OpaqueQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/OpaqueQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/OpaqueQueryNode.cs
new file mode 100644
index 0000000..68e8ca7
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/OpaqueQueryNode.cs
@@ -0,0 +1,56 @@
+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.Core.Nodes
+{
+ public class OpaqueQueryNode : QueryNode
+ {
+ private string schema = null;
+
+ private string value = null;
+
+ 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 ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ return new StringCharSequenceWrapper("@" + this.schema + ":'" + this.value + "'");
+ }
+
+ public override IQueryNode CloneTree()
+ {
+ OpaqueQueryNode clone = (OpaqueQueryNode)base.CloneTree();
+
+ // .NET Port: shouldn't this have already been done by MemberwiseClone()?
+ clone.schema = this.schema;
+ clone.value = this.value;
+
+ return clone;
+ }
+
+ public string Schema
+ {
+ get { return schema; }
+ }
+
+ public string Value
+ {
+ get { return value; }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/OrQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/OrQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/OrQueryNode.cs
new file mode 100644
index 0000000..943b3f0
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/OrQueryNode.cs
@@ -0,0 +1,58 @@
+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.Core.Nodes
+{
+ public class OrQueryNode : BooleanQueryNode
+ {
+ 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 (Children == null || Children.Count == 0)
+ return "<boolean operation='or'/>";
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<boolean operation='or'>");
+ foreach (IQueryNode child in Children)
+ {
+ sb.Append("\n");
+ sb.Append(child.ToString());
+
+ }
+ sb.Append("\n</boolean>");
+ return sb.ToString();
+ }
+
+ public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (Children == null || Children.Count == 0)
+ return new StringCharSequenceWrapper("");
+
+ StringBuilder sb = new StringBuilder();
+ String filler = "";
+ foreach (IQueryNode child in Children)
+ {
+ sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+ filler = " OR ";
+ }
+
+ // in case is root or the parent is a group node avoid parenthesis
+ if ((Parent != null && Parent is GroupQueryNode) || IsRoot)
+ return new StringCharSequenceWrapper(sb.ToString());
+ else
+ return new StringCharSequenceWrapper("( " + sb.ToString() + " )");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/PathQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/PathQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/PathQueryNode.cs
new file mode 100644
index 0000000..c8d55de
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/PathQueryNode.cs
@@ -0,0 +1,125 @@
+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.Core.Nodes
+{
+ public class PathQueryNode : QueryNode
+ {
+ public class QueryText : ICloneable
+ {
+ string value = null;
+ int begin;
+ int end;
+
+ public QueryText(string value, int begin, int end)
+ {
+ this.value = value;
+ this.begin = begin;
+ this.end = end;
+ }
+
+ public string Value
+ {
+ get { return value; }
+ }
+
+ public int Begin
+ {
+ get { return begin; }
+ }
+
+ public int End
+ {
+ get { return end; }
+ }
+
+ public override string ToString()
+ {
+ return value + ", " + begin + ", " + end;
+ }
+
+ public object Clone()
+ {
+ return this.MemberwiseClone();
+ }
+ }
+
+ private IList<QueryText> values = null;
+
+ public PathQueryNode(IList<QueryText> pathElements)
+ {
+ this.values = pathElements;
+ if (pathElements.Count <= 1)
+ {
+ // this should not happen
+ throw new ArgumentException("PathQuerynode requires more 2 or more path elements.");
+ }
+ }
+
+ public IList<QueryText> PathElements
+ {
+ get { return values; }
+ set { this.values = value; }
+ }
+
+ public QueryText GetPathElement(int index)
+ {
+ return values[index];
+ }
+
+ public string FirstPathElement
+ {
+ get { return values[0].Value; }
+ }
+
+ public IList<QueryText> GetPathElements(int startIndex)
+ {
+ IList<PathQueryNode.QueryText> rValues = new List<PathQueryNode.QueryText>();
+ for (int i = startIndex; i < this.values.Count; i++)
+ {
+ try
+ {
+ rValues.Add((QueryText)this.values[i].Clone());
+ }
+ catch (NotSupportedException)
+ {
+ // this will not happen
+ }
+ }
+ return rValues;
+ }
+
+ private string PathString
+ {
+ get
+ {
+ StringBuilder path = new StringBuilder();
+
+ foreach (QueryText pathelement in values)
+ {
+ path.Append("/").Append(pathelement.Value);
+ }
+ return path.ToString();
+ }
+ }
+
+ public override ICharSequence ToQueryString(IEscapeQuerySyntax escaper)
+ {
+ StringBuilder path = new StringBuilder();
+ path.Append("/").Append(FirstPathElement);
+
+ foreach (QueryText pathelement in GetPathElements(1))
+ {
+ ICharSequence value = escaper.Escape(new StringCharSequenceWrapper(pathelement.Value), CultureInfo.CurrentCulture, EscapeQuerySyntax.Type.STRING);
+ path.Append("/\"").Append(value).Append("\"");
+ }
+ return new StringCharSequenceWrapper(path.ToString());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/PhraseSlopQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/PhraseSlopQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/PhraseSlopQueryNode.cs
new file mode 100644
index 0000000..0ea1974
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/PhraseSlopQueryNode.cs
@@ -0,0 +1,93 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+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
+{
+ public class PhraseSlopQueryNode : QueryNode, IFieldableNode
+ {
+ private int value = 0;
+
+ public PhraseSlopQueryNode(IQueryNode query, int value)
+ {
+ if (query == null)
+ {
+ throw new QueryNodeError(new Message(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
+ }
+
+ this.value = value;
+ SetLeaf(false);
+ Allocate();
+ Add(query);
+ }
+
+ public IQueryNode Child
+ {
+ get { return Children[0]; }
+ }
+
+ public int Value
+ {
+ get { return value; }
+ }
+
+ private string ValueString
+ {
+ get
+ {
+ // .NET Port: java code here was doing some seemingly unnecessary checks
+ // that seemed like cruft left over from float code
+ return value.ToString();
+ }
+ }
+
+ public override string ToString()
+ {
+ return "<phraseslop value='" + ValueString + "'>" + "\n" + Child.ToString() + "\n</phraseslop>";
+ }
+
+ public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (Child == null)
+ return new StringCharSequenceWrapper("");
+ return new StringCharSequenceWrapper(Child.ToQueryString(escapeSyntaxParser) + "~" + ValueString);
+ }
+
+ public override IQueryNode CloneTree()
+ {
+ PhraseSlopQueryNode clone = (PhraseSlopQueryNode)base.CloneTree();
+
+ clone.value = this.value;
+
+ return clone;
+ }
+
+ public string Field
+ {
+ get
+ {
+ IQueryNode child = Child;
+
+ if (child is IFieldableNode)
+ return ((IFieldableNode)child).Field;
+
+ return null;
+ }
+ set
+ {
+ IQueryNode child = Child;
+
+ if (child is IFieldableNode)
+ {
+ ((IFieldableNode)child).Field = value;
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/ProximityQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/ProximityQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/ProximityQueryNode.cs
new file mode 100644
index 0000000..7fadda6
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/ProximityQueryNode.cs
@@ -0,0 +1,196 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+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
+{
+ public class ProximityQueryNode : BooleanQueryNode
+ {
+ public enum Type
+ {
+ PARAGRAPH,
+ SENTENCE,
+ NUMBER
+ }
+
+ // .NET Port: This is necessary as enums are value types in .NET and can't have override/abstract methods
+ public static string TypeToQueryString(Type t)
+ {
+ switch (t)
+ {
+ case Type.PARAGRAPH:
+ return "WITHIN PARAGRAPH";
+ case Type.SENTENCE:
+ return "WITHIN SENTENCE";
+ case Type.NUMBER:
+ return "WITHIN";
+ default:
+ throw new InvalidOperationException("Not supported");
+ }
+ }
+
+ public class ProximityType
+ {
+ internal int pDistance = 0;
+
+ internal Type? pType = null;
+
+ public ProximityType(Type type)
+ : this(type, 0)
+ {
+ }
+
+ public ProximityType(Type type, int distance)
+ {
+ this.pType = type;
+ this.pDistance = distance;
+ }
+ }
+
+ private Type proximityType = Type.SENTENCE;
+ private int distance = -1;
+ private bool inorder = false;
+ private string field = null;
+
+ public ProximityQueryNode(IList<IQueryNode> clauses, string field, Type type, int distance, bool inorder)
+ : base(clauses)
+ {
+ SetLeaf(false);
+ this.proximityType = type;
+ this.inorder = inorder;
+ this.field = field;
+ if (type == Type.NUMBER)
+ {
+ if (distance <= 0)
+ {
+ throw new QueryNodeError(new Message(QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "distance", distance));
+
+ }
+ else
+ {
+ this.distance = distance;
+ }
+
+ }
+ ClearFields(clauses, field);
+ }
+
+ public ProximityQueryNode(IList<IQueryNode> clauses, string field, Type type, bool inorder)
+ : this(clauses, field, type, -1, inorder)
+ {
+ }
+
+ private static void ClearFields(IList<IQueryNode> nodes, string field)
+ {
+ if (nodes == null || nodes.Count == 0)
+ return;
+
+ foreach (IQueryNode clause in nodes)
+ {
+ if (clause is FieldQueryNode)
+ {
+ ((FieldQueryNode)clause).toQueryStringIgnoreFields = true;
+ ((FieldQueryNode)clause).Field = field;
+ }
+ }
+ }
+
+ public Type ProximityTypeValue
+ {
+ get
+ {
+ return this.proximityType;
+ }
+ }
+
+ public override string ToString()
+ {
+ String distanceSTR = ((this.distance == -1) ? ("")
+ : (" distance='" + this.distance) + "'");
+
+ if (Children == null || Children.Count == 0)
+ return "<proximity field='" + this.field + "' inorder='" + this.inorder
+ + "' type='" + this.proximityType.ToString() + "'" + distanceSTR
+ + "/>";
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<proximity field='" + this.field + "' inorder='" + this.inorder
+ + "' type='" + this.proximityType.ToString() + "'" + distanceSTR + ">");
+ foreach (IQueryNode child in Children)
+ {
+ sb.Append("\n");
+ sb.Append(child.ToString());
+ }
+ sb.Append("\n</proximity>");
+ return sb.ToString();
+ }
+
+ public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ String withinSTR = TypeToQueryString(this.proximityType)
+ + ((this.distance == -1) ? ("") : (" " + this.distance))
+ + ((this.inorder) ? (" INORDER") : (""));
+
+ StringBuilder sb = new StringBuilder();
+ if (Children == null || Children.Count == 0)
+ {
+ // no children case
+ }
+ else
+ {
+ String filler = "";
+ foreach (IQueryNode child in Children)
+ {
+ sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+ filler = " ";
+ }
+ }
+
+ if (IsDefaultField(this.field))
+ {
+ return new StringCharSequenceWrapper("( " + sb.ToString() + " ) " + withinSTR);
+ }
+ else
+ {
+ return new StringCharSequenceWrapper(this.field + ":(( " + sb.ToString() + " ) " + withinSTR + ")");
+ }
+ }
+
+ public override IQueryNode CloneTree()
+ {
+ ProximityQueryNode clone = (ProximityQueryNode)base.CloneTree();
+
+ clone.proximityType = this.proximityType;
+ clone.distance = this.distance;
+ clone.field = this.field;
+
+ return clone;
+ }
+
+ public int Distance
+ {
+ get { return this.distance; }
+ }
+
+ public string Field
+ {
+ get { return this.field; }
+ set { this.field = value; }
+ }
+
+ public string FieldAsString
+ {
+ get { return this.field; }
+ }
+
+ public bool IsInOrder
+ {
+ get { return this.inorder; }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/QuotedFieldQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/QuotedFieldQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/QuotedFieldQueryNode.cs
new file mode 100644
index 0000000..2af7e36
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/QuotedFieldQueryNode.cs
@@ -0,0 +1,43 @@
+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.Core.Nodes
+{
+ public class QuotedFieldQueryNode : FieldQueryNode
+ {
+ public QuotedFieldQueryNode(string field, string text, int begin, int end)
+ : base(field, text, begin, end)
+ {
+ }
+
+ public override ICharSequence ToQueryString(IEscapeQuerySyntax escaper)
+ {
+ if (IsDefaultField(this.field))
+ {
+ return new StringCharSequenceWrapper("\"" + GetTermEscapeQuoted(escaper) + "\"");
+ }
+ else
+ {
+ return new StringCharSequenceWrapper(this.field + ":" + "\"" + GetTermEscapeQuoted(escaper) + "\"");
+ }
+ }
+
+ public override string ToString()
+ {
+ return "<quotedfield start='" + this.begin + "' end='" + this.end
+ + "' field='" + this.field + "' term='" + this.text + "'/>";
+ }
+
+ public override IQueryNode CloneTree()
+ {
+ QuotedFieldQueryNode clone = (QuotedFieldQueryNode)base.CloneTree();
+ // nothing to do here
+ return clone;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/SlopQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/SlopQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/SlopQueryNode.cs
new file mode 100644
index 0000000..b2ce8f2
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/SlopQueryNode.cs
@@ -0,0 +1,93 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Messages;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Messages;
+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
+{
+ public class SlopQueryNode : QueryNode, IFieldableNode
+ {
+ private int value = 0;
+
+ public SlopQueryNode(IQueryNode query, int value)
+ {
+ if (query == null)
+ {
+ throw new QueryNodeError(new Message(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
+ }
+
+ this.value = value;
+ SetLeaf(false);
+ Allocate();
+ Add(query);
+ }
+
+ public IQueryNode Child
+ {
+ get
+ {
+ return Children[0];
+ }
+ }
+
+ public int Value
+ {
+ get { return value; }
+ }
+
+ public string ValueString
+ {
+ get { return value.ToString(); }
+ }
+
+ public override string ToString()
+ {
+ return "<slop value='" + ValueString + "'>" + "\n" + Child.ToString() + "\n</slop>";
+ }
+
+ public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (Child == null)
+ return new StringCharSequenceWrapper("");
+ return new StringCharSequenceWrapper(Child.ToQueryString(escapeSyntaxParser) + "~" + ValueString);
+ }
+
+ public override IQueryNode CloneTree()
+ {
+ SlopQueryNode clone = (SlopQueryNode)base.CloneTree();
+
+ clone.value = this.value;
+
+ return clone;
+ }
+
+ public string Field
+ {
+ get
+ {
+ IQueryNode child = Child;
+
+ if (child is IFieldableNode)
+ {
+ return ((IFieldableNode)child).Field;
+ }
+
+ return null;
+ }
+ set
+ {
+ IQueryNode child = Child;
+
+ if (child is IFieldableNode)
+ {
+ ((IFieldableNode)child).Field = value;
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Nodes/TokenizedPhraseQueryNode.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Nodes/TokenizedPhraseQueryNode.cs b/src/contrib/QueryParsers/Flexible/Core/Nodes/TokenizedPhraseQueryNode.cs
new file mode 100644
index 0000000..d42443e
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Nodes/TokenizedPhraseQueryNode.cs
@@ -0,0 +1,92 @@
+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.Core.Nodes
+{
+ public class TokenizedPhraseQueryNode : QueryNode, IFieldableNode
+ {
+ public TokenizedPhraseQueryNode()
+ {
+ SetLeaf(false);
+ Allocate();
+ }
+
+ public override string ToString()
+ {
+ if (Children == null || Children.Count == 0)
+ return "<tokenizedphrase/>";
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<tokenizedtphrase>");
+ foreach (IQueryNode child in Children)
+ {
+ sb.Append("\n");
+ sb.Append(child.ToString());
+ }
+ sb.Append("\n</tokenizedphrase>");
+ return sb.ToString();
+ }
+
+ public override ICharSequence ToQueryString(IEscapeQuerySyntax escapeSyntaxParser)
+ {
+ if (Children == null || Children.Count == 0)
+ return new StringCharSequenceWrapper("");
+
+ StringBuilder sb = new StringBuilder();
+ String filler = "";
+ foreach (IQueryNode child in Children)
+ {
+ sb.Append(filler).Append(child.ToQueryString(escapeSyntaxParser));
+ filler = ",";
+ }
+
+ return new StringCharSequenceWrapper("[TP[" + sb.ToString() + "]]");
+ }
+
+ public override IQueryNode CloneTree()
+ {
+ TokenizedPhraseQueryNode clone = (TokenizedPhraseQueryNode)base.CloneTree();
+
+ // nothing to do
+
+ return clone;
+ }
+
+ public string Field
+ {
+ get
+ {
+ IList<IQueryNode> children = Children;
+
+ if (children == null || children.Count == 0)
+ {
+ return null;
+
+ }
+ else
+ {
+ return ((IFieldableNode)children[0]).Field;
+ }
+ }
+ set
+ {
+ IList<IQueryNode> children = Children;
+
+ 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/539a6ded/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs b/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
index b59540e..4a56a44 100644
--- a/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
+++ b/src/contrib/QueryParsers/Flexible/Core/Parser/ISyntaxParser.cs
@@ -10,6 +10,6 @@ namespace Lucene.Net.QueryParsers.Flexible.Core.Parser
{
public interface ISyntaxParser
{
- IQueryNode Parse(ICharSequence query, ICharSequence field);
+ IQueryNode Parse(string query, string field);
}
}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Processors/IQueryNodeProcessor.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/IQueryNodeProcessor.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/IQueryNodeProcessor.cs
new file mode 100644
index 0000000..c2cd9a4
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/IQueryNodeProcessor.cs
@@ -0,0 +1,17 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using 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.Core.Processors
+{
+ public interface IQueryNodeProcessor
+ {
+ IQueryNode Process(IQueryNode queryTree);
+
+ QueryConfigHandler QueryConfigHandler { get; set; }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Processors/NoChildOptimizationQueryNodeProcessor.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/NoChildOptimizationQueryNodeProcessor.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/NoChildOptimizationQueryNodeProcessor.cs
new file mode 100644
index 0000000..3390b2c
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/NoChildOptimizationQueryNodeProcessor.cs
@@ -0,0 +1,52 @@
+using 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.Core.Processors
+{
+ public class NoChildOptimizationQueryNodeProcessor : QueryNodeProcessor
+ {
+ public NoChildOptimizationQueryNodeProcessor()
+ {
+ // empty constructor
+ }
+
+ protected override IQueryNode PostProcessNode(IQueryNode node)
+ {
+ if (node is BooleanQueryNode || node is BoostQueryNode
+ || node is TokenizedPhraseQueryNode
+ || node is ModifierQueryNode)
+ {
+ IList<IQueryNode> children = node.Children;
+
+ if (children != null && children.Count > 0)
+ {
+ foreach (IQueryNode child in children)
+ {
+ if (!(child is DeletedQueryNode))
+ {
+ return node;
+ }
+ }
+ }
+
+ return new MatchNoDocsQueryNode();
+ }
+
+ return node;
+ }
+
+ protected override IQueryNode PreProcessNode(IQueryNode node)
+ {
+ return node;
+ }
+
+ protected override IList<IQueryNode> SetChildrenOrder(IList<IQueryNode> children)
+ {
+ return children;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessor.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessor.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessor.cs
new file mode 100644
index 0000000..98def49
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessor.cs
@@ -0,0 +1,131 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using 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.Core.Processors
+{
+ public abstract class QueryNodeProcessor : IQueryNodeProcessor
+ {
+ private List<ChildrenList> childrenListPool = new List<ChildrenList>();
+
+ private QueryConfigHandler queryConfig;
+
+ public QueryNodeProcessor()
+ {
+ // empty constructor
+ }
+
+ public QueryNodeProcessor(QueryConfigHandler queryConfigHandler)
+ {
+ this.queryConfig = queryConfigHandler;
+ }
+
+ public virtual IQueryNode Process(IQueryNode queryTree)
+ {
+ return ProcessIteration(queryTree);
+ }
+
+ private IQueryNode ProcessIteration(IQueryNode queryTree)
+ {
+ queryTree = PreProcessNode(queryTree);
+
+ ProcessChildren(queryTree);
+
+ queryTree = PostProcessNode(queryTree);
+
+ return queryTree;
+ }
+
+ protected void ProcessChildren(IQueryNode queryTree)
+ {
+ IList<IQueryNode> children = queryTree.Children;
+ ChildrenList newChildren;
+
+ if (children != null && children.Count > 0)
+ {
+ newChildren = AllocateChildrenList();
+
+ try
+ {
+ IQueryNode child;
+
+ // .NET Port: can't modify range variable, changed to for loop
+ for (int i = 0; i < children.Count; i++)
+ {
+ child = children[i];
+
+ child = ProcessIteration(child);
+
+ if (child == null)
+ {
+ throw new NullReferenceException();
+ }
+
+ newChildren.Add(child);
+ }
+
+ IList<IQueryNode> orderedChildrenList = SetChildrenOrder(newChildren);
+
+ queryTree.Set(orderedChildrenList);
+ }
+ finally
+ {
+ newChildren.beingUsed = false;
+ }
+ }
+ }
+
+ private ChildrenList AllocateChildrenList()
+ {
+ ChildrenList list = null;
+
+ foreach (ChildrenList auxList in this.childrenListPool)
+ {
+ if (!auxList.beingUsed)
+ {
+ list = auxList;
+ list.Clear();
+
+ break;
+ }
+ }
+
+ if (list == null)
+ {
+ list = new ChildrenList();
+ this.childrenListPool.Add(list);
+ }
+
+ list.beingUsed = true;
+
+ return list;
+ }
+
+ public QueryConfigHandler QueryConfigHandler
+ {
+ get
+ {
+ return this.queryConfig;
+ }
+ set
+ {
+ this.queryConfig = value;
+ }
+ }
+
+ protected abstract IQueryNode PreProcessNode(IQueryNode node);
+
+ protected abstract IQueryNode PostProcessNode(IQueryNode node);
+
+ protected abstract IList<IQueryNode> SetChildrenOrder(IList<IQueryNode> children);
+
+ private class ChildrenList : List<IQueryNode>
+ {
+ internal bool beingUsed;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessorPipeline.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessorPipeline.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessorPipeline.cs
new file mode 100644
index 0000000..d674ce9
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/QueryNodeProcessorPipeline.cs
@@ -0,0 +1,180 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using 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.Core.Processors
+{
+ public class QueryNodeProcessorPipeline : IQueryNodeProcessor, IList<IQueryNodeProcessor>
+ {
+ private List<IQueryNodeProcessor> processors = new List<IQueryNodeProcessor>();
+
+ private QueryConfigHandler queryConfig;
+
+ public QueryNodeProcessorPipeline()
+ {
+ // empty constructor
+ }
+
+ public QueryNodeProcessorPipeline(QueryConfigHandler queryConfigHandler)
+ {
+ this.queryConfig = queryConfigHandler;
+ }
+
+ public QueryConfigHandler QueryConfigHandler
+ {
+ get
+ {
+ return this.queryConfig;
+ }
+ set
+ {
+ this.queryConfig = value;
+
+ foreach (IQueryNodeProcessor processor in this.processors)
+ {
+ processor.QueryConfigHandler = this.queryConfig;
+ }
+ }
+ }
+
+ public IQueryNode Process(IQueryNode queryTree)
+ {
+ foreach (IQueryNodeProcessor processor in this.processors)
+ {
+ queryTree = processor.Process(queryTree);
+ }
+
+ return queryTree;
+ }
+
+ public void Add(IQueryNodeProcessor processor)
+ {
+ this.processors.Add(processor);
+
+ processor.QueryConfigHandler = this.queryConfig;
+ }
+
+ public void Insert(int index, IQueryNodeProcessor processor)
+ {
+ this.processors.Insert(index, processor);
+ processor.QueryConfigHandler = this.queryConfig;
+ }
+
+ public bool AddAll(ICollection<IQueryNodeProcessor> c)
+ {
+ this.processors.AddRange(c);
+
+ foreach (IQueryNodeProcessor processor in c)
+ {
+ processor.QueryConfigHandler = this.queryConfig;
+ }
+
+ return c.Count > 0;
+ }
+
+ public bool AddAll(int index, ICollection<IQueryNodeProcessor> c)
+ {
+ this.processors.InsertRange(index, c);
+
+ foreach (IQueryNodeProcessor processor in c)
+ {
+ processor.QueryConfigHandler = this.queryConfig;
+ }
+
+ return c.Count > 0;
+ }
+
+ public void Clear()
+ {
+ this.processors.Clear();
+ }
+
+ public bool Contains(IQueryNodeProcessor item)
+ {
+ return this.processors.Contains(item);
+ }
+
+ public bool ContainsAll(ICollection<IQueryNodeProcessor> c)
+ {
+ foreach (var processor in c)
+ {
+ if (!this.processors.Contains(processor))
+ return false;
+ }
+
+ return true;
+ }
+
+ public IQueryNodeProcessor this[int index]
+ {
+ get
+ {
+ return this.processors[index];
+ }
+ set
+ {
+ IQueryNodeProcessor oldProcessor = (this.processors.Count > index) ? this.processors[index] : value;
+ this.processors[index] = value;
+
+ if (oldProcessor != value)
+ {
+ value.QueryConfigHandler = this.queryConfig;
+ }
+ }
+ }
+
+ public int IndexOf(IQueryNodeProcessor item)
+ {
+ return this.processors.IndexOf(item);
+ }
+
+ public bool IsEmpty
+ {
+ get { return this.processors.Count == 0; }
+ }
+
+ public IEnumerator<IQueryNodeProcessor> GetEnumerator()
+ {
+ return this.processors.GetEnumerator();
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public int LastIndexOf(IQueryNodeProcessor o)
+ {
+ return this.processors.LastIndexOf(o);
+ }
+
+ public bool Remove(IQueryNodeProcessor item)
+ {
+ return this.processors.Remove(item);
+ }
+
+ public void RemoveAt(int index)
+ {
+ this.processors.RemoveAt(index);
+ }
+
+ public int Count
+ {
+ get { return this.processors.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+
+ public void CopyTo(IQueryNodeProcessor[] array, int arrayIndex)
+ {
+ ((IList<IQueryNodeProcessor>)this.processors).CopyTo(array, arrayIndex);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs b/src/contrib/QueryParsers/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
new file mode 100644
index 0000000..106f075
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/Processors/RemoveDeletedQueryNodesProcessor.cs
@@ -0,0 +1,82 @@
+using 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.Core.Processors
+{
+ public class RemoveDeletedQueryNodesProcessor : QueryNodeProcessor
+ {
+ public RemoveDeletedQueryNodesProcessor()
+ {
+ // empty constructor
+ }
+
+ public override IQueryNode Process(IQueryNode queryTree)
+ {
+ queryTree = base.Process(queryTree);
+
+ if (queryTree is DeletedQueryNode
+ && !(queryTree is MatchNoDocsQueryNode))
+ {
+ return new MatchNoDocsQueryNode();
+ }
+
+ return queryTree;
+ }
+
+ protected override IQueryNode PostProcessNode(IQueryNode node)
+ {
+ if (!node.IsLeaf)
+ {
+ IList<IQueryNode> children = node.Children;
+ bool removeBoolean = false;
+
+ if (children == null || children.Count == 0)
+ {
+ removeBoolean = true;
+ }
+ else
+ {
+ removeBoolean = true;
+
+ foreach (IQueryNode child in children)
+ {
+ if (!(child is DeletedQueryNode))
+ {
+ removeBoolean = false;
+ break;
+ }
+ }
+ }
+
+ if (removeBoolean)
+ {
+ return new DeletedQueryNode();
+ }
+ }
+
+ return node;
+ }
+
+ protected override IList<IQueryNode> SetChildrenOrder(IList<IQueryNode> children)
+ {
+ for (int i = 0; i < children.Count; i++)
+ {
+ if (children[i] is DeletedQueryNode)
+ {
+ children.RemoveAt(i--);
+ }
+ }
+
+ return children;
+ }
+
+ protected override IQueryNode PreProcessNode(IQueryNode node)
+ {
+ return node;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/539a6ded/src/contrib/QueryParsers/Flexible/Core/QueryParserHelper.cs
----------------------------------------------------------------------
diff --git a/src/contrib/QueryParsers/Flexible/Core/QueryParserHelper.cs b/src/contrib/QueryParsers/Flexible/Core/QueryParserHelper.cs
new file mode 100644
index 0000000..97fdd7c
--- /dev/null
+++ b/src/contrib/QueryParsers/Flexible/Core/QueryParserHelper.cs
@@ -0,0 +1,107 @@
+using Lucene.Net.QueryParsers.Flexible.Core.Builders;
+using Lucene.Net.QueryParsers.Flexible.Core.Config;
+using Lucene.Net.QueryParsers.Flexible.Core.Nodes;
+using Lucene.Net.QueryParsers.Flexible.Core.Parser;
+using Lucene.Net.QueryParsers.Flexible.Core.Processors;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Lucene.Net.QueryParsers.Flexible.Core
+{
+ public class QueryParserHelper
+ {
+ private IQueryNodeProcessor processor;
+
+ private ISyntaxParser syntaxParser;
+
+ private IQueryBuilder builder;
+
+ private QueryConfigHandler config;
+
+ public QueryParserHelper(QueryConfigHandler queryConfigHandler, ISyntaxParser syntaxParser, IQueryNodeProcessor processor, IQueryBuilder builder)
+ {
+ this.syntaxParser = syntaxParser;
+ this.config = queryConfigHandler;
+ this.processor = processor;
+ this.builder = builder;
+
+ if (processor != null)
+ {
+ processor.QueryConfigHandler = queryConfigHandler;
+ }
+ }
+
+ public IQueryNodeProcessor QueryNodeProcessor
+ {
+ get
+ {
+ return processor;
+ }
+ set
+ {
+ this.processor = value;
+ this.processor.QueryConfigHandler = QueryConfigHandler;
+ }
+ }
+
+ public ISyntaxParser SyntaxParser
+ {
+ get { return syntaxParser; }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentException("textParser should not be null!");
+ }
+
+ this.syntaxParser = value;
+ }
+ }
+
+ public IQueryBuilder QueryBuilder
+ {
+ get { return builder; }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentException("queryBuilder should not be null!");
+ }
+
+ this.builder = value;
+ }
+ }
+
+ public QueryConfigHandler QueryConfigHandler
+ {
+ get { return config; }
+ set
+ {
+ this.config = value;
+ IQueryNodeProcessor processor = QueryNodeProcessor;
+
+ if (processor != null)
+ {
+ processor.QueryConfigHandler = config;
+ }
+ }
+ }
+
+ public object Parse(string query, string defaultField)
+ {
+ IQueryNode queryTree = SyntaxParser.Parse(query, defaultField);
+
+ IQueryNodeProcessor processor = QueryNodeProcessor;
+
+ if (processor != null)
+ {
+ queryTree = processor.Process(queryTree);
+ }
+
+ return QueryBuilder.Build(queryTree);
+ }
+ }
+}