1 package org.apache.lucene.search.spans;
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 import org.apache.lucene.index.IndexReader;
21 import org.apache.lucene.index.Term;
22 import org.apache.lucene.search.Query;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collection;
34 public abstract class SpanPositionCheckQuery extends SpanQuery implements Cloneable {
35 protected SpanQuery match;
38 public SpanPositionCheckQuery(SpanQuery match) {
43 * @return the SpanQuery whose matches are filtered.
46 public SpanQuery getMatch() { return match; }
51 public String getField() { return match.getField(); }
56 public void extractTerms(Set<Term> terms) {
57 match.extractTerms(terms);
60 /** Return value if the match should be accepted {@code YES}, rejected {@code NO},
61 * or rejected and enumeration should advance to the next document {@code NO_AND_ADVANCE}.
62 * @see #acceptPosition(Spans)
64 protected static enum AcceptStatus { YES, NO, NO_AND_ADVANCE };
67 * Implementing classes are required to return whether the current position is a match for the passed in
68 * "match" {@link org.apache.lucene.search.spans.SpanQuery}.
70 * This is only called if the underlying {@link org.apache.lucene.search.spans.Spans#next()} for the
74 * @param spans The {@link org.apache.lucene.search.spans.Spans} instance, positioned at the spot to check
75 * @return whether the match is accepted, rejected, or rejected and should move to the next doc.
77 * @see org.apache.lucene.search.spans.Spans#next()
80 protected abstract AcceptStatus acceptPosition(Spans spans) throws IOException;
83 public Spans getSpans(final IndexReader reader) throws IOException {
84 return new PositionCheckSpan(reader);
89 public Query rewrite(IndexReader reader) throws IOException {
90 SpanPositionCheckQuery clone = null;
92 SpanQuery rewritten = (SpanQuery) match.rewrite(reader);
93 if (rewritten != match) {
94 clone = (SpanPositionCheckQuery) this.clone();
95 clone.match = rewritten;
99 return clone; // some clauses rewrote
101 return this; // no clauses rewrote
105 protected class PositionCheckSpan extends Spans {
108 public PositionCheckSpan(IndexReader reader) throws IOException {
109 spans = match.getSpans(reader);
113 public boolean next() throws IOException {
121 public boolean skipTo(int target) throws IOException {
122 if (!spans.skipTo(target))
128 protected boolean doNext() throws IOException {
130 switch(acceptPosition(this)) {
131 case YES: return true;
137 if (!spans.skipTo(spans.doc()+1))
145 public int doc() { return spans.doc(); }
148 public int start() { return spans.start(); }
151 public int end() { return spans.end(); }
152 // TODO: Remove warning after API has been finalized
155 public Collection<byte[]> getPayload() throws IOException {
156 ArrayList<byte[]> result = null;
157 if (spans.isPayloadAvailable()) {
158 result = new ArrayList<byte[]>(spans.getPayload());
160 return result;//TODO: any way to avoid the new construction?
162 // TODO: Remove warning after API has been finalized
165 public boolean isPayloadAvailable() {
166 return spans.isPayloadAvailable();
170 public String toString() {
171 return "spans(" + SpanPositionCheckQuery.this.toString() + ")";