| Index: CHANGES.txt |
| =================================================================== |
| --- CHANGES.txt (revision 513819) |
| +++ CHANGES.txt (working copy) |
| @@ -20,6 +20,10 @@ |
| classes, package-private again (they were unnecessarily made public |
| as part of LUCENE-701). (Mike McCandless) |
| |
| + 3. LUCENE-818: changed public methods of IndexWriter, IndexReader |
| + (and its subclasses), FieldsReader to throw AlreadyClosedException |
| + if they are accessed after being closed. (Mike McCandless) |
| + |
| Bug fixes |
| |
| 1. LUCENE-804: Fixed build.xml to pack a fully compilable src dist. (Doron Cohen) |
| Index: src/test/org/apache/lucene/search/TestMultiSearcher.java |
| =================================================================== |
| --- src/test/org/apache/lucene/search/TestMultiSearcher.java (revision 513819) |
| +++ src/test/org/apache/lucene/search/TestMultiSearcher.java (working copy) |
| @@ -149,7 +149,6 @@ |
| // no exception should happen at this point |
| Document d = hits2.doc(i); |
| } |
| - mSearcher2.close(); |
| |
| // test the subSearcher() method: |
| Query subSearcherQuery = parser.parse("id:doc1"); |
| @@ -161,6 +160,7 @@ |
| hits2 = mSearcher2.search(subSearcherQuery); |
| assertEquals(1, hits2.length()); |
| assertEquals(1, mSearcher2.subSearcher(hits2.id(0))); // hit from searchers2[1] |
| + mSearcher2.close(); |
| |
| //-------------------------------------------------------------------- |
| // scenario 3 |
| Index: src/test/org/apache/lucene/index/TestMultiReader.java |
| =================================================================== |
| --- src/test/org/apache/lucene/index/TestMultiReader.java (revision 513819) |
| +++ src/test/org/apache/lucene/index/TestMultiReader.java (working copy) |
| @@ -85,15 +85,18 @@ |
| assertEquals( 2, reader.numDocs() ); |
| |
| // Ensure undeleteAll survives commit/close/reopen: |
| - reader.commit(); |
| reader.close(); |
| sis.read(dir); |
| + |
| + // Must re-open the readers from setUp(): |
| + readers[0] = SegmentReader.get(new SegmentInfo("seg-1", 1, dir)); |
| + readers[1] = SegmentReader.get(new SegmentInfo("seg-2", 1, dir)); |
| + |
| reader = new MultiReader(dir, sis, false, readers); |
| assertEquals( 2, reader.numDocs() ); |
| |
| reader.deleteDocument(0); |
| assertEquals( 1, reader.numDocs() ); |
| - reader.commit(); |
| reader.close(); |
| sis.read(dir); |
| reader = new MultiReader(dir, sis, false, readers); |
| Index: src/test/org/apache/lucene/index/TestFieldsReader.java |
| =================================================================== |
| --- src/test/org/apache/lucene/index/TestFieldsReader.java (revision 513819) |
| +++ src/test/org/apache/lucene/index/TestFieldsReader.java (working copy) |
| @@ -23,6 +23,7 @@ |
| import org.apache.lucene.search.Similarity; |
| import org.apache.lucene.store.FSDirectory; |
| import org.apache.lucene.store.RAMDirectory; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| import org.apache.lucene.util._TestUtil; |
| |
| import java.io.File; |
| @@ -133,6 +134,36 @@ |
| } |
| } |
| |
| + public void testLazyFieldsAfterClose() throws Exception { |
| + assertTrue(dir != null); |
| + assertTrue(fieldInfos != null); |
| + FieldsReader reader = new FieldsReader(dir, "test", fieldInfos); |
| + assertTrue(reader != null); |
| + assertTrue(reader.size() == 1); |
| + Set loadFieldNames = new HashSet(); |
| + loadFieldNames.add(DocHelper.TEXT_FIELD_1_KEY); |
| + loadFieldNames.add(DocHelper.TEXT_FIELD_UTF1_KEY); |
| + Set lazyFieldNames = new HashSet(); |
| + lazyFieldNames.add(DocHelper.LARGE_LAZY_FIELD_KEY); |
| + lazyFieldNames.add(DocHelper.LAZY_FIELD_KEY); |
| + lazyFieldNames.add(DocHelper.LAZY_FIELD_BINARY_KEY); |
| + lazyFieldNames.add(DocHelper.TEXT_FIELD_UTF2_KEY); |
| + lazyFieldNames.add(DocHelper.COMPRESSED_TEXT_FIELD_2_KEY); |
| + SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(loadFieldNames, lazyFieldNames); |
| + Document doc = reader.doc(0, fieldSelector); |
| + assertTrue("doc is null and it shouldn't be", doc != null); |
| + Fieldable field = doc.getFieldable(DocHelper.LAZY_FIELD_KEY); |
| + assertTrue("field is null and it shouldn't be", field != null); |
| + assertTrue("field is not lazy and it should be", field.isLazy()); |
| + reader.close(); |
| + try { |
| + String value = field.stringValue(); |
| + fail("did not hit AlreadyClosedException as expected"); |
| + } catch (AlreadyClosedException e) { |
| + // expected |
| + } |
| + } |
| + |
| public void testLoadFirst() throws Exception { |
| assertTrue(dir != null); |
| assertTrue(fieldInfos != null); |
| Index: src/test/org/apache/lucene/index/TestIndexReader.java |
| =================================================================== |
| --- src/test/org/apache/lucene/index/TestIndexReader.java (revision 513819) |
| +++ src/test/org/apache/lucene/index/TestIndexReader.java (working copy) |
| @@ -26,6 +26,7 @@ |
| import org.apache.lucene.store.RAMDirectory; |
| import org.apache.lucene.store.FSDirectory; |
| import org.apache.lucene.store.LockObtainFailedException; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| import org.apache.lucene.analysis.standard.StandardAnalyzer; |
| import org.apache.lucene.analysis.WhitespaceAnalyzer; |
| import org.apache.lucene.document.Document; |
| @@ -273,21 +274,21 @@ |
| try { |
| reader.deleteDocument(4); |
| fail("deleteDocument after close failed to throw IOException"); |
| - } catch (IOException e) { |
| + } catch (AlreadyClosedException e) { |
| // expected |
| } |
| |
| try { |
| reader.setNorm(5, "aaa", 2.0f); |
| fail("setNorm after close failed to throw IOException"); |
| - } catch (IOException e) { |
| + } catch (AlreadyClosedException e) { |
| // expected |
| } |
| |
| try { |
| reader.undeleteAll(); |
| fail("undeleteAll after close failed to throw IOException"); |
| - } catch (IOException e) { |
| + } catch (AlreadyClosedException e) { |
| // expected |
| } |
| } |
| Index: src/test/org/apache/lucene/index/TestIndexWriter.java |
| =================================================================== |
| --- src/test/org/apache/lucene/index/TestIndexWriter.java (revision 513819) |
| +++ src/test/org/apache/lucene/index/TestIndexWriter.java (working copy) |
| @@ -19,6 +19,7 @@ |
| import org.apache.lucene.store.RAMDirectory; |
| import org.apache.lucene.store.IndexInput; |
| import org.apache.lucene.store.IndexOutput; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| |
| import org.apache.lucene.store.MockRAMDirectory; |
| import org.apache.lucene.store.LockFactory; |
| @@ -653,6 +654,25 @@ |
| } |
| } |
| |
| + public void testChangesAfterClose() throws IOException { |
| + Directory dir = new RAMDirectory(); |
| + |
| + IndexWriter writer = null; |
| + |
| + writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true); |
| + addDoc(writer); |
| + |
| + // close |
| + writer.close(); |
| + try { |
| + addDoc(writer); |
| + fail("did not hit AlreadyClosedException"); |
| + } catch (AlreadyClosedException e) { |
| + // expected |
| + } |
| + } |
| + |
| + |
| // Simulate a corrupt index by removing one of the cfs |
| // files and make sure we get an IOException trying to |
| // open the index: |
| @@ -722,7 +742,6 @@ |
| IndexSearcher searcher = new IndexSearcher(dir); |
| Hits hits = searcher.search(new TermQuery(searchTerm)); |
| assertEquals("did not get right number of hits", 100, hits.length()); |
| - writer.close(); |
| |
| writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true); |
| writer.close(); |
| Index: src/java/org/apache/lucene/index/MultiReader.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/MultiReader.java (revision 513819) |
| +++ src/java/org/apache/lucene/index/MultiReader.java (working copy) |
| @@ -20,6 +20,7 @@ |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.document.FieldSelector; |
| import org.apache.lucene.store.Directory; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| |
| import java.io.IOException; |
| import java.util.Collection; |
| @@ -72,24 +73,21 @@ |
| } |
| |
| |
| - /** Return an array of term frequency vectors for the specified document. |
| - * The array contains a vector for each vectorized field in the document. |
| - * Each vector vector contains term numbers and frequencies for all terms |
| - * in a given vectorized field. |
| - * If no such fields existed, the method returns null. |
| - */ |
| - public TermFreqVector[] getTermFreqVectors(int n) throws IOException { |
| + public TermFreqVector[] getTermFreqVectors(int n) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| int i = readerIndex(n); // find segment num |
| return subReaders[i].getTermFreqVectors(n - starts[i]); // dispatch to segment |
| } |
| |
| public TermFreqVector getTermFreqVector(int n, String field) |
| - throws IOException { |
| + throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| int i = readerIndex(n); // find segment num |
| return subReaders[i].getTermFreqVector(n - starts[i], field); |
| } |
| |
| - public synchronized int numDocs() { |
| + public synchronized int numDocs() throws AlreadyClosedException { |
| + ensureOpen(); |
| if (numDocs == -1) { // check cache |
| int n = 0; // cache miss--recompute |
| for (int i = 0; i < subReaders.length; i++) |
| @@ -99,22 +97,28 @@ |
| return numDocs; |
| } |
| |
| - public int maxDoc() { |
| + public int maxDoc() throws AlreadyClosedException { |
| + ensureOpen(); |
| return maxDoc; |
| } |
| |
| // inherit javadoc |
| - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { |
| + public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| int i = readerIndex(n); // find segment num |
| return subReaders[i].document(n - starts[i], fieldSelector); // dispatch to segment reader |
| } |
| |
| - public boolean isDeleted(int n) { |
| + public boolean isDeleted(int n) throws AlreadyClosedException { |
| + ensureOpen(); |
| int i = readerIndex(n); // find segment num |
| return subReaders[i].isDeleted(n - starts[i]); // dispatch to segment reader |
| } |
| |
| - public boolean hasDeletions() { return hasDeletions; } |
| + public boolean hasDeletions() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return hasDeletions; |
| + } |
| |
| protected void doDelete(int n) throws CorruptIndexException, IOException { |
| numDocs = -1; // invalidate cache |
| @@ -152,7 +156,8 @@ |
| return hi; |
| } |
| |
| - public boolean hasNorms(String field) throws IOException { |
| + public boolean hasNorms(String field) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| for (int i = 0; i < subReaders.length; i++) { |
| if (subReaders[i].hasNorms(field)) return true; |
| } |
| @@ -165,7 +170,8 @@ |
| return ones; |
| } |
| |
| - public synchronized byte[] norms(String field) throws IOException { |
| + public synchronized byte[] norms(String field) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| byte[] bytes = (byte[])normsCache.get(field); |
| if (bytes != null) |
| return bytes; // cache hit |
| @@ -180,7 +186,8 @@ |
| } |
| |
| public synchronized void norms(String field, byte[] result, int offset) |
| - throws IOException { |
| + throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| byte[] bytes = (byte[])normsCache.get(field); |
| if (bytes==null && !hasNorms(field)) bytes=fakeNorms(); |
| if (bytes != null) // cache hit |
| @@ -197,26 +204,31 @@ |
| subReaders[i].setNorm(n-starts[i], field, value); // dispatch |
| } |
| |
| - public TermEnum terms() throws IOException { |
| + public TermEnum terms() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new MultiTermEnum(subReaders, starts, null); |
| } |
| |
| - public TermEnum terms(Term term) throws IOException { |
| + public TermEnum terms(Term term) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new MultiTermEnum(subReaders, starts, term); |
| } |
| |
| - public int docFreq(Term t) throws IOException { |
| + public int docFreq(Term t) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| int total = 0; // sum freqs in segments |
| for (int i = 0; i < subReaders.length; i++) |
| total += subReaders[i].docFreq(t); |
| return total; |
| } |
| |
| - public TermDocs termDocs() throws IOException { |
| + public TermDocs termDocs() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new MultiTermDocs(subReaders, starts); |
| } |
| |
| - public TermPositions termPositions() throws IOException { |
| + public TermPositions termPositions() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new MultiTermPositions(subReaders, starts); |
| } |
| |
| @@ -251,11 +263,9 @@ |
| subReaders[i].close(); |
| } |
| |
| - /** |
| - * @see IndexReader#getFieldNames(IndexReader.FieldOption) |
| - */ |
| - public Collection getFieldNames (IndexReader.FieldOption fieldNames) { |
| + public Collection getFieldNames (IndexReader.FieldOption fieldNames) throws AlreadyClosedException { |
| // maintain a unique set of field names |
| + ensureOpen(); |
| Set fieldSet = new HashSet(); |
| for (int i = 0; i < subReaders.length; i++) { |
| IndexReader reader = subReaders[i]; |
| Index: src/java/org/apache/lucene/index/FieldsReader.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/FieldsReader.java (revision 513819) |
| +++ src/java/org/apache/lucene/index/FieldsReader.java (working copy) |
| @@ -20,6 +20,7 @@ |
| import org.apache.lucene.document.*; |
| import org.apache.lucene.store.Directory; |
| import org.apache.lucene.store.IndexInput; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| @@ -46,6 +47,7 @@ |
| |
| private final IndexInput indexStream; |
| private int size; |
| + private boolean closed; |
| |
| private ThreadLocal fieldsStreamTL = new ThreadLocal(); |
| |
| @@ -59,19 +61,31 @@ |
| } |
| |
| /** |
| + * @throws AlreadyClosedException if this FieldsReader is closed |
| + */ |
| + protected void ensureOpen() throws AlreadyClosedException { |
| + if (closed) { |
| + throw new AlreadyClosedException("this FieldsReader is closed"); |
| + } |
| + } |
| + |
| + /** |
| * Closes the underlying {@link org.apache.lucene.store.IndexInput} streams, including any ones associated with a |
| * lazy implementation of a Field. This means that the Fields values will not be accessible. |
| * |
| * @throws IOException |
| */ |
| final void close() throws IOException { |
| - fieldsStream.close(); |
| - cloneableFieldsStream.close(); |
| - indexStream.close(); |
| - IndexInput localFieldsStream = (IndexInput) fieldsStreamTL.get(); |
| - if (localFieldsStream != null) { |
| - localFieldsStream.close(); |
| - fieldsStreamTL.set(null); |
| + if (!closed) { |
| + fieldsStream.close(); |
| + cloneableFieldsStream.close(); |
| + indexStream.close(); |
| + IndexInput localFieldsStream = (IndexInput) fieldsStreamTL.get(); |
| + if (localFieldsStream != null) { |
| + localFieldsStream.close(); |
| + fieldsStreamTL.set(null); |
| + } |
| + closed = true; |
| } |
| } |
| |
| @@ -321,8 +335,10 @@ |
| * The value of the field in Binary, or null. If null, the Reader or |
| * String value is used. Exactly one of stringValue(), readerValue() and |
| * binaryValue() must be set. |
| + * @throws AlreadyClosedException if this FieldsReader is closed |
| */ |
| - public byte[] binaryValue() { |
| + public byte[] binaryValue() throws AlreadyClosedException { |
| + ensureOpen(); |
| if (fieldsData == null) { |
| final byte[] b = new byte[toRead]; |
| IndexInput localFieldsStream = getFieldStream(); |
| @@ -347,8 +363,10 @@ |
| * The value of the field as a Reader, or null. If null, the String value |
| * or binary value is used. Exactly one of stringValue(), readerValue(), |
| * and binaryValue() must be set. |
| + * @throws AlreadyClosedException if this FieldsReader is closed |
| */ |
| - public Reader readerValue() { |
| + public Reader readerValue() throws AlreadyClosedException { |
| + ensureOpen(); |
| return fieldsData instanceof Reader ? (Reader) fieldsData : null; |
| } |
| |
| @@ -356,8 +374,10 @@ |
| * The value of the field as a String, or null. If null, the Reader value |
| * or binary value is used. Exactly one of stringValue(), readerValue(), and |
| * binaryValue() must be set. |
| + * @throws AlreadyClosedException if this FieldsReader is closed |
| */ |
| - public String stringValue() { |
| + public String stringValue() throws AlreadyClosedException { |
| + ensureOpen(); |
| if (fieldsData == null) { |
| IndexInput localFieldsStream = getFieldStream(); |
| try { |
| @@ -379,19 +399,35 @@ |
| return fieldsData instanceof String ? (String) fieldsData : null; |
| } |
| |
| - public long getPointer() { |
| + /** |
| + * @throws AlreadyClosedException if this FieldsReader is closed |
| + */ |
| + public long getPointer() throws AlreadyClosedException { |
| + ensureOpen(); |
| return pointer; |
| } |
| |
| - public void setPointer(long pointer) { |
| + /** |
| + * @throws AlreadyClosedException if this FieldsReader is closed |
| + */ |
| + public void setPointer(long pointer) throws AlreadyClosedException { |
| + ensureOpen(); |
| this.pointer = pointer; |
| } |
| |
| - public int getToRead() { |
| + /** |
| + * @throws AlreadyClosedException if this FieldsReader is closed |
| + */ |
| + public int getToRead() throws AlreadyClosedException { |
| + ensureOpen(); |
| return toRead; |
| } |
| |
| - public void setToRead(int toRead) { |
| + /** |
| + * @throws AlreadyClosedException if this FieldsReader is closed |
| + */ |
| + public void setToRead(int toRead) throws AlreadyClosedException { |
| + ensureOpen(); |
| this.toRead = toRead; |
| } |
| } |
| Index: src/java/org/apache/lucene/index/IndexReader.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/IndexReader.java (revision 513819) |
| +++ src/java/org/apache/lucene/index/IndexReader.java (working copy) |
| @@ -25,6 +25,7 @@ |
| import org.apache.lucene.store.IndexInput; |
| import org.apache.lucene.store.Lock; |
| import org.apache.lucene.store.LockObtainFailedException; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| @@ -115,8 +116,17 @@ |
| private boolean directoryOwner; |
| private boolean closeDirectory; |
| protected IndexFileDeleter deleter; |
| - private boolean isClosed; |
| + private boolean closed; |
| |
| + /** |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + protected void ensureOpen() throws AlreadyClosedException { |
| + if (closed) { |
| + throw new AlreadyClosedException("this IndexReader is closed"); |
| + } |
| + } |
| + |
| private SegmentInfos segmentInfos; |
| private Lock writeLock; |
| private boolean stale; |
| @@ -190,8 +200,13 @@ |
| }.run(); |
| } |
| |
| - /** Returns the directory this index resides in. */ |
| - public Directory directory() { return directory; } |
| + /** Returns the directory this index resides in. |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public Directory directory() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return directory; |
| + } |
| |
| /** |
| * Returns the time the index in the named directory was last modified. |
| @@ -281,8 +296,10 @@ |
| |
| /** |
| * Version number when this IndexReader was opened. |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public long getVersion() { |
| + public long getVersion() throws AlreadyClosedException { |
| + ensureOpen(); |
| return segmentInfos.getVersion(); |
| } |
| |
| @@ -293,17 +310,21 @@ |
| * |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public boolean isCurrent() throws CorruptIndexException, IOException { |
| + public boolean isCurrent() throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return SegmentInfos.readCurrentVersion(directory) == segmentInfos.getVersion(); |
| } |
| |
| /** |
| * Checks is the index is optimized (if it has a single segment and no deletions) |
| * @return <code>true</code> if the index is optimized; <code>false</code> otherwise |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public boolean isOptimized() { |
| - return segmentInfos.size() == 1 && hasDeletions() == false; |
| + public boolean isOptimized() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return segmentInfos.size() == 1 && hasDeletions() == false; |
| } |
| |
| /** |
| @@ -318,10 +339,11 @@ |
| * @return array of term frequency vectors. May be null if no term vectors have been |
| * stored for the specified document. |
| * @throws IOException if index cannot be accessed |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| * @see org.apache.lucene.document.Field.TermVector |
| */ |
| abstract public TermFreqVector[] getTermFreqVectors(int docNumber) |
| - throws IOException; |
| + throws IOException, AlreadyClosedException; |
| |
| |
| /** |
| @@ -336,10 +358,11 @@ |
| * @return term frequency vector May be null if field does not exist in the specified |
| * document or term vector was not stored. |
| * @throws IOException if index cannot be accessed |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| * @see org.apache.lucene.document.Field.TermVector |
| */ |
| abstract public TermFreqVector getTermFreqVector(int docNumber, String field) |
| - throws IOException; |
| + throws IOException, AlreadyClosedException; |
| |
| /** |
| * Returns <code>true</code> if an index exists at the specified directory. |
| @@ -374,21 +397,26 @@ |
| return SegmentInfos.getCurrentSegmentGeneration(directory) != -1; |
| } |
| |
| - /** Returns the number of documents in this index. */ |
| - public abstract int numDocs(); |
| + /** Returns the number of documents in this index. |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public abstract int numDocs() throws AlreadyClosedException; |
| |
| /** Returns one greater than the largest possible document number. |
| * This may be used to, e.g., determine how big to allocate an array which |
| * will have an element for every document number in an index. |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public abstract int maxDoc(); |
| + public abstract int maxDoc() throws AlreadyClosedException; |
| |
| /** Returns the stored fields of the <code>n</code><sup>th</sup> |
| <code>Document</code> in this index. |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public Document document(int n) throws CorruptIndexException, IOException { |
| + public Document document(int n) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return document(n, null); |
| } |
| |
| @@ -411,22 +439,30 @@ |
| * @see org.apache.lucene.document.FieldSelector |
| * @see org.apache.lucene.document.SetBasedFieldSelector |
| * @see org.apache.lucene.document.LoadFirstFieldSelector |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| //When we convert to JDK 1.5 make this Set<String> |
| - public abstract Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException; |
| + public abstract Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException, AlreadyClosedException; |
| |
| |
| |
| - /** Returns true if document <i>n</i> has been deleted */ |
| - public abstract boolean isDeleted(int n); |
| + /** Returns true if document <i>n</i> has been deleted |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public abstract boolean isDeleted(int n) throws AlreadyClosedException; |
| |
| - /** Returns true if any documents have been deleted */ |
| - public abstract boolean hasDeletions(); |
| + /** Returns true if any documents have been deleted |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public abstract boolean hasDeletions() throws AlreadyClosedException; |
| |
| - /** Returns true if there are norms stored for this field. */ |
| - public boolean hasNorms(String field) throws IOException { |
| + /** Returns true if there are norms stored for this field. |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public boolean hasNorms(String field) throws IOException, AlreadyClosedException { |
| // backward compatible implementation. |
| // SegmentReader has an efficient implementation. |
| + ensureOpen(); |
| return norms(field) != null; |
| } |
| |
| @@ -434,16 +470,18 @@ |
| * every document. This is used by the search code to score documents. |
| * |
| * @see org.apache.lucene.document.Field#setBoost(float) |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public abstract byte[] norms(String field) throws IOException; |
| + public abstract byte[] norms(String field) throws IOException, AlreadyClosedException; |
| |
| /** Reads the byte-encoded normalization factor for the named field of every |
| * document. This is used by the search code to score documents. |
| * |
| * @see org.apache.lucene.document.Field#setBoost(float) |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| public abstract void norms(String field, byte[] bytes, int offset) |
| - throws IOException; |
| + throws IOException, AlreadyClosedException; |
| |
| /** Expert: Resets the normalization factor for the named field of the named |
| * document. The norm represents the product of the field's {@link |
| @@ -459,11 +497,12 @@ |
| * @throws LockObtainFailedException if another writer |
| * has this index open (<code>write.lock</code> could not |
| * be obtained) |
| - * @throws IOException if this reader was closed already |
| - * or there is a low-level IO error |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| public final synchronized void setNorm(int doc, String field, byte value) |
| - throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { |
| + throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| if(directoryOwner) |
| acquireWriteLock(); |
| hasChanges = true; |
| @@ -486,28 +525,36 @@ |
| * @throws LockObtainFailedException if another writer |
| * has this index open (<code>write.lock</code> could not |
| * be obtained) |
| - * @throws IOException if this reader was closed already |
| - * or there is a low-level IO error |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| public void setNorm(int doc, String field, float value) |
| - throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { |
| + throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| setNorm(doc, field, Similarity.encodeNorm(value)); |
| } |
| |
| /** Returns an enumeration of all the terms in the index. |
| * The enumeration is ordered by Term.compareTo(). Each term |
| * is greater than all that precede it in the enumeration. |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public abstract TermEnum terms() throws IOException; |
| + public abstract TermEnum terms() throws IOException, AlreadyClosedException; |
| |
| /** Returns an enumeration of all terms after a given term. |
| * The enumeration is ordered by Term.compareTo(). Each term |
| * is greater than all that precede it in the enumeration. |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public abstract TermEnum terms(Term t) throws IOException; |
| + public abstract TermEnum terms(Term t) throws IOException, AlreadyClosedException; |
| |
| - /** Returns the number of documents containing the term <code>t</code>. */ |
| - public abstract int docFreq(Term t) throws IOException; |
| + /** Returns the number of documents containing the term <code>t</code>. |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public abstract int docFreq(Term t) throws IOException, AlreadyClosedException; |
| |
| /** Returns an enumeration of all the documents which contain |
| * <code>term</code>. For each document, the document number, the frequency of |
| @@ -518,15 +565,21 @@ |
| * </ul> |
| * <p>The enumeration is ordered by document number. Each document number |
| * is greater than all that precede it in the enumeration. |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public TermDocs termDocs(Term term) throws IOException { |
| + public TermDocs termDocs(Term term) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| TermDocs termDocs = termDocs(); |
| termDocs.seek(term); |
| return termDocs; |
| } |
| |
| - /** Returns an unpositioned {@link TermDocs} enumerator. */ |
| - public abstract TermDocs termDocs() throws IOException; |
| + /** Returns an unpositioned {@link TermDocs} enumerator. |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public abstract TermDocs termDocs() throws IOException, AlreadyClosedException; |
| |
| /** Returns an enumeration of all the documents which contain |
| * <code>term</code>. For each document, in addition to the document number |
| @@ -543,15 +596,21 @@ |
| * <p> This positional information faciliates phrase and proximity searching. |
| * <p>The enumeration is ordered by document number. Each document number is |
| * greater than all that precede it in the enumeration. |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public TermPositions termPositions(Term term) throws IOException { |
| + public TermPositions termPositions(Term term) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| TermPositions termPositions = termPositions(); |
| termPositions.seek(term); |
| return termPositions; |
| } |
| |
| - /** Returns an unpositioned {@link TermPositions} enumerator. */ |
| - public abstract TermPositions termPositions() throws IOException; |
| + /** Returns an unpositioned {@link TermPositions} enumerator. |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public abstract TermPositions termPositions() throws IOException, AlreadyClosedException; |
| |
| /** |
| * Tries to acquire the WriteLock on this directory. |
| @@ -564,12 +623,12 @@ |
| * has this index open (<code>write.lock</code> could not |
| * be obtained) |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - private void acquireWriteLock() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { |
| + private void acquireWriteLock() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| if (stale) |
| throw new StaleReaderException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations"); |
| - if (isClosed) |
| - throw new IOException("this reader is closed"); |
| |
| if (writeLock == null) { |
| Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME); |
| @@ -602,10 +661,11 @@ |
| * @throws LockObtainFailedException if another writer |
| * has this index open (<code>write.lock</code> could not |
| * be obtained) |
| - * @throws IOException if this reader was closed already |
| - * or there is a low-level IO error |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public final synchronized void deleteDocument(int docNum) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { |
| + public final synchronized void deleteDocument(int docNum) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| if(directoryOwner) |
| acquireWriteLock(); |
| hasChanges = true; |
| @@ -634,10 +694,11 @@ |
| * @throws LockObtainFailedException if another writer |
| * has this index open (<code>write.lock</code> could not |
| * be obtained) |
| - * @throws IOException if this reader was closed already |
| - * or there is a low-level IO error |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public final int deleteDocuments(Term term) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { |
| + public final int deleteDocuments(Term term) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| TermDocs docs = termDocs(term); |
| if (docs == null) return 0; |
| int n = 0; |
| @@ -660,10 +721,11 @@ |
| * has this index open (<code>write.lock</code> could not |
| * be obtained) |
| * @throws CorruptIndexException if the index is corrupt |
| - * @throws IOException if this reader was closed already |
| - * or there is a low-level IO error |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public final synchronized void undeleteAll() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { |
| + public final synchronized void undeleteAll() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| if(directoryOwner) |
| acquireWriteLock(); |
| hasChanges = true; |
| @@ -793,20 +855,18 @@ |
| * Closes files associated with this index. |
| * Also saves any new deletions to disk. |
| * No other methods should be called after this has been called. |
| - * @throws IOException if this reader was closed already |
| - * or there is a low-level IO error |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| public final synchronized void close() throws IOException { |
| - if (directoryOwner && isClosed) { |
| - throw new IOException("this reader is already closed"); |
| + if (!closed) { |
| + commit(); |
| + doClose(); |
| + if (directoryOwner) |
| + closed = true; |
| + if(closeDirectory) |
| + directory.close(); |
| } |
| - commit(); |
| - doClose(); |
| - if(closeDirectory) |
| - directory.close(); |
| - if (directoryOwner) { |
| - isClosed = true; |
| - } |
| } |
| |
| /** Implements close. */ |
| @@ -831,8 +891,9 @@ |
| * @param fldOption specifies which field option should be available for the returned fields |
| * @return Collection of Strings indicating the names of the fields. |
| * @see IndexReader.FieldOption |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| - public abstract Collection getFieldNames(FieldOption fldOption); |
| + public abstract Collection getFieldNames(FieldOption fldOption) throws AlreadyClosedException; |
| |
| /** |
| * Returns <code>true</code> iff the index in the named directory is |
| Index: src/java/org/apache/lucene/index/FilterIndexReader.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/FilterIndexReader.java (revision 513819) |
| +++ src/java/org/apache/lucene/index/FilterIndexReader.java (working copy) |
| @@ -19,6 +19,7 @@ |
| |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.document.FieldSelector; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| |
| |
| import java.io.IOException; |
| @@ -91,44 +92,85 @@ |
| } |
| |
| public TermFreqVector[] getTermFreqVectors(int docNumber) |
| - throws IOException { |
| + throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return in.getTermFreqVectors(docNumber); |
| } |
| |
| public TermFreqVector getTermFreqVector(int docNumber, String field) |
| - throws IOException { |
| + throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return in.getTermFreqVector(docNumber, field); |
| } |
| |
| - public int numDocs() { return in.numDocs(); } |
| - public int maxDoc() { return in.maxDoc(); } |
| + public int numDocs() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return in.numDocs(); |
| + } |
| |
| - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { return in.document(n, fieldSelector); } |
| + public int maxDoc() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return in.maxDoc(); |
| + } |
| |
| - public boolean isDeleted(int n) { return in.isDeleted(n); } |
| - public boolean hasDeletions() { return in.hasDeletions(); } |
| + public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| + return in.document(n, fieldSelector); |
| + } |
| + |
| + public boolean isDeleted(int n) throws AlreadyClosedException { |
| + ensureOpen(); |
| + return in.isDeleted(n); |
| + } |
| + |
| + public boolean hasDeletions() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return in.hasDeletions(); |
| + } |
| + |
| protected void doUndeleteAll() throws CorruptIndexException, IOException {in.undeleteAll();} |
| |
| - public boolean hasNorms(String field) throws IOException { |
| + public boolean hasNorms(String field) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return in.hasNorms(field); |
| } |
| |
| - public byte[] norms(String f) throws IOException { return in.norms(f); } |
| - public void norms(String f, byte[] bytes, int offset) throws IOException { |
| + public byte[] norms(String f) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| + return in.norms(f); |
| + } |
| + |
| + public void norms(String f, byte[] bytes, int offset) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| in.norms(f, bytes, offset); |
| } |
| + |
| protected void doSetNorm(int d, String f, byte b) throws CorruptIndexException, IOException { |
| in.setNorm(d, f, b); |
| } |
| |
| - public TermEnum terms() throws IOException { return in.terms(); } |
| - public TermEnum terms(Term t) throws IOException { return in.terms(t); } |
| + public TermEnum terms() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| + return in.terms(); |
| + } |
| |
| - public int docFreq(Term t) throws IOException { return in.docFreq(t); } |
| + public TermEnum terms(Term t) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| + return in.terms(t); |
| + } |
| |
| - public TermDocs termDocs() throws IOException { return in.termDocs(); } |
| + public int docFreq(Term t) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| + return in.docFreq(t); |
| + } |
| |
| - public TermPositions termPositions() throws IOException { |
| + public TermDocs termDocs() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| + return in.termDocs(); |
| + } |
| + |
| + public TermPositions termPositions() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return in.termPositions(); |
| } |
| |
| @@ -137,10 +179,18 @@ |
| protected void doClose() throws IOException { in.close(); } |
| |
| |
| - public Collection getFieldNames(IndexReader.FieldOption fieldNames) { |
| + public Collection getFieldNames(IndexReader.FieldOption fieldNames) throws AlreadyClosedException { |
| + ensureOpen(); |
| return in.getFieldNames(fieldNames); |
| } |
| |
| - public long getVersion() { return in.getVersion(); } |
| - public boolean isCurrent() throws CorruptIndexException, IOException { return in.isCurrent(); } |
| + public long getVersion() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return in.getVersion(); |
| + } |
| + |
| + public boolean isCurrent() throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| + return in.isCurrent(); |
| + } |
| } |
| Index: src/java/org/apache/lucene/index/IndexWriter.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/IndexWriter.java (revision 513819) |
| +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) |
| @@ -24,6 +24,7 @@ |
| import org.apache.lucene.store.FSDirectory; |
| import org.apache.lucene.store.Lock; |
| import org.apache.lucene.store.LockObtainFailedException; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| import org.apache.lucene.store.RAMDirectory; |
| |
| import java.io.File; |
| @@ -151,37 +152,55 @@ |
| private boolean useCompoundFile = true; |
| |
| private boolean closeDir; |
| + private boolean closed; |
| |
| + /** |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| + */ |
| + protected void ensureOpen() throws AlreadyClosedException { |
| + if (closed) { |
| + throw new AlreadyClosedException("this IndexWriter is closed"); |
| + } |
| + } |
| + |
| /** Get the current setting of whether to use the compound file format. |
| * Note that this just returns the value you set with setUseCompoundFile(boolean) |
| * or the default. You cannot use this to query the status of an existing index. |
| * @see #setUseCompoundFile(boolean) |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public boolean getUseCompoundFile() { |
| + public boolean getUseCompoundFile() throws AlreadyClosedException { |
| + ensureOpen(); |
| return useCompoundFile; |
| } |
| |
| /** Setting to turn on usage of a compound file. When on, multiple files |
| * for each segment are merged into a single file once the segment creation |
| * is finished. This is done regardless of what directory is in use. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setUseCompoundFile(boolean value) { |
| + public void setUseCompoundFile(boolean value) throws AlreadyClosedException { |
| + ensureOpen(); |
| useCompoundFile = value; |
| } |
| |
| /** Expert: Set the Similarity implementation used by this IndexWriter. |
| * |
| * @see Similarity#setDefault(Similarity) |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setSimilarity(Similarity similarity) { |
| + public void setSimilarity(Similarity similarity) throws AlreadyClosedException { |
| + ensureOpen(); |
| this.similarity = similarity; |
| } |
| |
| /** Expert: Return the Similarity implementation used by this IndexWriter. |
| * |
| * <p>This defaults to the current value of {@link Similarity#getDefault()}. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public Similarity getSimilarity() { |
| + public Similarity getSimilarity() throws AlreadyClosedException { |
| + ensureOpen(); |
| return this.similarity; |
| } |
| |
| @@ -205,16 +224,22 @@ |
| * must be scanned for each random term access. |
| * |
| * @see #DEFAULT_TERM_INDEX_INTERVAL |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setTermIndexInterval(int interval) { |
| + public void setTermIndexInterval(int interval) throws AlreadyClosedException { |
| + ensureOpen(); |
| this.termIndexInterval = interval; |
| } |
| |
| /** Expert: Return the interval between indexed terms. |
| * |
| * @see #setTermIndexInterval(int) |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public int getTermIndexInterval() { return termIndexInterval; } |
| + public int getTermIndexInterval() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return termIndexInterval; |
| + } |
| |
| /** |
| * Constructs an IndexWriter for the index in <code>path</code>. |
| @@ -430,15 +455,19 @@ |
| * Larger values are best for batched indexing and speedier searches. |
| * |
| * <p>The default value is {@link Integer#MAX_VALUE}. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setMaxMergeDocs(int maxMergeDocs) { |
| + public void setMaxMergeDocs(int maxMergeDocs) throws AlreadyClosedException { |
| + ensureOpen(); |
| this.maxMergeDocs = maxMergeDocs; |
| } |
| |
| /** |
| * @see #setMaxMergeDocs |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public int getMaxMergeDocs() { |
| + public int getMaxMergeDocs() throws AlreadyClosedException { |
| + ensureOpen(); |
| return maxMergeDocs; |
| } |
| |
| @@ -453,15 +482,19 @@ |
| * the expected size. If you set it to Integer.MAX_VALUE, then the only limit |
| * is your memory, but you should anticipate an OutOfMemoryError.<p/> |
| * By default, no more than 10,000 terms will be indexed for a field. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setMaxFieldLength(int maxFieldLength) { |
| + public void setMaxFieldLength(int maxFieldLength) throws AlreadyClosedException { |
| + ensureOpen(); |
| this.maxFieldLength = maxFieldLength; |
| } |
| |
| /** |
| * @see #setMaxFieldLength |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public int getMaxFieldLength() { |
| + public int getMaxFieldLength() throws AlreadyClosedException { |
| + ensureOpen(); |
| return maxFieldLength; |
| } |
| |
| @@ -474,8 +507,10 @@ |
| * <p> The default value is 10. |
| * |
| * @throws IllegalArgumentException if maxBufferedDocs is smaller than 2 |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setMaxBufferedDocs(int maxBufferedDocs) { |
| + public void setMaxBufferedDocs(int maxBufferedDocs) throws AlreadyClosedException { |
| + ensureOpen(); |
| if (maxBufferedDocs < 2) |
| throw new IllegalArgumentException("maxBufferedDocs must at least be 2"); |
| this.minMergeDocs = maxBufferedDocs; |
| @@ -483,8 +518,10 @@ |
| |
| /** |
| * @see #setMaxBufferedDocs |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public int getMaxBufferedDocs() { |
| + public int getMaxBufferedDocs() throws AlreadyClosedException { |
| + ensureOpen(); |
| return minMergeDocs; |
| } |
| |
| @@ -496,8 +533,10 @@ |
| |
| * <p>The default value is {@link #DEFAULT_MAX_BUFFERED_DELETE_TERMS}. |
| * @throws IllegalArgumentException if maxBufferedDeleteTerms is smaller than 1</p> |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setMaxBufferedDeleteTerms(int maxBufferedDeleteTerms) { |
| + public void setMaxBufferedDeleteTerms(int maxBufferedDeleteTerms) throws AlreadyClosedException { |
| + ensureOpen(); |
| if (maxBufferedDeleteTerms < 1) |
| throw new IllegalArgumentException("maxBufferedDeleteTerms must at least be 1"); |
| this.maxBufferedDeleteTerms = maxBufferedDeleteTerms; |
| @@ -505,8 +544,10 @@ |
| |
| /** |
| * @see #setMaxBufferedDeleteTerms |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public int getMaxBufferedDeleteTerms() { |
| + public int getMaxBufferedDeleteTerms() throws AlreadyClosedException { |
| + ensureOpen(); |
| return maxBufferedDeleteTerms; |
| } |
| |
| @@ -519,8 +560,10 @@ |
| * interactively maintained. |
| * |
| * <p>This must never be less than 2. The default value is 10. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setMergeFactor(int mergeFactor) { |
| + public void setMergeFactor(int mergeFactor) throws AlreadyClosedException { |
| + ensureOpen(); |
| if (mergeFactor < 2) |
| throw new IllegalArgumentException("mergeFactor cannot be less than 2"); |
| this.mergeFactor = mergeFactor; |
| @@ -528,37 +571,47 @@ |
| |
| /** |
| * @see #setMergeFactor |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public int getMergeFactor() { |
| + public int getMergeFactor() throws AlreadyClosedException { |
| + ensureOpen(); |
| return mergeFactor; |
| } |
| |
| /** If non-null, information about merges and a message when |
| * maxFieldLength is reached will be printed to this. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setInfoStream(PrintStream infoStream) { |
| + public void setInfoStream(PrintStream infoStream) throws AlreadyClosedException { |
| + ensureOpen(); |
| this.infoStream = infoStream; |
| } |
| |
| /** |
| * @see #setInfoStream |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public PrintStream getInfoStream() { |
| + public PrintStream getInfoStream() throws AlreadyClosedException { |
| + ensureOpen(); |
| return infoStream; |
| } |
| |
| /** |
| * Sets the maximum time to wait for a write lock (in milliseconds) for this instance of IndexWriter. @see |
| * @see #setDefaultWriteLockTimeout to change the default value for all instances of IndexWriter. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void setWriteLockTimeout(long writeLockTimeout) { |
| + public void setWriteLockTimeout(long writeLockTimeout) throws AlreadyClosedException { |
| + ensureOpen(); |
| this.writeLockTimeout = writeLockTimeout; |
| } |
| |
| /** |
| * @see #setWriteLockTimeout |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public long getWriteLockTimeout() { |
| + public long getWriteLockTimeout() throws AlreadyClosedException { |
| + ensureOpen(); |
| return writeLockTimeout; |
| } |
| |
| @@ -612,14 +665,17 @@ |
| * @throws IOException if there is a low-level IO error |
| */ |
| public synchronized void close() throws CorruptIndexException, IOException { |
| - flushRamSegments(); |
| - ramDirectory.close(); |
| - if (writeLock != null) { |
| - writeLock.release(); // release write lock |
| - writeLock = null; |
| + if (!closed) { |
| + flushRamSegments(); |
| + ramDirectory.close(); |
| + closed = true; |
| + if (writeLock != null) { |
| + writeLock.release(); // release write lock |
| + writeLock = null; |
| + } |
| + if(closeDir) |
| + directory.close(); |
| } |
| - if(closeDir) |
| - directory.close(); |
| } |
| |
| /** Release the write lock, if needed. */ |
| @@ -634,19 +690,32 @@ |
| } |
| } |
| |
| - /** Returns the Directory used by this index. */ |
| - public Directory getDirectory() { |
| - return directory; |
| + /** |
| + * Returns the Directory used by this index. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| + */ |
| + public Directory getDirectory() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return directory; |
| } |
| |
| - /** Returns the analyzer used by this index. */ |
| - public Analyzer getAnalyzer() { |
| - return analyzer; |
| + /** |
| + * Returns the analyzer used by this index. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| + */ |
| + public Analyzer getAnalyzer() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return analyzer; |
| } |
| |
| |
| - /** Returns the number of documents currently in this index. */ |
| - public synchronized int docCount() { |
| + /** |
| + * Returns the number of documents currently in this |
| + * index. |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| + */ |
| + public synchronized int docCount() throws AlreadyClosedException { |
| + ensureOpen(); |
| int count = ramSegmentInfos.size(); |
| for (int i = 0; i < segmentInfos.size(); i++) { |
| SegmentInfo si = segmentInfos.info(i); |
| @@ -722,8 +791,10 @@ |
| * |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void addDocument(Document doc, Analyzer analyzer) throws CorruptIndexException, IOException { |
| + public void addDocument(Document doc, Analyzer analyzer) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| SegmentInfo newSegmentInfo = buildSingleDocSegment(doc, analyzer); |
| synchronized (this) { |
| ramSegmentInfos.addElement(newSegmentInfo); |
| @@ -745,8 +816,10 @@ |
| * @param term the term to identify the documents to be deleted |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public synchronized void deleteDocuments(Term term) throws CorruptIndexException, IOException { |
| + public synchronized void deleteDocuments(Term term) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| bufferDeleteTerm(term); |
| maybeFlushRamSegments(); |
| } |
| @@ -758,8 +831,10 @@ |
| * to be deleted |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public synchronized void deleteDocuments(Term[] terms) throws CorruptIndexException, IOException { |
| + public synchronized void deleteDocuments(Term[] terms) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| for (int i = 0; i < terms.length; i++) { |
| bufferDeleteTerm(terms[i]); |
| } |
| @@ -777,8 +852,10 @@ |
| * @param doc the document to be added |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public void updateDocument(Term term, Document doc) throws CorruptIndexException, IOException { |
| + public void updateDocument(Term term, Document doc) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| updateDocument(term, doc, getAnalyzer()); |
| } |
| |
| @@ -794,9 +871,11 @@ |
| * @param analyzer the analyzer to use when analyzing the document |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| public void updateDocument(Term term, Document doc, Analyzer analyzer) |
| - throws CorruptIndexException, IOException { |
| + throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| SegmentInfo newSegmentInfo = buildSingleDocSegment(doc, analyzer); |
| synchronized (this) { |
| bufferDeleteTerm(term); |
| @@ -929,8 +1008,10 @@ |
| * compound format.</p> |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public synchronized void optimize() throws CorruptIndexException, IOException { |
| + public synchronized void optimize() throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| flushRamSegments(); |
| while (segmentInfos.size() > 1 || |
| (segmentInfos.size() == 1 && |
| @@ -1068,10 +1149,12 @@ |
| * for details.</p> |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| public synchronized void addIndexes(Directory[] dirs) |
| - throws CorruptIndexException, IOException { |
| + throws CorruptIndexException, IOException, AlreadyClosedException { |
| |
| + ensureOpen(); |
| optimize(); // start with zero or 1 seg |
| |
| int start = segmentInfos.size(); |
| @@ -1126,9 +1209,10 @@ |
| * on an Exception.</p> |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| public synchronized void addIndexesNoOptimize(Directory[] dirs) |
| - throws CorruptIndexException, IOException { |
| + throws CorruptIndexException, IOException, AlreadyClosedException { |
| // Adding indexes can be viewed as adding a sequence of segments S to |
| // a sequence of segments T. Segments in T follow the invariants but |
| // segments in S may not since they could come from multiple indexes. |
| @@ -1157,6 +1241,7 @@ |
| |
| // 1 flush ram segments |
| |
| + ensureOpen(); |
| flushRamSegments(); |
| |
| // 2 copy segment infos and find the highest level from dirs |
| @@ -1264,10 +1349,12 @@ |
| * on an Exception.</p> |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| public synchronized void addIndexes(IndexReader[] readers) |
| - throws CorruptIndexException, IOException { |
| + throws CorruptIndexException, IOException, AlreadyClosedException { |
| |
| + ensureOpen(); |
| optimize(); // start with zero or 1 seg |
| |
| final String mergedName = newSegmentName(); |
| @@ -1407,22 +1494,28 @@ |
| * to the Directory. |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public final synchronized void flush() throws CorruptIndexException, IOException { |
| + public final synchronized void flush() throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| flushRamSegments(); |
| } |
| |
| /** Expert: Return the total size of all index files currently cached in memory. |
| * Useful for size management with flushRamDocs() |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public final long ramSizeInBytes() { |
| + public final long ramSizeInBytes() throws AlreadyClosedException { |
| + ensureOpen(); |
| return ramDirectory.sizeInBytes(); |
| } |
| |
| /** Expert: Return the number of documents whose segments are currently cached in memory. |
| * Useful when calling flushRamSegments() |
| + * @throws AlreadyClosedException if this IndexWriter is closed |
| */ |
| - public final synchronized int numRamDocs() { |
| + public final synchronized int numRamDocs() throws AlreadyClosedException { |
| + ensureOpen(); |
| return ramSegmentInfos.size(); |
| } |
| |
| Index: src/java/org/apache/lucene/index/ParallelReader.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/ParallelReader.java (revision 513819) |
| +++ src/java/org/apache/lucene/index/ParallelReader.java (working copy) |
| @@ -21,6 +21,7 @@ |
| import org.apache.lucene.document.Fieldable; |
| import org.apache.lucene.document.FieldSelector; |
| import org.apache.lucene.document.FieldSelectorResult; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| |
| import java.io.IOException; |
| import java.util.SortedMap; |
| @@ -66,8 +67,12 @@ |
| /** Construct a ParallelReader. */ |
| public ParallelReader() throws IOException { super(null); } |
| |
| - /** Add an IndexReader. */ |
| - public void add(IndexReader reader) throws IOException { |
| + /** Add an IndexReader. |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| + */ |
| + public void add(IndexReader reader) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| add(reader, false); |
| } |
| |
| @@ -79,10 +84,13 @@ |
| * of documents |
| * @throws IllegalArgumentException if not all indexes have the same value |
| * of {@link IndexReader#maxDoc()} |
| + * @throws IOException if there is a low-level IO error |
| + * @throws AlreadyClosedException if this IndexReader is closed |
| */ |
| public void add(IndexReader reader, boolean ignoreStoredFields) |
| - throws IOException { |
| + throws IOException, AlreadyClosedException { |
| |
| + ensureOpen(); |
| if (readers.size() == 0) { |
| this.maxDoc = reader.maxDoc(); |
| this.numDocs = reader.numDocs(); |
| @@ -110,14 +118,24 @@ |
| readers.add(reader); |
| } |
| |
| - public int numDocs() { return numDocs; } |
| + public int numDocs() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return numDocs; |
| + } |
| |
| - public int maxDoc() { return maxDoc; } |
| + public int maxDoc() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return maxDoc; |
| + } |
| |
| - public boolean hasDeletions() { return hasDeletions; } |
| + public boolean hasDeletions() throws AlreadyClosedException { |
| + ensureOpen(); |
| + return hasDeletions; |
| + } |
| |
| // check first reader |
| - public boolean isDeleted(int n) { |
| + public boolean isDeleted(int n) throws AlreadyClosedException { |
| + ensureOpen(); |
| if (readers.size() > 0) |
| return ((IndexReader)readers.get(0)).isDeleted(n); |
| return false; |
| @@ -140,7 +158,8 @@ |
| } |
| |
| // append fields from storedFieldReaders |
| - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { |
| + public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| Document result = new Document(); |
| for (int i = 0; i < storedFieldReaders.size(); i++) { |
| IndexReader reader = (IndexReader)storedFieldReaders.get(i); |
| @@ -165,7 +184,8 @@ |
| } |
| |
| // get all vectors |
| - public TermFreqVector[] getTermFreqVectors(int n) throws IOException { |
| + public TermFreqVector[] getTermFreqVectors(int n) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| ArrayList results = new ArrayList(); |
| Iterator i = fieldToReader.entrySet().iterator(); |
| while (i.hasNext()) { |
| @@ -181,23 +201,27 @@ |
| } |
| |
| public TermFreqVector getTermFreqVector(int n, String field) |
| - throws IOException { |
| + throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| IndexReader reader = ((IndexReader)fieldToReader.get(field)); |
| return reader==null ? null : reader.getTermFreqVector(n, field); |
| } |
| |
| - public boolean hasNorms(String field) throws IOException { |
| + public boolean hasNorms(String field) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| IndexReader reader = ((IndexReader)fieldToReader.get(field)); |
| return reader==null ? false : reader.hasNorms(field); |
| } |
| |
| - public byte[] norms(String field) throws IOException { |
| + public byte[] norms(String field) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| IndexReader reader = ((IndexReader)fieldToReader.get(field)); |
| return reader==null ? null : reader.norms(field); |
| } |
| |
| public void norms(String field, byte[] result, int offset) |
| - throws IOException { |
| + throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| IndexReader reader = ((IndexReader)fieldToReader.get(field)); |
| if (reader!=null) |
| reader.norms(field, result, offset); |
| @@ -210,32 +234,39 @@ |
| reader.doSetNorm(n, field, value); |
| } |
| |
| - public TermEnum terms() throws IOException { |
| + public TermEnum terms() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new ParallelTermEnum(); |
| } |
| |
| - public TermEnum terms(Term term) throws IOException { |
| + public TermEnum terms(Term term) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new ParallelTermEnum(term); |
| } |
| |
| - public int docFreq(Term term) throws IOException { |
| + public int docFreq(Term term) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| IndexReader reader = ((IndexReader)fieldToReader.get(term.field())); |
| return reader==null ? 0 : reader.docFreq(term); |
| } |
| |
| - public TermDocs termDocs(Term term) throws IOException { |
| + public TermDocs termDocs(Term term) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new ParallelTermDocs(term); |
| } |
| |
| - public TermDocs termDocs() throws IOException { |
| + public TermDocs termDocs() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new ParallelTermDocs(); |
| } |
| |
| - public TermPositions termPositions(Term term) throws IOException { |
| + public TermPositions termPositions(Term term) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new ParallelTermPositions(term); |
| } |
| |
| - public TermPositions termPositions() throws IOException { |
| + public TermPositions termPositions() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new ParallelTermPositions(); |
| } |
| |
| @@ -250,7 +281,8 @@ |
| } |
| |
| |
| - public Collection getFieldNames (IndexReader.FieldOption fieldNames) { |
| + public Collection getFieldNames (IndexReader.FieldOption fieldNames) throws AlreadyClosedException { |
| + ensureOpen(); |
| Set fieldSet = new HashSet(); |
| for (int i = 0; i < readers.size(); i++) { |
| IndexReader reader = ((IndexReader)readers.get(i)); |
| Index: src/java/org/apache/lucene/index/SegmentReader.java |
| =================================================================== |
| --- src/java/org/apache/lucene/index/SegmentReader.java (revision 513819) |
| +++ src/java/org/apache/lucene/index/SegmentReader.java (working copy) |
| @@ -23,6 +23,7 @@ |
| import org.apache.lucene.store.Directory; |
| import org.apache.lucene.store.IndexInput; |
| import org.apache.lucene.store.IndexOutput; |
| +import org.apache.lucene.store.AlreadyClosedException; |
| import org.apache.lucene.util.BitVector; |
| |
| import java.io.IOException; |
| @@ -279,7 +280,8 @@ |
| return si.hasDeletions(); |
| } |
| |
| - public boolean hasDeletions() { |
| + public boolean hasDeletions() throws AlreadyClosedException { |
| + ensureOpen(); |
| return deletedDocs != null; |
| } |
| |
| @@ -339,11 +341,13 @@ |
| return files; |
| } |
| |
| - public TermEnum terms() { |
| + public TermEnum terms() throws AlreadyClosedException { |
| + ensureOpen(); |
| return tis.terms(); |
| } |
| |
| - public TermEnum terms(Term t) throws IOException { |
| + public TermEnum terms(Term t) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return tis.terms(t); |
| } |
| |
| @@ -351,26 +355,31 @@ |
| * @throws CorruptIndexException if the index is corrupt |
| * @throws IOException if there is a low-level IO error |
| */ |
| - public synchronized Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { |
| + public synchronized Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException, AlreadyClosedException { |
| + ensureOpen(); |
| if (isDeleted(n)) |
| throw new IllegalArgumentException |
| ("attempt to access a deleted document"); |
| return fieldsReader.doc(n, fieldSelector); |
| } |
| |
| - public synchronized boolean isDeleted(int n) { |
| + public synchronized boolean isDeleted(int n) throws AlreadyClosedException { |
| + ensureOpen(); |
| return (deletedDocs != null && deletedDocs.get(n)); |
| } |
| |
| - public TermDocs termDocs() throws IOException { |
| + public TermDocs termDocs() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new SegmentTermDocs(this); |
| } |
| |
| - public TermPositions termPositions() throws IOException { |
| + public TermPositions termPositions() throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| return new SegmentTermPositions(this); |
| } |
| |
| - public int docFreq(Term t) throws IOException { |
| + public int docFreq(Term t) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| TermInfo ti = tis.get(t); |
| if (ti != null) |
| return ti.docFreq; |
| @@ -378,21 +387,24 @@ |
| return 0; |
| } |
| |
| - public int numDocs() { |
| + public int numDocs() throws AlreadyClosedException { |
| + ensureOpen(); |
| int n = maxDoc(); |
| if (deletedDocs != null) |
| n -= deletedDocs.count(); |
| return n; |
| } |
| |
| - public int maxDoc() { |
| + public int maxDoc() throws AlreadyClosedException { |
| + ensureOpen(); |
| return si.docCount; |
| } |
| |
| /** |
| * @see IndexReader#getFieldNames(IndexReader.FieldOption fldOption) |
| */ |
| - public Collection getFieldNames(IndexReader.FieldOption fieldOption) { |
| + public Collection getFieldNames(IndexReader.FieldOption fieldOption) throws AlreadyClosedException { |
| + ensureOpen(); |
| |
| Set fieldSet = new HashSet(); |
| for (int i = 0; i < fieldInfos.size(); i++) { |
| @@ -433,7 +445,8 @@ |
| } |
| |
| |
| - public synchronized boolean hasNorms(String field) { |
| + public synchronized boolean hasNorms(String field) throws AlreadyClosedException { |
| + ensureOpen(); |
| return norms.containsKey(field); |
| } |
| |
| @@ -462,7 +475,8 @@ |
| } |
| |
| // returns fake norms if norms aren't available |
| - public synchronized byte[] norms(String field) throws IOException { |
| + public synchronized byte[] norms(String field) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| byte[] bytes = getNorms(field); |
| if (bytes==null) bytes=fakeNorms(); |
| return bytes; |
| @@ -481,8 +495,9 @@ |
| |
| /** Read norms into a pre-allocated array. */ |
| public synchronized void norms(String field, byte[] bytes, int offset) |
| - throws IOException { |
| + throws IOException, AlreadyClosedException { |
| |
| + ensureOpen(); |
| Norm norm = (Norm) norms.get(field); |
| if (norm == null) { |
| System.arraycopy(fakeNorms(), 0, bytes, offset, maxDoc()); |
| @@ -551,8 +566,9 @@ |
| * flag set. If the flag was not set, the method returns null. |
| * @throws IOException |
| */ |
| - public TermFreqVector getTermFreqVector(int docNumber, String field) throws IOException { |
| + public TermFreqVector getTermFreqVector(int docNumber, String field) throws IOException, AlreadyClosedException { |
| // Check if this field is invalid or has no stored term vector |
| + ensureOpen(); |
| FieldInfo fi = fieldInfos.fieldInfo(field); |
| if (fi == null || !fi.storeTermVector || termVectorsReaderOrig == null) |
| return null; |
| @@ -572,7 +588,8 @@ |
| * If no such fields existed, the method returns null. |
| * @throws IOException |
| */ |
| - public TermFreqVector[] getTermFreqVectors(int docNumber) throws IOException { |
| + public TermFreqVector[] getTermFreqVectors(int docNumber) throws IOException, AlreadyClosedException { |
| + ensureOpen(); |
| if (termVectorsReaderOrig == null) |
| return null; |
| |
| Index: src/java/org/apache/lucene/store/AlreadyClosedException.java |
| =================================================================== |
| --- src/java/org/apache/lucene/store/AlreadyClosedException.java (revision 0) |
| +++ src/java/org/apache/lucene/store/AlreadyClosedException.java (revision 0) |
| @@ -0,0 +1,28 @@ |
| +package org.apache.lucene.store; |
| + |
| +/** |
| + * Licensed to the Apache Software Foundation (ASF) under one or more |
| + * contributor license agreements. See the NOTICE file distributed with |
| + * this work for additional information regarding copyright ownership. |
| + * The ASF licenses this file to You under the Apache License, Version 2.0 |
| + * (the "License"); you may not use this file except in compliance with |
| + * the License. You may obtain a copy of the License at |
| + * |
| + * http://www.apache.org/licenses/LICENSE-2.0 |
| + * |
| + * Unless required by applicable law or agreed to in writing, software |
| + * distributed under the License is distributed on an "AS IS" BASIS, |
| + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| + * See the License for the specific language governing permissions and |
| + * limitations under the License. |
| + */ |
| + |
| +/** |
| + * This exception is thrown when there is an attempt to |
| + * access something that has already been closed. |
| + */ |
| +public class AlreadyClosedException extends IllegalStateException { |
| + public AlreadyClosedException(String message) { |
| + super(message); |
| + } |
| +} |
| |
| Property changes on: src/java/org/apache/lucene/store/AlreadyClosedException.java |
| ___________________________________________________________________ |
| Name: svn:eol-style |
| + native |
| |