[jboss-cvs] JBossAS SVN: r98954 - projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Dec 30 15:11:39 EST 2009


Author: johnbailey
Date: 2009-12-30 15:11:39 -0500 (Wed, 30 Dec 2009)
New Revision: 98954

Modified:
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/Automounter.java
Log:
[JBAS-7342] - Updated Automounter to make a copy of an archive before mounting to avoid file locking issues

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/Automounter.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/Automounter.java	2009-12-30 13:10:16 UTC (rev 98953)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/Automounter.java	2009-12-30 20:11:39 UTC (rev 98954)
@@ -22,9 +22,11 @@
 package org.jboss.vfs.util;
 
 import java.io.Closeable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -32,6 +34,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.jboss.util.id.GUID;
 import org.jboss.vfs.TempFileProvider;
@@ -53,8 +56,11 @@
    private static final RegistryEntry rootEntry = new RegistryEntry();
 
    /* VirutalFile used as a base mount for 'hidden' original copies of mounted files */
-   private static final VirtualFile originalsRoot = VFS.getChild("/vfs/backups");
+   private static final VirtualFile originalsRoot = VFS.getChild("/.vfs/backups");
    
+   /* VirutalFile used as a base for all temporary filesytems created */
+   private static final VirtualFile tempRoot = VFS.getChild("/.vfs/tmp");
+   
    /* Possible mount types */
    private static enum MountType {
       ZIP, EXPANDED
@@ -153,7 +159,7 @@
    {
       RegistryEntry entry = getEntry(original); 
       entry.backup(original);
-      return entry.backup.file;
+      return entry.backupFile;
    }
    
    /**
@@ -164,8 +170,8 @@
     */
    public static VirtualFile getBackup(VirtualFile target) 
    {
-      Backup backup = getEntry(target).backup;
-      return backup != null ? backup.file : null;
+      RegistryEntry entry = getEntry(target);
+      return entry.backupFile != null ? entry.backupFile : null;
    }
    
    /**
@@ -176,7 +182,7 @@
     */
    public static boolean hasBackup(VirtualFile target) 
    {
-      return getEntry(target).backup != null;
+      return getEntry(target).backupFile != null;
    }
    
    
@@ -200,7 +206,7 @@
       return TempFileProvider.create(name, Executors.newSingleThreadScheduledExecutor());
    }
    
-   static class RegistryEntry
+   private static class RegistryEntry
    {
       private final ConcurrentMap<String, RegistryEntry> children = new ConcurrentHashMap<String, RegistryEntry>();
 
@@ -208,26 +214,28 @@
 
       private final Set<RegistryEntry> outboundReferences = new HashSet<RegistryEntry>();
 
-      private Closeable handle;
+      private final List<Closeable> handles = new LinkedList<Closeable>();
       
-      private Backup backup;
-
-      Collection<RegistryEntry> getChildren()
+      private final AtomicBoolean mounted = new AtomicBoolean();
+      
+      private VirtualFile backupFile;
+      
+      private void mount(RegistryEntry owner, VirtualFile target, MountType mountType) throws IOException
       {
-         return Collections.unmodifiableCollection(children.values());
-      }
-
-      void mount(RegistryEntry owner, VirtualFile target, MountType mountType) throws IOException
-      {
-         if (!isMounted())
+         if (mounted.compareAndSet(false, true))
          {
             if(target.isFile())
             {
+               final TempFileProvider provider = getTempFileProvider(target.getName());
+               // Make sure we can get to the original
                backup(target);
+               // Copy archive to temporary location to avoid file locking issues
+               File copy = copyArchiveFile(target, provider);
+               
                if (MountType.ZIP.equals(mountType))
-                  handle = VFS.mountZip(target, target, getTempFileProvider(target.getName()));
+                  handles.add(VFS.mountZip(copy, target, provider));
                else
-                  handle = VFS.mountZipExpanded(target, target, getTempFileProvider(target.getName()));
+                  handles.add(VFS.mountZipExpanded(copy, target, provider));
             }
          }
          if (owner.equals(this) == false)
@@ -237,8 +245,19 @@
          }
       }
 
-      void removeInboundReference(RegistryEntry owner)
+      
+      private File copyArchiveFile(VirtualFile target, final TempFileProvider provider) throws IOException,
+            FileNotFoundException
       {
+         VirtualFile tempLocation = tempRoot.getChild(GUID.asString());
+         handles.add(VFS.mountTemp(tempLocation, provider));
+         File copy = tempLocation.getChild(target.getName()).getPhysicalFile();
+         VFSUtils.copyStreamAndClose(target.openStream(), new FileOutputStream(copy));
+         return copy;
+      }
+
+      private void removeInboundReference(RegistryEntry owner)
+      {
          inboundReferences.remove(owner);
          if (inboundReferences.isEmpty())
          {
@@ -246,14 +265,10 @@
          }
       }
 
-      void cleanup()
+      private void cleanup()
       {
-         VFSUtils.safeClose(handle);
-         handle = null;
-         if(backup != null) {
-            VFSUtils.safeClose(backup.handle);
-            backup = null;
-         }
+         VFSUtils.safeClose(handles);
+         handles.clear();
 
          Collection<RegistryEntry> entries = getEntriesRecursive();
          for (RegistryEntry entry : entries)
@@ -264,19 +279,20 @@
          {
             entry.removeInboundReference(this);
          }
+         mounted.set(false);
       }
 
-      boolean isMounted()
+      private boolean isMounted()
       {
-         return handle != null;
+         return !handles.isEmpty();
       }
 
-      RegistryEntry find(VirtualFile file)
+      private RegistryEntry find(VirtualFile file)
       {
          return find(PathTokenizer.getTokens(file.getPathName()));
       }
 
-      RegistryEntry find(List<String> path)
+      private RegistryEntry find(List<String> path)
       {
          if (path.isEmpty())
          {
@@ -288,37 +304,26 @@
          return childEntry.find(path);
       }
 
-      Collection<RegistryEntry> getEntriesRecursive()
+      private Collection<RegistryEntry> getEntriesRecursive()
       {
          List<RegistryEntry> allHandles = new LinkedList<RegistryEntry>();
          collectEntries(this, allHandles);
          return allHandles;
       }
 
-      void collectEntries(RegistryEntry registryEntry, List<RegistryEntry> entries)
+      private void collectEntries(RegistryEntry registryEntry, List<RegistryEntry> entries)
       {
-         for (RegistryEntry childEntry : registryEntry.getChildren())
+         for (RegistryEntry childEntry : registryEntry.children.values())
          {
             collectEntries(childEntry, entries);
             entries.add(childEntry);
          }
       }
       
-      void backup(VirtualFile target) throws IOException
+      private void backup(VirtualFile target) throws IOException
       {
-         VirtualFile backupFile = originalsRoot.getChild(GUID.asString() + target.getName());
-         backup  = new Backup(backupFile, VFS.mountReal(target.getPhysicalFile(), backupFile));
+         backupFile = originalsRoot.getChild(GUID.asString() + target.getName());
+         handles.add(VFS.mountReal(target.getPhysicalFile(), backupFile));
       }
    }
-   
-   static class Backup {
-      private final VirtualFile file;
-      private final Closeable handle;
-
-      public Backup(VirtualFile backupFile, Closeable handle)
-      {
-         this.file = backupFile;
-         this.handle = handle;
-      }
-   }
 }




More information about the jboss-cvs-commits mailing list