001: package org.apache.lucene.search.spans;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import java.io.IOException;
021:
022: import java.util.Collection;
023: import java.util.Set;
024:
025: import org.apache.lucene.index.IndexReader;
026: import org.apache.lucene.search.Query;
027: import org.apache.lucene.util.ToStringUtils;
028:
029: /** Matches spans near the beginning of a field. */
030: public class SpanFirstQuery extends SpanQuery {
031: private SpanQuery match;
032: private int end;
033:
034: /** Construct a SpanFirstQuery matching spans in <code>match</code> whose end
035: * position is less than or equal to <code>end</code>. */
036: public SpanFirstQuery(SpanQuery match, int end) {
037: this .match = match;
038: this .end = end;
039: }
040:
041: /** Return the SpanQuery whose matches are filtered. */
042: public SpanQuery getMatch() {
043: return match;
044: }
045:
046: /** Return the maximum end position permitted in a match. */
047: public int getEnd() {
048: return end;
049: }
050:
051: public String getField() {
052: return match.getField();
053: }
054:
055: /** Returns a collection of all terms matched by this query.
056: * @deprecated use extractTerms instead
057: * @see #extractTerms(Set)
058: */
059: public Collection getTerms() {
060: return match.getTerms();
061: }
062:
063: public String toString(String field) {
064: StringBuffer buffer = new StringBuffer();
065: buffer.append("spanFirst(");
066: buffer.append(match.toString(field));
067: buffer.append(", ");
068: buffer.append(end);
069: buffer.append(")");
070: buffer.append(ToStringUtils.boost(getBoost()));
071: return buffer.toString();
072: }
073:
074: public void extractTerms(Set terms) {
075: match.extractTerms(terms);
076: }
077:
078: public Spans getSpans(final IndexReader reader) throws IOException {
079: return new Spans() {
080: private Spans spans = match.getSpans(reader);
081:
082: public boolean next() throws IOException {
083: while (spans.next()) { // scan to next match
084: if (end() <= end)
085: return true;
086: }
087: return false;
088: }
089:
090: public boolean skipTo(int target) throws IOException {
091: if (!spans.skipTo(target))
092: return false;
093:
094: if (spans.end() <= end) // there is a match
095: return true;
096:
097: return next(); // scan to next match
098: }
099:
100: public int doc() {
101: return spans.doc();
102: }
103:
104: public int start() {
105: return spans.start();
106: }
107:
108: public int end() {
109: return spans.end();
110: }
111:
112: public String toString() {
113: return "spans(" + SpanFirstQuery.this .toString() + ")";
114: }
115:
116: };
117: }
118:
119: public Query rewrite(IndexReader reader) throws IOException {
120: SpanFirstQuery clone = null;
121:
122: SpanQuery rewritten = (SpanQuery) match.rewrite(reader);
123: if (rewritten != match) {
124: clone = (SpanFirstQuery) this .clone();
125: clone.match = rewritten;
126: }
127:
128: if (clone != null) {
129: return clone; // some clauses rewrote
130: } else {
131: return this ; // no clauses rewrote
132: }
133: }
134:
135: public boolean equals(Object o) {
136: if (this == o)
137: return true;
138: if (!(o instanceof SpanFirstQuery))
139: return false;
140:
141: SpanFirstQuery other = (SpanFirstQuery) o;
142: return this .end == other.end && this .match.equals(other.match)
143: && this .getBoost() == other.getBoost();
144: }
145:
146: public int hashCode() {
147: int h = match.hashCode();
148: h ^= (h << 8) | (h >>> 25); // reversible
149: h ^= Float.floatToRawIntBits(getBoost()) ^ end;
150: return h;
151: }
152:
153: }
|