You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by im...@apache.org on 2005/10/13 20:18:53 UTC

svn commit: r320848 - in /jakarta/commons/proper/vfs/trunk: ./ src/java/org/apache/commons/vfs/ src/java/org/apache/commons/vfs/provider/ src/java/org/apache/commons/vfs/provider/jar/ src/java/org/apache/commons/vfs/provider/tar/ src/java/org/apache/co...

Author: imario
Date: Thu Oct 13 11:18:37 2005
New Revision: 320848

URL: http://svn.apache.org/viewcvs?rev=320848&view=rev
Log:
zip, jar, tar:
close archive if there is no open stream. This avoids locking on the archive.

Modified:
    jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/FileContent.java
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/DefaultFileContent.java
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileObject.java
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileSystem.java
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/tar/TarFileSystem.java
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileObject.java
    jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystem.java
    jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/test/AbstractProviderTestCase.java

Modified: jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt (original)
+++ jakarta/commons/proper/vfs/trunk/RELEASE_NOTES.txt Thu Oct 13 11:18:37 2005
@@ -1,3 +1,9 @@
+2005-10 commons-vfs 1.0 RC5
+
+zip, jar, tar:
+close archive if there is no open stream. This avoids locking on the archive.
+
+
 2005-09-26  commons-vfs 1.0 RC4
 
 bzip:

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/FileContent.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/FileContent.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/FileContent.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/FileContent.java Thu Oct 13 11:18:37 2005
@@ -197,9 +197,13 @@
      */
     void close() throws FileSystemException;
 
-
     /**
      * get the content info. e.g. type, encoding, ...
      */
     public FileContentInfo getContentInfo() throws FileSystemException;
+
+    /**
+     * check if this file has open streams
+     */
+    public boolean isOpen();
 }

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java Thu Oct 13 11:18:37 2005
@@ -40,10 +40,10 @@
 import java.security.PrivilegedExceptionAction;
 import java.security.cert.Certificate;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Arrays;
 
 /**
  * A partial file object implementation.
@@ -905,7 +905,7 @@
                 doRename(destFile);
 
                 ((AbstractFileObject) destFile).handleCreate(getType());
-                
+
                 destFile.close(); // now the destFile is no longer imaginary. force reattach.
 
                 handleDelete(); // fire delete-events. This file-object (src) is like deleted.
@@ -1523,5 +1523,12 @@
             objects = new ArrayList(5);
         }
         objects.add(strongRef);
+    }
+
+    /**
+     * will be called after this file-object closed all its streams.
+     */
+    protected void notifyAllStreamsClosed()
+    {
     }
 }

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java Thu Oct 13 11:18:37 2005
@@ -80,6 +80,11 @@
 
     private FileSystemKey cacheKey;
 
+    /**
+     * open streams counter for this filesystem
+     */
+    private int openStreams;
+
     protected AbstractFileSystem(final FileName rootName,
                                  final FileObject parentLayer,
                                  final FileSystemOptions fileSystemOptions)
@@ -447,7 +452,6 @@
 
     void freeResources()
     {
-
     }
 
     /**
@@ -499,5 +503,46 @@
     FileSystemKey getCacheKey()
     {
         return this.cacheKey;
+    }
+
+    void streamOpened()
+    {
+        synchronized (this)
+        {
+            openStreams++;
+        }
+    }
+
+    void streamClosed()
+    {
+        synchronized (this)
+        {
+            if (openStreams > 0)
+            {
+                openStreams--;
+                if (openStreams < 1)
+                {
+                    notifyAllStreamsClosed();
+                }
+            }
+        }
+    }
+
+    /**
+     * will be called after all file-objects closed their streams.
+     */
+    protected void notifyAllStreamsClosed()
+    {
+    }
+
+    /**
+     * check if this filesystem has open streams
+     */
+    public boolean isOpen()
+    {
+        synchronized (this)
+        {
+            return openStreams > 0;
+        }
     }
 }

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/DefaultFileContent.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/DefaultFileContent.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/DefaultFileContent.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/DefaultFileContent.java Thu Oct 13 11:18:37 2005
@@ -48,6 +48,7 @@
     static final int STATE_WRITING = 2;
     static final int STATE_RANDOM_ACCESS = 3;
     */
+
     static final int STATE_CLOSED = 0;
     static final int STATE_OPENED = 1;
 
@@ -59,6 +60,11 @@
 
     private final ThreadLocal threadData = new ThreadLocal();
 
+    /**
+     * open streams counter for this file
+     */
+    private int openStreams = 0;
+
     public DefaultFileContent(final AbstractFileObject file, final FileContentInfoFactory fileContentInfoFactory)
     {
         this.file = file;
@@ -76,6 +82,31 @@
         return data;
     }
 
+    void streamOpened()
+    {
+        synchronized (this)
+        {
+            openStreams++;
+        }
+        ((AbstractFileSystem) file.getFileSystem()).streamOpened();
+    }
+
+    void streamClosed()
+    {
+        synchronized (this)
+        {
+            if (openStreams > 0)
+            {
+                openStreams--;
+                if (openStreams < 1)
+                {
+                    file.notifyAllStreamsClosed();
+                }
+            }
+        }
+        ((AbstractFileSystem) file.getFileSystem()).streamClosed();
+    }
+
     /**
      * Returns the file that this is the content of.
      */
@@ -280,7 +311,10 @@
         // Get the raw input stream
         final InputStream instr = file.getInputStream();
         final InputStream wrappedInstr = new FileContentInputStream(file, instr);
+
         this.getThreadData().addInstr(wrappedInstr);
+        streamOpened();
+
         // setState(STATE_OPENED);
         return wrappedInstr;
     }
@@ -300,7 +334,10 @@
 
         // Get the content
         final RandomAccessContent rastr = file.getRandomAccessContent(mode);
+
         this.getThreadData().setRastr(new FileRandomAccessContent(file, rastr));
+        streamOpened();
+
         // setState(STATE_OPENED);
         return this.getThreadData().getRastr();
     }
@@ -331,6 +368,8 @@
 
         // Create wrapper
         this.getThreadData().setOutstr(new FileContentOutputStream(file, outstr));
+        streamOpened();
+
         // setState(STATE_OPENED);
         return this.getThreadData().getOutstr();
     }
@@ -381,6 +420,7 @@
     private void endInput(final FileContentInputStream instr)
     {
         getThreadData().removeInstr(instr);
+        streamClosed();
         /*
         if (!getThreadData().hasStreams())
         {
@@ -394,6 +434,7 @@
      */
     private void endRandomAccess()
     {
+        streamClosed();
         // setState(STATE_CLOSED);
     }
 
@@ -402,6 +443,8 @@
      */
     private void endOutput() throws Exception
     {
+        streamClosed();
+
         this.getThreadData().setOutstr(null);
         // setState(STATE_CLOSED);
 
@@ -416,7 +459,8 @@
     */
 
     /**
-     * check if a input and/or output stream is open.
+     * check if a input and/or output stream is open.<br />
+     * This checks only the scope of the current thread.
      *
      * @return true if this is the case
      */
@@ -424,6 +468,20 @@
     {
         // return getThreadData().getState() == STATE_OPENED;
         return getThreadData().hasStreams();
+    }
+
+    /**
+     * check if a input and/or output stream is open.<br />
+     * This checks all threads.
+     *
+     * @return true if this is the case
+     */
+    public boolean isOpenGlobal()
+    {
+        synchronized (this)
+        {
+            return openStreams > 0;
+        }
     }
 
     /**

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileObject.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileObject.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileObject.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileObject.java Thu Oct 13 11:18:37 2005
@@ -49,6 +49,15 @@
     {
         super(name, entry, fs, zipExists);
         this.fs = fs;
+
+        try
+        {
+            getAttributes(); // early get the attributes as the zip file might be closed
+        }
+        catch (IOException e)
+        {
+            throw new FileSystemException(e);
+        }
     }
 
     /**

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileSystem.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileSystem.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileSystem.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/jar/JarFileSystem.java Thu Oct 13 11:18:37 2005
@@ -215,6 +215,7 @@
         return getAttribute(name);
     }
 
+
     protected ZipFile getZipFile() throws FileSystemException
     {
         return super.getZipFile();

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/tar/TarFileSystem.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/tar/TarFileSystem.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/tar/TarFileSystem.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/tar/TarFileSystem.java Thu Oct 13 11:18:37 2005
@@ -72,7 +72,7 @@
             return;
         }
 
-        tarFile = createTarFile(this.file);
+        // tarFile = createTarFile(this.file);
     }
 
     public void init() throws FileSystemException
@@ -128,6 +128,10 @@
         {
             throw new FileSystemException(e);
         }
+        finally
+        {
+            closeCommunicationLink();
+        }
     }
 
     public InputStream getInputStream(TarEntry entry) throws FileSystemException
@@ -244,5 +248,13 @@
     {
         // This is only called for files which do not exist in the Tar file
         return new TarFileObject(name, null, this, false);
+    }
+
+    /**
+     * will be called after all file-objects closed their streams.
+     */
+    protected void notifyAllStreamsClosed()
+    {
+        closeCommunicationLink();
     }
 }

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileObject.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileObject.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileObject.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileObject.java Thu Oct 13 11:18:37 2005
@@ -19,12 +19,9 @@
 import org.apache.commons.vfs.FileObject;
 import org.apache.commons.vfs.FileSystemException;
 import org.apache.commons.vfs.FileType;
-import org.apache.commons.vfs.util.MonitorInputStream;
 import org.apache.commons.vfs.provider.AbstractFileObject;
-import org.apache.commons.vfs.provider.AbstractFileSystem;
 
 import java.io.InputStream;
-import java.io.IOException;
 import java.util.HashSet;
 import java.util.zip.ZipEntry;
 
@@ -137,23 +134,6 @@
      */
     protected InputStream doGetInputStream() throws Exception
     {
-        return new MonitorInputStream(fs.getZipFile().getInputStream(entry))
-        {
-            protected void onClose() throws IOException
-            {
-                ZipFileObject.this.close();
-            }
-        };
-    }
-
-    public void close() throws FileSystemException
-    {
-        super.close();
-
-        AbstractFileSystem fs = (AbstractFileSystem) getFileSystem();
-        if (fs.isReleaseable())
-        {
-            fs.closeCommunicationLink();
-        }
+        return fs.getZipFile().getInputStream(entry);
     }
 }

Modified: jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystem.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystem.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystem.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/java/org/apache/commons/vfs/provider/zip/ZipFileSystem.java Thu Oct 13 11:18:37 2005
@@ -76,50 +76,56 @@
     {
         super.init();
 
-        // Build the index
-        List strongRef = new ArrayList(100);
-        Enumeration entries = getZipFile().entries();
-        while (entries.hasMoreElements())
-        {
-            ZipEntry entry = (ZipEntry) entries.nextElement();
-            FileName name = getFileSystemManager().resolveName(getRootName(), UriParser.encode(entry.getName()));
-
-            // Create the file
-            ZipFileObject fileObj;
-            if (entry.isDirectory() && getFileFromCache(name) != null)
+        try
+        {
+            // Build the index
+            List strongRef = new ArrayList(100);
+            Enumeration entries = getZipFile().entries();
+            while (entries.hasMoreElements())
             {
-                fileObj = (ZipFileObject) getFileFromCache(name);
-                fileObj.setZipEntry(entry);
-                continue;
-            }
+                ZipEntry entry = (ZipEntry) entries.nextElement();
+                FileName name = getFileSystemManager().resolveName(getRootName(), UriParser.encode(entry.getName()));
 
-            fileObj = createZipFileObject(name, entry);
-            putFileToCache(fileObj);
-            strongRef.add(fileObj);
-            fileObj.holdObject(strongRef);
-
-            // Make sure all ancestors exist
-            // TODO - create these on demand
-            ZipFileObject parent = null;
-            for (FileName parentName = name.getParent();
-                 parentName != null;
-                 fileObj = parent, parentName = parentName.getParent())
-            {
-                // Locate the parent
-                parent = (ZipFileObject) getFileFromCache(parentName);
-                if (parent == null)
+                // Create the file
+                ZipFileObject fileObj;
+                if (entry.isDirectory() && getFileFromCache(name) != null)
                 {
-                    parent = createZipFileObject(parentName, null);
-                    putFileToCache(parent);
-                    strongRef.add(parent);
-                    parent.holdObject(strongRef);
+                    fileObj = (ZipFileObject) getFileFromCache(name);
+                    fileObj.setZipEntry(entry);
+                    continue;
                 }
 
-                // Attach child to parent
-                parent.attachChild(fileObj.getName());
+                fileObj = createZipFileObject(name, entry);
+                putFileToCache(fileObj);
+                strongRef.add(fileObj);
+                fileObj.holdObject(strongRef);
+
+                // Make sure all ancestors exist
+                // TODO - create these on demand
+                ZipFileObject parent = null;
+                for (FileName parentName = name.getParent();
+                     parentName != null;
+                     fileObj = parent, parentName = parentName.getParent())
+                {
+                    // Locate the parent
+                    parent = (ZipFileObject) getFileFromCache(parentName);
+                    if (parent == null)
+                    {
+                        parent = createZipFileObject(parentName, null);
+                        putFileToCache(parent);
+                        strongRef.add(parent);
+                        parent.holdObject(strongRef);
+                    }
+
+                    // Attach child to parent
+                    parent.attachChild(fileObj.getName());
+                }
             }
         }
-        closeCommunicationLink();
+        finally
+        {
+            closeCommunicationLink();
+        }
     }
 
     protected ZipFile getZipFile() throws FileSystemException
@@ -185,5 +191,13 @@
     {
         // This is only called for files which do not exist in the Zip file
         return new ZipFileObject(name, null, this, false);
+    }
+
+    /**
+     * will be called after all file-objects closed their streams.
+     */
+    protected void notifyAllStreamsClosed()
+    {
+        closeCommunicationLink();
     }
 }

Modified: jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/test/AbstractProviderTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/test/AbstractProviderTestCase.java?rev=320848&r1=320847&r2=320848&view=diff
==============================================================================
--- jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/test/AbstractProviderTestCase.java (original)
+++ jakarta/commons/proper/vfs/trunk/src/test/org/apache/commons/vfs/test/AbstractProviderTestCase.java Thu Oct 13 11:18:37 2005
@@ -19,11 +19,10 @@
 import org.apache.commons.vfs.Capability;
 import org.apache.commons.vfs.FileContent;
 import org.apache.commons.vfs.FileObject;
-import org.apache.commons.vfs.FileType;
-import org.apache.commons.vfs.FileSystemManager;
-import org.apache.commons.vfs.FileName;
 import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileType;
 import org.apache.commons.vfs.impl.DefaultFileSystemManager;
+import org.apache.commons.vfs.provider.AbstractFileSystem;
 
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
@@ -165,6 +164,17 @@
         else
         {
             super.runTest();
+        }
+
+        if (((AbstractFileSystem) readFolder.getFileSystem()).isOpen())
+        {
+            String name = "unknown";
+            if (method != null)
+            {
+                name = method.getName();
+            }
+
+            throw new IllegalStateException(getClass().getName() + ": filesystem has open streams after: " + name);
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org