KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lucene > search > spans > SpanOrQuery


1 package org.apache.lucene.search.spans;
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.io.IOException JavaDoc;
20
21 import java.util.List JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26 import org.apache.lucene.index.IndexReader;
27 import org.apache.lucene.util.PriorityQueue;
28 import org.apache.lucene.util.ToStringUtils;
29 import org.apache.lucene.search.Query;
30
31 /** Matches the union of its clauses.*/
32 public class SpanOrQuery extends SpanQuery {
33   private List JavaDoc clauses;
34   private String JavaDoc field;
35
36   /** Construct a SpanOrQuery merging the provided clauses. */
37   public SpanOrQuery(SpanQuery[] clauses) {
38
39     // copy clauses array into an ArrayList
40
this.clauses = new ArrayList JavaDoc(clauses.length);
41     for (int i = 0; i < clauses.length; i++) {
42       SpanQuery clause = clauses[i];
43       if (i == 0) { // check field
44
field = clause.getField();
45       } else if (!clause.getField().equals(field)) {
46         throw new IllegalArgumentException JavaDoc("Clauses must have same field.");
47       }
48       this.clauses.add(clause);
49     }
50   }
51
52   /** Return the clauses whose spans are matched. */
53   public SpanQuery[] getClauses() {
54     return (SpanQuery[])clauses.toArray(new SpanQuery[clauses.size()]);
55   }
56
57   public String JavaDoc getField() { return field; }
58
59   public Collection JavaDoc getTerms() {
60     Collection JavaDoc terms = new ArrayList JavaDoc();
61     Iterator JavaDoc i = clauses.iterator();
62     while (i.hasNext()) {
63       SpanQuery clause = (SpanQuery)i.next();
64       terms.addAll(clause.getTerms());
65     }
66     return terms;
67   }
68
69   public Query rewrite(IndexReader reader) throws IOException JavaDoc {
70     SpanOrQuery clone = null;
71     for (int i = 0 ; i < clauses.size(); i++) {
72       SpanQuery c = (SpanQuery)clauses.get(i);
73       SpanQuery query = (SpanQuery) c.rewrite(reader);
74       if (query != c) { // clause rewrote: must clone
75
if (clone == null)
76           clone = (SpanOrQuery) this.clone();
77         clone.clauses.set(i,query);
78       }
79     }
80     if (clone != null) {
81       return clone; // some clauses rewrote
82
} else {
83       return this; // no clauses rewrote
84
}
85   }
86
87   public String JavaDoc toString(String JavaDoc field) {
88     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
89     buffer.append("spanOr([");
90     Iterator JavaDoc i = clauses.iterator();
91     while (i.hasNext()) {
92       SpanQuery clause = (SpanQuery)i.next();
93       buffer.append(clause.toString(field));
94       if (i.hasNext()) {
95         buffer.append(", ");
96       }
97     }
98     buffer.append("])");
99     buffer.append(ToStringUtils.boost(getBoost()));
100     return buffer.toString();
101   }
102
103   public boolean equals(Object JavaDoc o) {
104     if (this == o) return true;
105     if (o == null || getClass() != o.getClass()) return false;
106
107     final SpanOrQuery that = (SpanOrQuery) o;
108
109     if (!clauses.equals(that.clauses)) return false;
110     if (!field.equals(that.field)) return false;
111
112     return getBoost() == that.getBoost();
113   }
114
115   public int hashCode() {
116     int h = clauses.hashCode();
117     h ^= (h << 10) | (h >>> 23);
118     h ^= Float.floatToRawIntBits(getBoost());
119     return h;
120   }
121
122   private class SpanQueue extends PriorityQueue {
123     public SpanQueue(int size) {
124       initialize(size);
125     }
126
127     protected final boolean lessThan(Object JavaDoc o1, Object JavaDoc o2) {
128       Spans spans1 = (Spans)o1;
129       Spans spans2 = (Spans)o2;
130       if (spans1.doc() == spans2.doc()) {
131         if (spans1.start() == spans2.start()) {
132           return spans1.end() < spans2.end();
133         } else {
134           return spans1.start() < spans2.start();
135         }
136       } else {
137         return spans1.doc() < spans2.doc();
138       }
139     }
140   }
141
142
143   public Spans getSpans(final IndexReader reader) throws IOException JavaDoc {
144     if (clauses.size() == 1) // optimize 1-clause case
145
return ((SpanQuery)clauses.get(0)).getSpans(reader);
146
147     return new Spans() {
148         private List JavaDoc all = new ArrayList JavaDoc(clauses.size());
149         private SpanQueue queue = new SpanQueue(clauses.size());
150
151         {
152           Iterator JavaDoc i = clauses.iterator();
153           while (i.hasNext()) { // initialize all
154
all.add(((SpanQuery)i.next()).getSpans(reader));
155           }
156         }
157
158         private boolean firstTime = true;
159
160         public boolean next() throws IOException JavaDoc {
161           if (firstTime) { // first time -- initialize
162
for (int i = 0; i < all.size(); i++) {
163               Spans spans = (Spans)all.get(i);
164               if (spans.next()) { // move to first entry
165
queue.put(spans); // build queue
166
} else {
167                 all.remove(i--);
168               }
169             }
170             firstTime = false;
171             return queue.size() != 0;
172           }
173
174           if (queue.size() == 0) { // all done
175
return false;
176           }
177
178           if (top().next()) { // move to next
179
queue.adjustTop();
180             return true;
181           }
182
183           all.remove(queue.pop()); // exhausted a clause
184

185           return queue.size() != 0;
186         }
187
188         private Spans top() { return (Spans)queue.top(); }
189
190         public boolean skipTo(int target) throws IOException JavaDoc {
191           if (firstTime) {
192             for (int i = 0; i < all.size(); i++) {
193               Spans spans = (Spans)all.get(i);
194               if (spans.skipTo(target)) { // skip each spans in all
195
queue.put(spans); // build queue
196
} else {
197                 all.remove(i--);
198               }
199             }
200             firstTime = false;
201           } else {
202             while (queue.size() != 0 && top().doc() < target) {
203               if (top().skipTo(target)) {
204                 queue.adjustTop();
205               } else {
206                 all.remove(queue.pop());
207               }
208             }
209           }
210
211           return queue.size() != 0;
212         }
213
214         public int doc() { return top().doc(); }
215         public int start() { return top().start(); }
216         public int end() { return top().end(); }
217
218         public String JavaDoc toString() {
219           return "spans("+SpanOrQuery.this+")@"+
220             (firstTime?"START"
221              :(queue.size()>0?(doc()+":"+start()+"-"+end()):"END"));
222         }
223
224       };
225   }
226
227 }
228
Popular Tags