add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / search / TermRangeTermEnum.java
1 package org.apache.lucene.search;
2
3 /**
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 import java.io.IOException;
21 import java.text.Collator;
22
23 import org.apache.lucene.index.IndexReader;
24 import org.apache.lucene.index.Term;
25 import org.apache.lucene.util.StringHelper;
26
27 /**
28  * Subclass of FilteredTermEnum for enumerating all terms that match the
29  * specified range parameters.
30  * <p>
31  * Term enumerations are always ordered by Term.compareTo().  Each term in
32  * the enumeration is greater than all that precede it.
33  * @since 2.9
34  */
35 public class TermRangeTermEnum extends FilteredTermEnum {
36
37   private Collator collator = null;
38   private boolean endEnum = false;
39   private String field;
40   private String upperTermText;
41   private String lowerTermText;
42   private boolean includeLower;
43   private boolean includeUpper;
44
45   /**
46    * Enumerates all terms greater/equal than <code>lowerTerm</code>
47    * but less/equal than <code>upperTerm</code>. 
48    * 
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.)
53    * 
54    * @param reader
55    * @param field
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
61    * @param includeLower
62    *          If true, the <code>lowerTerm</code> is included in the range.
63    * @param includeUpper
64    *          If true, the <code>upperTerm</code> is included in the range.
65    * @param collator
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>.
69    * 
70    * @throws IOException
71    */
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);
80     
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;
86     }
87     
88     if (this.upperTermText == null) {
89       this.includeUpper = true;
90     }
91
92     String startTermText = collator == null ? this.lowerTermText : "";
93     setEnum(reader.terms(new Term(this.field, startTermText)));
94   }
95
96   @Override
97   public float difference() {
98     return 1.0f;
99   }
100
101   @Override
102   protected boolean endEnum() {
103     return endEnum;
104   }
105
106   @Override
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
112         checkLower = true;
113       if (term != null && term.field() == field) { // interned comparison
114         if (!checkLower || null==lowerTermText || term.text().compareTo(lowerTermText) > 0) {
115           checkLower = false;
116           if (upperTermText != null) {
117             int compare = upperTermText.compareTo(term.text());
118             /*
119              * if beyond the upper term, or is exclusive and this is equal to
120              * the upper term, break out
121              */
122             if ((compare < 0) ||
123                 (!includeUpper && compare==0)) {
124               endEnum = true;
125               return false;
126             }
127           }
128           return true;
129         }
130       } else {
131         // break
132         endEnum = true;
133         return false;
134       }
135       return false;
136     } else {
137       if (term != null && term.field() == field) { // interned comparison
138         if ((lowerTermText == null
139             || (includeLower
140                 ? collator.compare(term.text(), lowerTermText) >= 0
141                 : collator.compare(term.text(), lowerTermText) > 0))
142            && (upperTermText == null
143                || (includeUpper
144                    ? collator.compare(term.text(), upperTermText) <= 0
145                    : collator.compare(term.text(), upperTermText) < 0))) {
146           return true;
147         }
148         return false;
149       }
150       endEnum = true;
151       return false;
152     }
153   }
154 }