1 package org.apache.lucene.search;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.IOException;
21 import java.text.Collator;
23 import org.apache.lucene.index.IndexReader;
24 import org.apache.lucene.index.Term;
25 import org.apache.lucene.util.StringHelper;
28 * Subclass of FilteredTermEnum for enumerating all terms that match the
29 * specified range parameters.
31 * Term enumerations are always ordered by Term.compareTo(). Each term in
32 * the enumeration is greater than all that precede it.
35 public class TermRangeTermEnum extends FilteredTermEnum {
37 private Collator collator = null;
38 private boolean endEnum = false;
40 private String upperTermText;
41 private String lowerTermText;
42 private boolean includeLower;
43 private boolean includeUpper;
46 * Enumerates all terms greater/equal than <code>lowerTerm</code>
47 * but less/equal than <code>upperTerm</code>.
49 * If an endpoint is null, it is said to be "open". Either or both
50 * endpoints may be open. Open endpoints may not be exclusive
51 * (you can't select all but the first or last term without
52 * explicitly specifying the term to exclude.)
56 * An interned field that holds both lower and upper terms.
57 * @param lowerTermText
58 * The term text at the lower end of the range
59 * @param upperTermText
60 * The term text at the upper end of the range
62 * If true, the <code>lowerTerm</code> is included in the range.
64 * If true, the <code>upperTerm</code> is included in the range.
66 * The collator to use to collate index Terms, to determine their
67 * membership in the range bounded by <code>lowerTerm</code> and
68 * <code>upperTerm</code>.
72 public TermRangeTermEnum(IndexReader reader, String field, String lowerTermText, String upperTermText,
73 boolean includeLower, boolean includeUpper, Collator collator) throws IOException {
74 this.collator = collator;
75 this.upperTermText = upperTermText;
76 this.lowerTermText = lowerTermText;
77 this.includeLower = includeLower;
78 this.includeUpper = includeUpper;
79 this.field = StringHelper.intern(field);
81 // do a little bit of normalization...
82 // open ended range queries should always be inclusive.
83 if (this.lowerTermText == null) {
84 this.lowerTermText = "";
85 this.includeLower = true;
88 if (this.upperTermText == null) {
89 this.includeUpper = true;
92 String startTermText = collator == null ? this.lowerTermText : "";
93 setEnum(reader.terms(new Term(this.field, startTermText)));
97 public float difference() {
102 protected boolean endEnum() {
107 protected boolean termCompare(Term term) {
108 if (collator == null) {
109 // Use Unicode code point ordering
110 boolean checkLower = false;
111 if (!includeLower) // make adjustments to set to exclusive
113 if (term != null && term.field() == field) { // interned comparison
114 if (!checkLower || null==lowerTermText || term.text().compareTo(lowerTermText) > 0) {
116 if (upperTermText != null) {
117 int compare = upperTermText.compareTo(term.text());
119 * if beyond the upper term, or is exclusive and this is equal to
120 * the upper term, break out
123 (!includeUpper && compare==0)) {
137 if (term != null && term.field() == field) { // interned comparison
138 if ((lowerTermText == null
140 ? collator.compare(term.text(), lowerTermText) >= 0
141 : collator.compare(term.text(), lowerTermText) > 0))
142 && (upperTermText == null
144 ? collator.compare(term.text(), upperTermText) <= 0
145 : collator.compare(term.text(), upperTermText) < 0))) {