| /* |
| * 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. |
| */ |
| |
| using System; |
| |
| using IndexReader = Lucene.Net.Index.IndexReader; |
| using Term = Lucene.Net.Index.Term; |
| using StringHelper = Lucene.Net.Util.StringHelper; |
| |
| namespace Lucene.Net.Search |
| { |
| |
| /// <summary> Subclass of FilteredTermEnum for enumerating all terms that match the |
| /// specified range parameters. |
| /// <p/> |
| /// Term enumerations are always ordered by Term.compareTo(). Each term in |
| /// the enumeration is greater than all that precede it. |
| /// </summary> |
| /// <since> 2.9 |
| /// </since> |
| public class TermRangeTermEnum:FilteredTermEnum |
| { |
| |
| private System.Globalization.CompareInfo collator = null; |
| private bool endEnum = false; |
| private System.String field; |
| private System.String upperTermText; |
| private System.String lowerTermText; |
| private bool includeLower; |
| private bool includeUpper; |
| |
| /// <summary> Enumerates all terms greater/equal than <c>lowerTerm</c> |
| /// but less/equal than <c>upperTerm</c>. |
| /// |
| /// If an endpoint is null, it is said to be "open". Either or both |
| /// endpoints may be open. Open endpoints may not be exclusive |
| /// (you can't select all but the first or last term without |
| /// explicitly specifying the term to exclude.) |
| /// |
| /// </summary> |
| /// <param name="reader"> |
| /// </param> |
| /// <param name="field">An interned field that holds both lower and upper terms. |
| /// </param> |
| /// <param name="lowerTermText">The term text at the lower end of the range |
| /// </param> |
| /// <param name="upperTermText">The term text at the upper end of the range |
| /// </param> |
| /// <param name="includeLower">If true, the <c>lowerTerm</c> is included in the range. |
| /// </param> |
| /// <param name="includeUpper">If true, the <c>upperTerm</c> is included in the range. |
| /// </param> |
| /// <param name="collator">The collator to use to collate index Terms, to determine their |
| /// membership in the range bounded by <c>lowerTerm</c> and |
| /// <c>upperTerm</c>. |
| /// |
| /// </param> |
| /// <throws> IOException </throws> |
| public TermRangeTermEnum(IndexReader reader, System.String field, System.String lowerTermText, System.String upperTermText, bool includeLower, bool includeUpper, System.Globalization.CompareInfo collator) |
| { |
| this.collator = collator; |
| this.upperTermText = upperTermText; |
| this.lowerTermText = lowerTermText; |
| this.includeLower = includeLower; |
| this.includeUpper = includeUpper; |
| this.field = StringHelper.Intern(field); |
| |
| // do a little bit of normalization... |
| // open ended range queries should always be inclusive. |
| if (this.lowerTermText == null) |
| { |
| this.lowerTermText = ""; |
| this.includeLower = true; |
| } |
| |
| if (this.upperTermText == null) |
| { |
| this.includeUpper = true; |
| } |
| |
| System.String startTermText = collator == null?this.lowerTermText:""; |
| SetEnum(reader.Terms(new Term(this.field, startTermText))); |
| } |
| |
| public override float Difference() |
| { |
| return 1.0f; |
| } |
| |
| public override bool EndEnum() |
| { |
| return endEnum; |
| } |
| |
| protected internal override bool TermCompare(Term term) |
| { |
| if (collator == null) |
| { |
| // Use Unicode code point ordering |
| bool checkLower = !includeLower; |
| if (term != null && (System.Object) term.Field == (System.Object) field) |
| { |
| // interned comparison |
| if (!checkLower || null == lowerTermText || String.CompareOrdinal(term.Text, lowerTermText) > 0) |
| { |
| checkLower = false; |
| if (upperTermText != null) |
| { |
| int compare = String.CompareOrdinal(upperTermText, term.Text); |
| /* |
| * if beyond the upper term, or is exclusive and this is equal to |
| * the upper term, break out |
| */ |
| if ((compare < 0) || (!includeUpper && compare == 0)) |
| { |
| endEnum = true; |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| else |
| { |
| // break |
| endEnum = true; |
| return false; |
| } |
| return false; |
| } |
| else |
| { |
| if (term != null && (System.Object) term.Field == (System.Object) field) |
| { |
| // interned comparison |
| if ((lowerTermText == null || (includeLower?collator.Compare(term.Text.ToString(), lowerTermText.ToString()) >= 0:collator.Compare(term.Text.ToString(), lowerTermText.ToString()) > 0)) && (upperTermText == null || (includeUpper?collator.Compare(term.Text.ToString(), upperTermText.ToString()) <= 0:collator.Compare(term.Text.ToString(), upperTermText.ToString()) < 0))) |
| { |
| return true; |
| } |
| return false; |
| } |
| endEnum = true; |
| return false; |
| } |
| } |
| } |
| } |