add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / search / spans / SpanPositionCheckQuery.java
1 package org.apache.lucene.search.spans;
2 /**
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
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
20 import org.apache.lucene.index.IndexReader;
21 import org.apache.lucene.index.Term;
22 import org.apache.lucene.search.Query;
23
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Set;
28
29
30 /**
31  *
32  *
33  **/
34 public abstract class SpanPositionCheckQuery extends SpanQuery implements Cloneable {
35   protected SpanQuery match;
36
37
38   public SpanPositionCheckQuery(SpanQuery match) {
39     this.match = match;
40   }
41
42   /**
43    * @return the SpanQuery whose matches are filtered.
44    *
45    * */
46   public SpanQuery getMatch() { return match; }
47
48
49
50   @Override
51   public String getField() { return match.getField(); }
52
53
54
55   @Override
56   public void extractTerms(Set<Term> terms) {
57             match.extractTerms(terms);
58   }
59
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)
63    */
64   protected static enum AcceptStatus { YES, NO, NO_AND_ADVANCE };
65   
66   /**
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}.
69    *
70    * This is only called if the underlying {@link org.apache.lucene.search.spans.Spans#next()} for the
71    * match is successful
72    *
73    *
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.
76    *
77    * @see org.apache.lucene.search.spans.Spans#next()
78    *
79    */
80   protected abstract AcceptStatus acceptPosition(Spans spans) throws IOException;
81
82   @Override
83   public Spans getSpans(final IndexReader reader) throws IOException {
84     return new PositionCheckSpan(reader);
85   }
86
87
88   @Override
89   public Query rewrite(IndexReader reader) throws IOException {
90     SpanPositionCheckQuery clone = null;
91
92     SpanQuery rewritten = (SpanQuery) match.rewrite(reader);
93     if (rewritten != match) {
94       clone = (SpanPositionCheckQuery) this.clone();
95       clone.match = rewritten;
96     }
97
98     if (clone != null) {
99       return clone;                        // some clauses rewrote
100     } else {
101       return this;                         // no clauses rewrote
102     }
103   }
104
105   protected class PositionCheckSpan extends Spans {
106     private Spans spans;
107
108     public PositionCheckSpan(IndexReader reader) throws IOException {
109       spans = match.getSpans(reader);
110     }
111
112     @Override
113     public boolean next() throws IOException {
114       if (!spans.next())
115         return false;
116       
117       return doNext();
118     }
119
120     @Override
121     public boolean skipTo(int target) throws IOException {
122       if (!spans.skipTo(target))
123         return false;
124
125       return doNext();
126     }
127     
128     protected boolean doNext() throws IOException {
129       for (;;) {
130         switch(acceptPosition(this)) {
131           case YES: return true;
132           case NO: 
133             if (!spans.next()) 
134               return false;
135             break;
136           case NO_AND_ADVANCE: 
137             if (!spans.skipTo(spans.doc()+1)) 
138               return false;
139             break;
140         }
141       }
142     }
143
144     @Override
145     public int doc() { return spans.doc(); }
146
147     @Override
148     public int start() { return spans.start(); }
149
150     @Override
151     public int end() { return spans.end(); }
152     // TODO: Remove warning after API has been finalized
153
154     @Override
155     public Collection<byte[]> getPayload() throws IOException {
156       ArrayList<byte[]> result = null;
157       if (spans.isPayloadAvailable()) {
158         result = new ArrayList<byte[]>(spans.getPayload());
159       }
160       return result;//TODO: any way to avoid the new construction?
161     }
162     // TODO: Remove warning after API has been finalized
163
164     @Override
165     public boolean isPayloadAvailable() {
166       return spans.isPayloadAvailable();
167     }
168
169     @Override
170     public String toString() {
171         return "spans(" + SpanPositionCheckQuery.this.toString() + ")";
172       }
173
174   }
175 }