Commits

Stephen Abrams committed b5d7dfe

Clean up handling of backing file and parent backing file for ByteStreamSource.

Comments (0)

Files changed (3)

src/main/java/org/jhove2/core/source/AbstractSource.java

      * Get little-endian {@link org.jhove2.core.io.Input} for the source unit
      * with the buffer size and type specified by the 
      * {@link org.jhove2.core.Invocation}.
+     * If this method is called explicitly, then the corresponding Input.close()
+     * method must be called to avoid a resource leak.
      * @param jhove2 JHOVE2 framework
      * @return Input for the source unit
      * @throws IOException 
 	 * parsable input (e.g. {@link org.jhove2.core.source.ClumpSource} or
 	 * {@link org.jhove2.core.source.DirectorySource} can let this inherited
 	 * method return null.
+     * If this method is called explicitly, then the corresponding Input.close()
+     * method must be called to avoid a resource leak.
 	 * @param jhove2 JHOVE2 framework object
 	 * @param order
 	 *            Byte order
 	}
 
 	/**
-	 * Get {@link java.io.InputStream} backing the source unit
+	 * Get {@link java.io.InputStream} backing the source unit.
+     * If this method is called explicitly, then the corresponding
+     * InputStream.close() method must be called to avoid a resource leak. 
 	 * 
 	 * @return Input stream backing the source unit, or null if a Clump,
 	 *         Directory, or FileSet source

src/main/java/org/jhove2/core/source/ByteStreamSource.java

     extends AbstractSource
     implements MeasurableSource
 {
-    /** Temporary backing file that is an appropriate subset of the parent
-     * source's backing file; not created unless it is actually requested.
+    /** The backing file of the parent source unit.  If parent is itself a
+     * ByteStreamSource, then the backing file of the parent's parent, and
+     * so on.
      */
-    protected File backingFile;
+    protected File parentFile;
      
     /** Buffer size (for creating temporary file). */
     protected int bufferSize;
         throws IOException, JHOVE2Exception
     {
         super();
-        this.file           = parent.getFile();
-        this.isTemp         = parent.isTemp();
+        if (parent instanceof ByteStreamSource) {
+            this.parentFile = ((ByteStreamSource) parent).getParentFile();
+        }
+        else {
+            this.parentFile = parent.getFile();
+        }
         this.size           = size;
         this.startingOffset = offset;
         this.endingOffset   = offset + size;
             this.endingOffset--;
         }
         this.name           = name;
-        this.backingFile    = null;
         
         /* Keep a copy of the temporary file prefix and suffix and I/O buffer
          * size in case we have to create a temporary backing file.
     @Override
     public void close() {
         super.close();
-        if (this.backingFile != null && this.deleteTempFileOnClose) {
-            this.backingFile.delete();
-            this.backingFile = null;
+        if (this.file != null && this.isTemp && this.deleteTempFileOnClose) {
+            this.file.delete();
+            this.file = null;
         }
     }
 
     }
 
     /**
-     * Get {@link java.io.File} backing only the byte stream subset of its
-     * parent source.
+     * Get {@link java.io.File} backing byte stream subset of its
+     * parent source.  Note that this File is not created until
+     * actually required, and will be deleted on close().
      * 
-     * @return File backing the byte stream
-     * @throws JHOVE2Exception 
+     * @return File backing the byte stream; or null if the backing
+     *         file cannot be created successfully
      */
-    public File getBackingFile()
-        throws IOException
+    @Override
+    public File getFile()
     {
-        if (this.backingFile == null) {
+        if (this.file == null) {
             /* Get format extension from name. */
             String ext = this.tmpSuffix;
             int in = name.lastIndexOf('.');
             if (in > -1) {
                 ext = name.substring(in);
             }
-            this.backingFile =
-                createTempFile(this.file, this.startingOffset,
+            try {
+                this.file =
+                    createTempFile(this.parentFile, this.startingOffset,
                                this.size, this.tmpDirectory,
                                this.tmpPrefix, ext, this.bufferSize);
+                this.isTemp = true;
+            }
+            catch (IOException e) {
+                /* Can't do anything more than return a null value. */
+            }
         }
-        return this.backingFile;
+        return this.file;
     }
 
     /**
-     * Get {@link java.io.InputStream} backing the source unit
+     * Get {@link java.io.InputStream} backing the source unit.
+     * If this method is called explicitly, then the corresponding
+     * InputStream.close() method must be called to avoid a resource leak. 
      * 
      * @return Input stream backing the source unit
      * @throws FileNotFoundException Backing file not found
         throws FileNotFoundException, IOException
     {
         InputStream stream = null;
-        stream = new FileInputStream(this.getBackingFile());
+        stream = new FileInputStream(this.getFile());
         return stream;
     }
      
+    /** Get parent file.  This is the file associated with the parent source
+     * unit, unless the parent is also a ByteStreamSource, in which case it
+     * is the file that parent source's parent, and so on.
+     * @return Parent file
+     */
+    public File getParentFile() {
+        return this.parentFile;
+    }
+    
     /** Get byte stream size, in bytes.
      * @return Byte stream size
      */

src/main/java/org/jhove2/core/source/Source.java

      * Get little-endian {@link org.jhove2.core.io.Input} for the source unit
      * with the buffer size and type specified by the
      * {@link org.jhove2.core.Invocation}.
-     * If this method is called explicitly, then the corresponding close()
+     * If this method is called explicitly, then the corresponding Input.close()
      * method must be called to avoid a resource leak.
      * @param jhove2 JHOVE2 framework
      * @return Input for the source unit
     /**
      * Get {@link org.jhove2.core.io.Input} for the source unit with the 
      * buffer size and type specified by the {@link org.jhove2.core.Invocation}.
-     * If this method is called explicitly and the source unit is not
-     * processed by the JHOVE2.characterize() method, then the corresponding
-     * close() method must be called to avoid a resource leak.
+     * If this method is called explicitly, then the corresponding
+     * Input.close() method must be called to avoid a resource leak.
      * @param jhove2 JHOVE2 framework
      * @param order  Byte order
      * @return Input for the source unit
   
 	/**
 	 * Get {@link java.io.InputStream} for the file backing the source unit.
+     * If this method is called explicitly, then the corresponding
+     * InputStream.close() method must be called to avoid a resource leak. 
 	 * 
 	 * @return Input stream for the file backing the source unit, or null if
 	 *         a Clump, Directory, or FileSet source