1 package org.apache.lucene.index;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import org.apache.lucene.document.Document;
21 import org.apache.lucene.document.FieldSelector;
22 import org.apache.lucene.store.Directory;
23 import org.apache.lucene.util.MapBackedSet;
25 import java.io.IOException;
26 import java.util.Collection;
28 import java.util.concurrent.ConcurrentHashMap;
30 /** A <code>FilterIndexReader</code> contains another IndexReader, which it
31 * uses as its basic source of data, possibly transforming the data along the
32 * way or providing additional functionality. The class
33 * <code>FilterIndexReader</code> itself simply implements all abstract methods
34 * of <code>IndexReader</code> with versions that pass all requests to the
35 * contained index reader. Subclasses of <code>FilterIndexReader</code> may
36 * further override some of these methods and may also provide additional
38 * <p><b>Note:</b> The default implementation of {@link FilterIndexReader#doOpenIfChanged}
39 * throws {@link UnsupportedOperationException} (like the base class),
40 * so it's not possible to reopen a <code>FilterIndexReader</code>.
41 * To reopen, you have to first reopen the underlying reader
42 * and wrap it again with the custom filter.
44 public class FilterIndexReader extends IndexReader {
46 /** Base class for filtering {@link TermDocs} implementations. */
47 public static class FilterTermDocs implements TermDocs {
48 protected TermDocs in;
50 public FilterTermDocs(TermDocs in) { this.in = in; }
52 public void seek(Term term) throws IOException { in.seek(term); }
53 public void seek(TermEnum termEnum) throws IOException { in.seek(termEnum); }
54 public int doc() { return in.doc(); }
55 public int freq() { return in.freq(); }
56 public boolean next() throws IOException { return in.next(); }
57 public int read(int[] docs, int[] freqs) throws IOException {
58 return in.read(docs, freqs);
60 public boolean skipTo(int i) throws IOException { return in.skipTo(i); }
61 public void close() throws IOException { in.close(); }
64 /** Base class for filtering {@link TermPositions} implementations. */
65 public static class FilterTermPositions
66 extends FilterTermDocs implements TermPositions {
68 public FilterTermPositions(TermPositions in) { super(in); }
70 public int nextPosition() throws IOException {
71 return ((TermPositions) this.in).nextPosition();
74 public int getPayloadLength() {
75 return ((TermPositions) this.in).getPayloadLength();
78 public byte[] getPayload(byte[] data, int offset) throws IOException {
79 return ((TermPositions) this.in).getPayload(data, offset);
83 // TODO: Remove warning after API has been finalized
84 public boolean isPayloadAvailable() {
85 return ((TermPositions)this.in).isPayloadAvailable();
89 /** Base class for filtering {@link TermEnum} implementations. */
90 public static class FilterTermEnum extends TermEnum {
91 protected TermEnum in;
93 public FilterTermEnum(TermEnum in) { this.in = in; }
96 public boolean next() throws IOException { return in.next(); }
98 public Term term() { return in.term(); }
100 public int docFreq() { return in.docFreq(); }
102 public void close() throws IOException { in.close(); }
105 protected IndexReader in;
108 * <p>Construct a FilterIndexReader based on the specified base reader.
109 * Directory locking for delete, undeleteAll, and setNorm operations is
110 * left to the base reader.</p>
111 * <p>Note that base reader is closed if this FilterIndexReader is closed.</p>
112 * @param in specified base reader.
114 public FilterIndexReader(IndexReader in) {
117 readerFinishedListeners = new MapBackedSet<ReaderFinishedListener>(new ConcurrentHashMap<ReaderFinishedListener,Boolean>());
121 public Directory directory() {
123 return in.directory();
127 public TermFreqVector[] getTermFreqVectors(int docNumber)
130 return in.getTermFreqVectors(docNumber);
134 public TermFreqVector getTermFreqVector(int docNumber, String field)
137 return in.getTermFreqVector(docNumber, field);
142 public void getTermFreqVector(int docNumber, String field, TermVectorMapper mapper) throws IOException {
144 in.getTermFreqVector(docNumber, field, mapper);
148 public void getTermFreqVector(int docNumber, TermVectorMapper mapper) throws IOException {
150 in.getTermFreqVector(docNumber, mapper);
154 public int numDocs() {
155 // Don't call ensureOpen() here (it could affect performance)
160 public int maxDoc() {
161 // Don't call ensureOpen() here (it could affect performance)
166 public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException {
168 return in.document(n, fieldSelector);
172 public boolean isDeleted(int n) {
173 // Don't call ensureOpen() here (it could affect performance)
174 return in.isDeleted(n);
178 public boolean hasDeletions() {
180 return in.hasDeletions();
184 protected void doUndeleteAll() throws CorruptIndexException, IOException {in.undeleteAll();}
187 public boolean hasNorms(String field) throws IOException {
189 return in.hasNorms(field);
193 public byte[] norms(String f) throws IOException {
199 public void norms(String f, byte[] bytes, int offset) throws IOException {
201 in.norms(f, bytes, offset);
205 protected void doSetNorm(int d, String f, byte b) throws CorruptIndexException, IOException {
210 public TermEnum terms() throws IOException {
216 public TermEnum terms(Term t) throws IOException {
222 public int docFreq(Term t) throws IOException {
224 return in.docFreq(t);
228 public TermDocs termDocs() throws IOException {
230 return in.termDocs();
234 public TermDocs termDocs(Term term) throws IOException {
236 return in.termDocs(term);
240 public TermPositions termPositions() throws IOException {
242 return in.termPositions();
246 protected void doDelete(int n) throws CorruptIndexException, IOException { in.deleteDocument(n); }
249 protected void doCommit(Map<String,String> commitUserData) throws IOException {
250 in.commit(commitUserData);
254 protected void doClose() throws IOException {
259 public Collection<String> getFieldNames(IndexReader.FieldOption fieldNames) {
261 return in.getFieldNames(fieldNames);
265 public long getVersion() {
267 return in.getVersion();
271 public boolean isCurrent() throws CorruptIndexException, IOException {
273 return in.isCurrent();
278 public boolean isOptimized() {
280 return in.isOptimized();
284 public IndexReader[] getSequentialSubReaders() {
285 return in.getSequentialSubReaders();
289 public Map<String, String> getCommitUserData() {
290 return in.getCommitUserData();
293 /** If the subclass of FilteredIndexReader modifies the
294 * contents of the FieldCache, you must override this
295 * method to provide a different key */
297 public Object getCoreCacheKey() {
298 return in.getCoreCacheKey();
301 /** If the subclass of FilteredIndexReader modifies the
302 * deleted docs, you must override this method to provide
305 public Object getDeletesCacheKey() {
306 return in.getDeletesCacheKey();
311 public String toString() {
312 final StringBuilder buffer = new StringBuilder("FilterReader(");
315 return buffer.toString();
319 public void addReaderFinishedListener(ReaderFinishedListener listener) {
320 super.addReaderFinishedListener(listener);
321 in.addReaderFinishedListener(listener);
325 public void removeReaderFinishedListener(ReaderFinishedListener listener) {
326 super.removeReaderFinishedListener(listener);
327 in.removeReaderFinishedListener(listener);