Author: bdelacretaz
Date: Thu Oct 11 22:46:55 2007
New Revision: 584054

URL: http://svn.apache.org/viewvc?rev=584054&view=rev
Log:
TIKA-52 - RereadableInputStream needs to support not closing the input stream 
it wraps

Modified:
    incubator/tika/trunk/CHANGES.txt
    incubator/tika/trunk/src/main/java/org/apache/tika/ms/MSParser.java
    
incubator/tika/trunk/src/main/java/org/apache/tika/utils/RereadableInputStream.java
    
incubator/tika/trunk/src/test/java/org/apache/tika/RereadableInputStreamTest.java

Modified: incubator/tika/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/incubator/tika/trunk/CHANGES.txt?rev=584054&r1=584053&r2=584054&view=diff
==============================================================================
--- incubator/tika/trunk/CHANGES.txt (original)
+++ incubator/tika/trunk/CHANGES.txt Thu Oct 11 22:46:55 2007
@@ -88,3 +88,6 @@
 40. TIKA-55 - ParseUtils.getParser() method variants should have consistent 
parameter orders
               (K. Bennett)
 
+41. TIKA-52 - RereadableInputStream needs to support not closing the input 
stream it wraps.
+              (K. Bennett via bdelacretaz)
+

Modified: incubator/tika/trunk/src/main/java/org/apache/tika/ms/MSParser.java
URL: 
http://svn.apache.org/viewvc/incubator/tika/trunk/src/main/java/org/apache/tika/ms/MSParser.java?rev=584054&r1=584053&r2=584054&view=diff
==============================================================================
--- incubator/tika/trunk/src/main/java/org/apache/tika/ms/MSParser.java 
(original)
+++ incubator/tika/trunk/src/main/java/org/apache/tika/ms/MSParser.java Thu Oct 
11 22:46:55 2007
@@ -40,7 +40,7 @@
     public String parse(InputStream input, Metadata metadata)
             throws IOException, TikaException {
         RereadableInputStream ris =
-            new RereadableInputStream(input, MEMORY_THRESHOLD);
+            new RereadableInputStream(input, MEMORY_THRESHOLD, true, false);
         try {
             // First, extract properties
             POIFSReader reader = new POIFSReader();

Modified: 
incubator/tika/trunk/src/main/java/org/apache/tika/utils/RereadableInputStream.java
URL: 
http://svn.apache.org/viewvc/incubator/tika/trunk/src/main/java/org/apache/tika/utils/RereadableInputStream.java?rev=584054&r1=584053&r2=584054&view=diff
==============================================================================
--- 
incubator/tika/trunk/src/main/java/org/apache/tika/utils/RereadableInputStream.java
 (original)
+++ 
incubator/tika/trunk/src/main/java/org/apache/tika/utils/RereadableInputStream.java
 Thu Oct 11 22:46:55 2007
@@ -35,6 +35,12 @@
  */
 public class RereadableInputStream extends InputStream {
 
+
+    /**
+     * Input stream originally passed to the constructor.
+     */
+    private InputStream originalInputStream;
+
     /**
      * The inputStream currently being used by this object to read contents;
      * may be the original stream passed in, or a stream that reads
@@ -92,6 +98,14 @@
      */
     private boolean readToEndOfStreamOnFirstRewind = true;
 
+
+    /**
+     * Specifies whether or not to close the original input stream
+     * when close() is called.  Defaults to true.
+     */
+    private boolean closeOriginalStreamOnClose = true;
+
+
     // TODO: At some point it would be better to replace the current approach
     // (specifying the above) with more automated behavior.  The stream could
     // keep the original stream open until EOF was reached.  For example, if:
@@ -122,33 +136,20 @@
      *     garbage collection (i.e. its reference set to null) when the
      *     content size exceeds the array's size, when close() is called, or
      *     when there are no more references to the instance.
-     */
-    public RereadableInputStream(InputStream inputStream, int 
maxBytesInMemory) {
-        this(inputStream, maxBytesInMemory, true);
-    }
-
-    /**
-     * Creates a rereadable input stream.
-     *
-     * @param inputStream stream containing the source of data
-     * @param maxBytesInMemory maximum number of bytes to use to store
-     *     the stream's contents in memory before switching to disk; note that
-     *     the instance will preallocate a byte array whose size is
-     *     maxBytesInMemory.  This byte array will be made available for
-     *     garbage collection (i.e. its reference set to null) when the
-     *     content size exceeds the array's size, when close() is called, or
-     *     when there are no more references to the instance.
      * @param readToEndOfStreamOnFirstRewind Specifies whether or not to
      *     read to the end of stream on first rewind.  If this is set to false,
      *     then when rewind() is first called, only those bytes already read
      *     from the original stream will be available from then on.
      */
     public RereadableInputStream(InputStream inputStream, int maxBytesInMemory,
-            boolean readToEndOfStreamOnFirstRewind) {
+            boolean readToEndOfStreamOnFirstRewind,
+            boolean closeOriginalStreamOnClose) {
         this.inputStream = inputStream;
+        this.originalInputStream = inputStream;
         this.maxBytesInMemory = maxBytesInMemory;
         byteBuffer = new byte[maxBytesInMemory];
         this.readToEndOfStreamOnFirstRewind = readToEndOfStreamOnFirstRewind;
+        this.closeOriginalStreamOnClose = closeOriginalStreamOnClose;
     }
 
     /**
@@ -201,7 +202,10 @@
      */
     // Does anyone need/want for this to be public?
     private void closeStream() throws IOException {
-        if (inputStream != null) {
+        if (inputStream != null
+                &&
+                (inputStream != originalInputStream
+                        || closeOriginalStreamOnClose)) {
             inputStream.close();
             inputStream = null;
         }

Modified: 
incubator/tika/trunk/src/test/java/org/apache/tika/RereadableInputStreamTest.java
URL: 
http://svn.apache.org/viewvc/incubator/tika/trunk/src/test/java/org/apache/tika/RereadableInputStreamTest.java?rev=584054&r1=584053&r2=584054&view=diff
==============================================================================
--- 
incubator/tika/trunk/src/test/java/org/apache/tika/RereadableInputStreamTest.java
 (original)
+++ 
incubator/tika/trunk/src/test/java/org/apache/tika/RereadableInputStreamTest.java
 Thu Oct 11 22:46:55 2007
@@ -39,7 +39,7 @@
 
         InputStream is = createTestInputStream();
         RereadableInputStream ris = new RereadableInputStream(is,
-                MEMORY_THRESHOLD);
+                MEMORY_THRESHOLD, true, true);
         try {
             for (int pass = 0; pass < NUM_PASSES; pass++) {
                 for (int byteNum = 0; byteNum < TEST_SIZE; byteNum++) {
@@ -74,16 +74,12 @@
 
         try {
             InputStream s1 = createTestInputStream();
-            ris = new RereadableInputStream(s1, 5, readToEndOnRewind);
+            ris = new RereadableInputStream(s1, 5, readToEndOnRewind, true);
             ris.read();
             assertEquals(1, ris.getSize());
             ris.rewind();
             boolean moreBytesWereRead = (ris.getSize() > 1);
-            if (readToEndOnRewind) {
-                assertTrue(moreBytesWereRead);
-            } else {
-                assertFalse(moreBytesWereRead);
-            }
+            assertEquals(readToEndOnRewind, moreBytesWereRead);
         } finally {
             if (ris != null) {
                 ris.close();
@@ -92,8 +88,10 @@
 
     }
 
-    private InputStream createTestInputStream() throws IOException {
-        return new BufferedInputStream(new FileInputStream(createTestFile()));
+    private TestInputStream createTestInputStream() throws IOException {
+        return new TestInputStream(
+                new BufferedInputStream(
+                        new FileInputStream(createTestFile())));
     }
 
     private File createTestFile() throws IOException {
@@ -106,4 +104,46 @@
         fos.close();
         return testfile;
     }
+
+
+    public void testCloseBehavior() throws IOException {
+        doACloseBehaviorTest(true);
+        doACloseBehaviorTest(false);
+    }
+
+    private void doACloseBehaviorTest(boolean wantToClose) throws IOException {
+
+        TestInputStream tis = createTestInputStream();
+        RereadableInputStream ris =
+                new RereadableInputStream(tis, 5, true, wantToClose);
+        ris.close();
+        assertEquals(wantToClose, tis.isClosed());
+
+        if (! tis.isClosed()) {
+            tis.close();
+        }
+    }
+
+
+    /**
+     * Adds isClosed() to a BufferedInputStream.
+     */
+    class TestInputStream extends BufferedInputStream {
+
+        private boolean closed;
+
+        public TestInputStream(InputStream inputStream) {
+            super(inputStream);
+        }
+
+        public void close() throws IOException {
+            super.close();
+            closed = true;
+        }
+
+        public boolean isClosed() {
+            return closed;
+        }
+    }
+
 }


Reply via email to