KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lucene > search > RangeFilter


1 package org.apache.lucene.search;
2
3 /**
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.util.BitSet JavaDoc;
20 import java.io.IOException JavaDoc;
21
22 import org.apache.lucene.search.Filter;
23 import org.apache.lucene.index.Term;
24 import org.apache.lucene.index.TermDocs;
25 import org.apache.lucene.index.TermEnum;
26 import org.apache.lucene.index.IndexReader;
27
28 /**
29  * A Filter that restricts search results to a range of values in a given
30  * field.
31  *
32  * <p>
33  * This code borrows heavily from {@link RangeQuery}, but is implemented as a Filter
34  * (much like {@link DateFilter}).
35  * </p>
36  */

37 public class RangeFilter extends Filter {
38     
39     private String JavaDoc fieldName;
40     private String JavaDoc lowerTerm;
41     private String JavaDoc upperTerm;
42     private boolean includeLower;
43     private boolean includeUpper;
44
45     /**
46      * @param fieldName The field this range applies to
47      * @param lowerTerm The lower bound on this range
48      * @param upperTerm The upper bound on this range
49      * @param includeLower Does this range include the lower bound?
50      * @param includeUpper Does this range include the upper bound?
51      * @throws IllegalArgumentException if both terms are null or if
52      * lowerTerm is null and includeLower is true (similar for upperTerm
53      * and includeUpper)
54      */

55     public RangeFilter(String JavaDoc fieldName, String JavaDoc lowerTerm, String JavaDoc upperTerm,
56                        boolean includeLower, boolean includeUpper) {
57         this.fieldName = fieldName;
58         this.lowerTerm = lowerTerm;
59         this.upperTerm = upperTerm;
60         this.includeLower = includeLower;
61         this.includeUpper = includeUpper;
62         
63         if (null == lowerTerm && null == upperTerm) {
64             throw new IllegalArgumentException JavaDoc
65                 ("At least one value must be non-null");
66         }
67         if (includeLower && null == lowerTerm) {
68             throw new IllegalArgumentException JavaDoc
69                 ("The lower bound must be non-null to be inclusive");
70         }
71         if (includeUpper && null == upperTerm) {
72             throw new IllegalArgumentException JavaDoc
73                 ("The upper bound must be non-null to be inclusive");
74         }
75     }
76     
77     /**
78      * Constructs a filter for field <code>fieldName</code> matching
79      * less than or equal to <code>upperTerm</code>.
80      */

81     public static RangeFilter Less(String JavaDoc fieldName, String JavaDoc upperTerm) {
82         return new RangeFilter(fieldName, null, upperTerm, false, true);
83     }
84
85     /**
86      * Constructs a filter for field <code>fieldName</code> matching
87      * greater than or equal to <code>lowerTerm</code>.
88      */

89     public static RangeFilter More(String JavaDoc fieldName, String JavaDoc lowerTerm) {
90         return new RangeFilter(fieldName, lowerTerm, null, true, false);
91     }
92     
93     /**
94      * Returns a BitSet with true for documents which should be
95      * permitted in search results, and false for those that should
96      * not.
97      */

98     public BitSet JavaDoc bits(IndexReader reader) throws IOException JavaDoc {
99         BitSet JavaDoc bits = new BitSet JavaDoc(reader.maxDoc());
100         TermEnum enumerator =
101             (null != lowerTerm
102              ? reader.terms(new Term(fieldName, lowerTerm))
103              : reader.terms(new Term(fieldName,"")));
104         
105         try {
106             
107             if (enumerator.term() == null) {
108                 return bits;
109             }
110             
111             boolean checkLower = false;
112             if (!includeLower) // make adjustments to set to exclusive
113
checkLower = true;
114         
115             TermDocs termDocs = reader.termDocs();
116             try {
117                 
118                 do {
119                     Term term = enumerator.term();
120                     if (term != null && term.field().equals(fieldName)) {
121                         if (!checkLower || null==lowerTerm || term.text().compareTo(lowerTerm) > 0) {
122                             checkLower = false;
123                             if (upperTerm != null) {
124                                 int compare = upperTerm.compareTo(term.text());
125                                 /* if beyond the upper term, or is exclusive and
126                                  * this is equal to the upper term, break out */

127                                 if ((compare < 0) ||
128                                     (!includeUpper && compare==0)) {
129                                     break;
130                                 }
131                             }
132                             /* we have a good term, find the docs */
133                             
134                             termDocs.seek(enumerator.term());
135                             while (termDocs.next()) {
136                                 bits.set(termDocs.doc());
137                             }
138                         }
139                     } else {
140                         break;
141                     }
142                 }
143                 while (enumerator.next());
144                 
145             } finally {
146                 termDocs.close();
147             }
148         } finally {
149             enumerator.close();
150         }
151
152         return bits;
153     }
154     
155     public String JavaDoc toString() {
156         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
157         buffer.append(fieldName);
158         buffer.append(":");
159         buffer.append(includeLower ? "[" : "{");
160         if (null != lowerTerm) {
161             buffer.append(lowerTerm);
162         }
163         buffer.append("-");
164         if (null != upperTerm) {
165             buffer.append(upperTerm);
166         }
167         buffer.append(includeUpper ? "]" : "}");
168         return buffer.toString();
169     }
170
171     /** Returns true if <code>o</code> is equal to this. */
172     public boolean equals(Object JavaDoc o) {
173         if (this == o) return true;
174         if (!(o instanceof RangeFilter)) return false;
175         RangeFilter other = (RangeFilter) o;
176
177         if (!this.fieldName.equals(other.fieldName)
178             || this.includeLower != other.includeLower
179             || this.includeUpper != other.includeUpper
180            ) { return false; }
181         if (this.lowerTerm != null ? !this.lowerTerm.equals(other.lowerTerm) : other.lowerTerm != null) return false;
182         if (this.upperTerm != null ? !this.upperTerm.equals(other.upperTerm) : other.upperTerm != null) return false;
183         return true;
184     }
185
186     /** Returns a hash code value for this object.*/
187     public int hashCode() {
188       int h = fieldName.hashCode();
189       h ^= lowerTerm != null ? lowerTerm.hashCode() : 0xB6ECE882;
190       h = (h << 1) | (h >>> 31); // rotate to distinguish lower from upper
191
h ^= (upperTerm != null ? (upperTerm.hashCode()) : 0x91BEC2C2);
192       h ^= (includeLower ? 0xD484B933 : 0)
193          ^ (includeUpper ? 0x6AE423AC : 0);
194       return h;
195     }
196 }
197
Popular Tags