[jboss-cvs] JBossAS SVN: r81472 - in projects/vfs/branches/Branch_2_0/src: main/java/org/jboss/virtual/plugins/cache and 17 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Nov 24 04:47:04 EST 2008


Author: alesj
Date: 2008-11-24 04:47:04 -0500 (Mon, 24 Nov 2008)
New Revision: 81472

Added:
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/IterableTimedVFSCache.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractExceptionHandler.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers/
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/ExceptionHandler.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/ExceptionHandlerTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/IterableTimedCacheTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/test/zipeinit.jar
Removed:
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/
   projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild
Modified:
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFS.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFSUtils.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/AbstractVFSCache.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/CachePolicyVFSCache.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/LRUVFSCache.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/PreInitializeVFSContexts.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/TimedVFSCache.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/VfsArchiveBrowserFactory.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/file/FileHandler.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/copy/AbstractCopyMechanism.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/vfs/helpers/PathTokenizer.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/protocol/AbstractVFSHandler.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/VFSContext.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/VirtualFileHandler.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache/VFSCache.java
   projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache/helpers/NoopVFSCache.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/AbstractVFSContextTest.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSContextUnitTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/JARVFSContextUnitTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/PathTokensTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSUnitTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java
   projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java
Log:
Merge with trunk.

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFS.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFS.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFS.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -27,14 +27,13 @@
 import java.util.List;
 
 import org.jboss.virtual.plugins.vfs.helpers.WrappingVirtualFileHandlerVisitor;
-import org.jboss.virtual.plugins.context.VfsArchiveBrowserFactory;
 import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VFSContextFactory;
 import org.jboss.virtual.spi.VFSContextFactoryLocator;
 import org.jboss.virtual.spi.VirtualFileHandler;
+import org.jboss.virtual.spi.ExceptionHandler;
 import org.jboss.virtual.spi.cache.VFSCacheFactory;
 import org.jboss.virtual.spi.cache.VFSCache;
-import org.jboss.util.file.ArchiveBrowser;
 
 /**
  * Virtual File System
@@ -55,8 +54,22 @@
    }
 
    /**
+    * Create a new VFS.
+    *
+    * @param context the context
+    * @throws IllegalArgumentException for a null context
+    */
+   public VFS(VFSContext context)
+   {
+      if (context == null)
+         throw new IllegalArgumentException("Null name");
+      this.context = context;
+   }
+
+   /**
     * Initialize VFS protocol handlers package property. 
     */
+   @SuppressWarnings({"deprecation", "unchecked"})
    public static void init()
    {
       String pkgs = System.getProperty("java.protocol.handler.pkgs");
@@ -70,13 +83,38 @@
          pkgs += "|org.jboss.virtual.protocol";
          System.setProperty("java.protocol.handler.pkgs", pkgs);
       }
+      org.jboss.virtual.plugins.context.VfsArchiveBrowserFactory factory = org.jboss.virtual.plugins.context.VfsArchiveBrowserFactory.INSTANCE;
       // keep this until AOP and HEM uses VFS internally instead of the stupid ArchiveBrowser crap.
-      ArchiveBrowser.factoryFinder.put("vfsfile", new VfsArchiveBrowserFactory());
-      ArchiveBrowser.factoryFinder.put("vfsjar", new VfsArchiveBrowserFactory());
-      ArchiveBrowser.factoryFinder.put("vfs", new VfsArchiveBrowserFactory());      
+      org.jboss.util.file.ArchiveBrowser.factoryFinder.put("vfsfile", factory);
+      org.jboss.util.file.ArchiveBrowser.factoryFinder.put("vfszip", factory);
+      org.jboss.util.file.ArchiveBrowser.factoryFinder.put("vfsjar", factory);
+      org.jboss.util.file.ArchiveBrowser.factoryFinder.put("vfs", factory);
    }
 
    /**
+    * Get the vfs context.
+    *
+    * This is package protected method.
+    * Same as VirtualFile::getHandler. 
+    *
+    * @return the vfs context
+    */
+   VFSContext getContext()
+   {
+      return context;
+   }
+
+   /**
+    * Set exception handler.
+    *
+    * @param exceptionHandler the exception handler.
+    */
+   public void setExceptionHandler(ExceptionHandler exceptionHandler)
+   {
+      context.setExceptionHandler(exceptionHandler);
+   }
+
+   /**
     * Get the virtual file system for a root uri
     * 
     * @param rootURI the root URI
@@ -123,7 +161,8 @@
    public static VirtualFile getCachedFile(URI rootURI) throws IOException
    {
       VFSCache cache = VFSCacheFactory.getInstance();
-      return cache.getFile(rootURI);
+      VirtualFile file = cache.getFile(rootURI);
+      return (file != null) ? file : getRoot(rootURI);
    }
 
    /**
@@ -135,6 +174,7 @@
     * @throws IOException if there is a problem accessing the VFS
     * @throws IllegalArgumentException if the rootURL or name is null
     */
+   @SuppressWarnings("deprecation")
    public static VirtualFile getVirtualFile(URI rootURI, String name) throws IOException
    {
       VFS vfs = getVFS(rootURI);
@@ -188,7 +228,8 @@
    public static VirtualFile getCachedFile(URL rootURL) throws IOException
    {
       VFSCache cache = VFSCacheFactory.getInstance();
-      return cache.getFile(rootURL);
+      VirtualFile file = cache.getFile(rootURL);
+      return (file != null) ? file : getRoot(rootURL);
    }
 
    /**
@@ -200,6 +241,7 @@
     * @throws IOException if there is a problem accessing the VFS
     * @throws IllegalArgumentException if the rootURL or name is null
     */
+   @SuppressWarnings("deprecation")
    public static VirtualFile getVirtualFile(URL rootURL, String name) throws IOException
    {
       VFS vfs = getVFS(rootURL);
@@ -207,19 +249,6 @@
    }
 
    /**
-    * Create a new VFS.
-    * 
-    * @param context the context
-    * @throws IllegalArgumentException for a null context
-    */
-   public VFS(VFSContext context)
-   {
-      if (context == null)
-         throw new IllegalArgumentException("Null name");
-      this.context = context;
-   }
-   
-   /**
     * Get the root file of this VFS
     * 
     * @return the root
@@ -283,6 +312,7 @@
     * @throws IllegalArgumentException if the path is null
     */
    @Deprecated
+   @SuppressWarnings("deprecation")
    public VirtualFile findChildFromRoot(String path) throws IOException
    {
       return findChild(path);

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFSUtils.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFSUtils.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFSUtils.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -25,11 +25,11 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLDecoder;
-import java.net.MalformedURLException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -112,6 +112,14 @@
    public static final String VFS_CACHE_KEY = "jboss.vfs.cache";
 
    /**
+    * Constant representing the URL file protocol
+    */
+   public static final String FILE_PROTOCOL = "file";
+   
+   /** Standard separator for JAR URL */
+   public static final String JAR_URL_SEPARATOR = "!/";
+   
+   /**
     * Stop cache.
     */
    public static void stopCache()
@@ -542,6 +550,21 @@
    }
 
    /**
+    * Get the options for this vfs.
+    *
+    * @param vfs the vfs
+    * @return options map
+    */
+   private static Map<String, String> getOptions(VFS vfs)
+   {
+      if (vfs == null)
+         throw new IllegalArgumentException("Null vfs");
+
+      VFSContext context = vfs.getContext();
+      return context.getOptions();
+   }
+
+   /**
     * Get the option.
     *
     * @param file the file
@@ -555,6 +578,19 @@
    }
 
    /**
+    * Get the option.
+    *
+    * @param vfs the vfs
+    * @param key the option key
+    * @return key's option
+    */
+   public static String getOption(VFS vfs, String key)
+   {
+      Map<String, String> options = getOptions(vfs);
+      return options != null ? options.get(key) : null;
+   }
+
+   /**
     * Enable option.
     *
     * @param file the file
@@ -585,6 +621,36 @@
    }
 
    /**
+    * Enable option.
+    *
+    * @param vfs the vfs
+    * @param optionName option name
+    */
+   protected static void enableOption(VFS vfs, String optionName)
+   {
+      Map<String, String> options = getOptions(vfs);
+      if (options == null)
+         throw new IllegalArgumentException("Cannot enable " + optionName + " on null options: " + vfs);
+
+      options.put(optionName, Boolean.TRUE.toString());
+   }
+
+   /**
+    * Disable option.
+    *
+    * @param vfs the vfs
+    * @param optionName option name
+    */
+   protected static void disableOption(VFS vfs, String optionName)
+   {
+      Map<String, String> options = getOptions(vfs);
+      if (options == null)
+         throw new IllegalArgumentException("Cannot disable " + optionName + " on null options: " + vfs);
+
+      options.remove(optionName);
+   }
+
+   /**
     * Enable copy for file param.
     *
     * @param file the file
@@ -605,8 +671,28 @@
    }
 
    /**
-    * Enable repaer for file param.
+    * Enable copy for vfs param.
     *
+    * @param vfs the vfs
+    */
+   public static void enableCopy(VFS vfs)
+   {
+      enableOption(vfs, USE_COPY_QUERY);
+   }
+
+   /**
+    * Disable copy for vfs param.
+    *
+    * @param vfs the vfs
+    */
+   public static void disableCopy(VFS vfs)
+   {
+      disableOption(vfs, USE_COPY_QUERY);
+   }
+
+   /**
+    * Enable reaper for file param.
+    *
     * @param file the file
     */
    public static void enableNoReaper(VirtualFile file)
@@ -625,6 +711,26 @@
    }
 
    /**
+    * Enable reaper for vfs param.
+    *
+    * @param vfs the vfs
+    */
+   public static void enableNoReaper(VFS vfs)
+   {
+      enableOption(vfs, NO_REAPER_QUERY);
+   }
+
+   /**
+    * Disable reaper for vfs param.
+    *
+    * @param vfs the vfs
+    */
+   public static void disableNoReaper(VFS vfs)
+   {
+      disableOption(vfs, NO_REAPER_QUERY);
+   }
+
+   /**
     * Enable case sensitive for file param.
     *
     * @param file the file
@@ -645,6 +751,26 @@
    }
 
    /**
+    * Enable case sensitive for vfs param.
+    *
+    * @param vfs the vfs
+    */
+   public static void enableCaseSensitive(VFS vfs)
+   {
+      enableOption(vfs, CASE_SENSITIVE_QUERY);
+   }
+
+   /**
+    * Disable case sensitive for vfs param.
+    *
+    * @param vfs the vfs
+    */
+   public static void disableCaseSensitive(VFS vfs)
+   {
+      disableOption(vfs, CASE_SENSITIVE_QUERY);
+   }
+
+   /**
     * Unpack the nested artifact under file param.
     *
     * @param file the file to unpack
@@ -907,4 +1033,19 @@
          return new URI(string);
       }
    };
+
+   /**
+    * Get real url.
+    * The closest thing that doesn't need the vfs url handlers.
+    *
+    * @param file the virtual file
+    * @return real url
+    * @throws IOException for any error
+    * @throws URISyntaxException for any uri syntac error
+    */
+   public static URL getRealURL(VirtualFile file) throws IOException, URISyntaxException
+   {
+      VirtualFileHandler handler = file.getHandler();
+      return handler.getRealURL();
+   }
 }

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/AbstractVFSCache.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/AbstractVFSCache.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/AbstractVFSCache.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -29,7 +29,6 @@
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.jboss.logging.Logger;
-import org.jboss.virtual.VFS;
 import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.spi.VFSContext;
@@ -61,6 +60,9 @@
 
    public VirtualFile getFile(URI uri) throws IOException
    {
+      if (uri == null)
+         throw new IllegalArgumentException("Null uri.");
+
       check();
 
       VFSContext context = findContext(uri);
@@ -69,9 +71,12 @@
          VirtualFileHandler root = context.getRoot();
          String relativePath = getRelativePath(context, uri);
          VirtualFileHandler child = root.getChild(relativePath);
+         if (child == null)
+            throw new IOException("Cannot find child, root=" + root + ", relativePath=" + relativePath);
+         
          return child.getVirtualFile();
       }
-      return VFS.getRoot(uri);
+      return null;
    }
 
    /**
@@ -90,6 +95,9 @@
 
    public VirtualFile getFile(URL url) throws IOException
    {
+      if (url == null)
+         throw new IllegalArgumentException("Null url.");
+
       check();
 
       try

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/CachePolicyVFSCache.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/CachePolicyVFSCache.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/CachePolicyVFSCache.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -32,11 +32,12 @@
 /**
  * Cache policy vfs cache.
  *
+ * @param <T> exact policy type
  * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
  */
-public abstract class CachePolicyVFSCache extends PathMatchingVFSCache
+public abstract class CachePolicyVFSCache<T extends CachePolicy> extends PathMatchingVFSCache
 {
-   private CachePolicy policy;
+   private T policy;
    private Map<Object, Object> properties;
 
    protected CachePolicyVFSCache()
@@ -59,6 +60,18 @@
       return policy != null ? policy.size() : -1;
    }
 
+   /**
+    * Get the policy.
+    * Run check before.
+    *
+    * @return the policy
+    */
+   protected T getPolicy()
+   {
+      check();
+      return policy;
+   }
+
    protected void check()
    {
       if (policy == null)
@@ -142,7 +155,7 @@
     *
     * @return the cache policy
     */
-   protected abstract CachePolicy createCachePolicy();
+   protected abstract T createCachePolicy();
 
    /**
     * Read instance properties.

Copied: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/IterableTimedVFSCache.java (from rev 81470, projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/cache/IterableTimedVFSCache.java)
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/IterableTimedVFSCache.java	                        (rev 0)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/IterableTimedVFSCache.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -0,0 +1,86 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.virtual.plugins.cache;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.net.URI;
+
+import org.jboss.virtual.spi.VFSContext;
+import org.jboss.util.TimedCachePolicy;
+
+/**
+ * Iterable timed cache policy vfs cache.
+ *
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public class IterableTimedVFSCache extends TimedVFSCache
+{
+   public IterableTimedVFSCache()
+   {
+   }
+
+   public IterableTimedVFSCache(Integer defaultLifetime)
+   {
+      super(defaultLifetime);
+   }
+
+   public IterableTimedVFSCache(Integer defaultLifetime, Boolean threadSafe, Integer resolution)
+   {
+      super(defaultLifetime, threadSafe, resolution);
+   }
+
+   public IterableTimedVFSCache(Map<Object, Object> properties)
+   {
+      super(properties);
+   }
+
+   @SuppressWarnings("unchecked")
+   protected VFSContext findContext(URI uri)
+   {
+      String uriString = stripProtocol(uri);
+      TimedCachePolicy tcp = getPolicy();
+      List validKeys = tcp.getValidKeys();
+      Set<String> keys = new TreeSet<String>(validKeys);
+      readLock();
+      try
+      {
+         for (String key : keys)
+         {
+            if (uriString.startsWith(key))
+               return getContext(key);
+         }
+      }
+      finally
+      {
+         readUnlock();
+      }
+      return null;
+   }
+
+   protected String getCacheName()
+   {
+      return "Iterable" + super.getCacheName();
+   }
+}
\ No newline at end of file

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/LRUVFSCache.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/LRUVFSCache.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/LRUVFSCache.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -23,7 +23,6 @@
 
 import java.util.Map;
 
-import org.jboss.util.CachePolicy;
 import org.jboss.util.LRUCachePolicy;
 import org.jboss.virtual.VFSUtils;
 
@@ -32,7 +31,7 @@
  *
  * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
  */
-public class LRUVFSCache extends CachePolicyVFSCache
+public class LRUVFSCache extends CachePolicyVFSCache<LRUCachePolicy>
 {
    private Integer min;
    private Integer max;
@@ -52,7 +51,7 @@
       super(properties);
    }
 
-   protected CachePolicy createCachePolicy()
+   protected LRUCachePolicy createCachePolicy()
    {
       if (min == null)
          min = getInteger(readInstanceProperties(VFSUtils.VFS_CACHE_KEY + ".LRUPolicyCaching.min", null, true));

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/PreInitializeVFSContexts.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/PreInitializeVFSContexts.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/PreInitializeVFSContexts.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -24,9 +24,12 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
 
 import org.jboss.logging.Logger;
 import org.jboss.virtual.VFS;
+import org.jboss.virtual.spi.ExceptionHandler;
 
 /**
  * Initialize vfs contexts - performance improvements.
@@ -36,7 +39,7 @@
 public class PreInitializeVFSContexts
 {
    private Logger log = Logger.getLogger(PreInitializeVFSContexts.class);
-   private List<URL> initializedVFSContexts;
+   private Map<URL, ExceptionHandler> initializedVFSContexts;
    private boolean holdReference;
    private List<VFS> references;
 
@@ -52,9 +55,14 @@
          if (holdReference)
             references = new ArrayList<VFS>();
 
-         for (URL url : initializedVFSContexts)
+         for (Map.Entry<URL, ExceptionHandler> entry : initializedVFSContexts.entrySet())
          {
-            VFS vfs = VFS.getVFS(url);
+            VFS vfs = VFS.getVFS(entry.getKey());
+
+            ExceptionHandler eh = entry.getValue();
+            if (eh != null)
+               vfs.setExceptionHandler(eh);
+
             log.debug("Initialized Virtual File: " + vfs.getRoot());
             if (holdReference)
             {
@@ -90,6 +98,20 @@
     */
    public void setInitializedVFSContexts(List<URL> initializedVFSContexts)
    {
+      this.initializedVFSContexts = new HashMap<URL, ExceptionHandler>();
+      for (URL url : initializedVFSContexts)
+      {
+         this.initializedVFSContexts.put(url, null);
+      }
+   }
+
+   /**
+    * Set URLs that need to be initialized before anything else.
+    *
+    * @param initializedVFSContexts the URLs to be initialized
+    */
+   public void setInitializedVFSContexts(Map<URL, ExceptionHandler> initializedVFSContexts)
+   {
       this.initializedVFSContexts = initializedVFSContexts;
    }
 

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/TimedVFSCache.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/TimedVFSCache.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache/TimedVFSCache.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -21,18 +21,21 @@
 */
 package org.jboss.virtual.plugins.cache;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 
-import org.jboss.util.CachePolicy;
 import org.jboss.util.TimedCachePolicy;
 import org.jboss.virtual.VFSUtils;
+import org.jboss.virtual.spi.VFSContext;
 
 /**
  * Timed cache policy vfs cache.
  *
  * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
  */
-public class TimedVFSCache extends CachePolicyVFSCache
+public class TimedVFSCache extends CachePolicyVFSCache<TimedCachePolicy>
 {
    private Integer defaultLifetime;
    private Boolean threadSafe;
@@ -61,8 +64,25 @@
       super(properties);
    }
 
-   protected CachePolicy createCachePolicy()
+   @Override
+   @SuppressWarnings("unchecked")
+   public Iterable<VFSContext> getCachedContexts()
    {
+      TimedCachePolicy tcp = getPolicy();
+      List keys = tcp.getValidKeys();
+      if (keys != null && keys.isEmpty() == false)
+      {
+         Map<Object, VFSContext> contexts = new TreeMap<Object, VFSContext>();
+         for (Object key : keys)
+            contexts.put(key, (VFSContext)tcp.peek(key));
+
+         return contexts.values();
+      }
+      return Collections.emptySet();
+   }
+
+   protected TimedCachePolicy createCachePolicy()
+   {
       if (defaultLifetime == null)
          defaultLifetime = getInteger(readInstanceProperties(VFSUtils.VFS_CACHE_KEY + ".TimedPolicyCaching.lifetime", null, true));
       if (threadSafe == null)
@@ -80,12 +100,22 @@
       else
          tcp = new TimedCachePolicy(defaultLifetime);
 
-      info = "TimedVFSCache{lifetime=" + tcp.getDefaultLifetime() + ", resolution=" + tcp.getResolution() + "}";
+      info = getCacheName() + "{lifetime=" + tcp.getDefaultLifetime() + ", resolution=" + tcp.getResolution() + "}";
 
       return tcp;
    }
 
    /**
+    * Get the cache name.
+    *
+    * @return the cache name
+    */
+   protected String getCacheName()
+   {
+      return "TimedVFSCache";
+   }
+
+   /**
     * Set default lifetime.
     *
     * @param defaultLifetime the default lifetime

Copied: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractExceptionHandler.java (from rev 81470, projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractExceptionHandler.java)
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractExceptionHandler.java	                        (rev 0)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractExceptionHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -0,0 +1,41 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.virtual.plugins.context;
+
+import org.jboss.logging.Logger;
+import org.jboss.virtual.spi.ExceptionHandler;
+
+/**
+ * AbstractExceptionHandler
+ *
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public abstract class AbstractExceptionHandler implements ExceptionHandler
+{
+   /** The log */
+   protected final Logger log = Logger.getLogger(getClass());
+
+   public void handleZipEntriesInitException(Exception e, String name)
+   {
+      throw new RuntimeException(e);
+   }
+}
\ No newline at end of file

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -22,10 +22,10 @@
 package org.jboss.virtual.plugins.context;
 
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.net.MalformedURLException;
 import java.util.List;
 import java.util.Map;
 
@@ -35,6 +35,7 @@
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.VirtualFileFilter;
 import org.jboss.virtual.VisitorAttributes;
+import org.jboss.virtual.spi.ExceptionHandler;
 import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VirtualFileHandler;
 import org.jboss.virtual.spi.VirtualFileHandlerVisitor;
@@ -44,6 +45,7 @@
  * 
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @author Scott.Stark at jboss.org
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
  * @version $Revision: 1.1 $
  */
 public abstract class AbstractVFSContext implements VFSContext
@@ -63,6 +65,9 @@
    /** Root's peer within another context */
    private VirtualFileHandler rootPeer;
 
+   /** The exception handler */
+   private ExceptionHandler exceptionHandler;
+
    /**
     * Create a new AbstractVFSContext.
     * 
@@ -123,6 +128,17 @@
    }
 
    /**
+    * Get peer vfs context.
+    *
+    * @return the peer context
+    */
+   protected VFSContext getPeerContext()
+   {
+      VirtualFileHandler peer = getRootPeer();
+      return peer != null ? peer.getVFSContext() : null;
+   }
+
+   /**
     * Helper method to set options on an URL
     *
     * @param url  url to set options on
@@ -319,7 +335,17 @@
          }
       }
    }
-   
+
+   public ExceptionHandler getExceptionHandler()
+   {
+      return exceptionHandler;
+   }
+
+   public void setExceptionHandler(ExceptionHandler exceptionHandler)
+   {
+      this.exceptionHandler = exceptionHandler;
+   }
+
    @Override
    public String toString()
    {

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -23,10 +23,10 @@
 
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.io.ObjectInputStream.GetField;
 import java.io.ObjectOutputStream;
+import java.io.ObjectOutputStream.PutField;
 import java.io.ObjectStreamField;
-import java.io.ObjectInputStream.GetField;
-import java.io.ObjectOutputStream.PutField;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -258,6 +258,11 @@
       return vfsUrl;
    }
 
+   public URL getRealURL() throws IOException, URISyntaxException
+   {
+      return toURL();
+   }
+
    /**
     * Get VFS url.
     *

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -180,6 +180,11 @@
       return getDelegate().toVfsUrl();
    }
 
+   public URL getRealURL() throws IOException, URISyntaxException
+   {
+      return getDelegate().getRealURL();
+   }
+
    public int hashCode()
    {
       if (delegate != null)

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/VfsArchiveBrowserFactory.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/VfsArchiveBrowserFactory.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/VfsArchiveBrowserFactory.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -25,22 +25,26 @@
 import java.net.URL;
 import java.util.Iterator;
 
-import org.jboss.util.file.ArchiveBrowser;
 import org.jboss.util.file.ArchiveBrowserFactory;
 import org.jboss.virtual.plugins.vfs.VirtualFileURLConnection;
 
 /**
- * This is a bridge to an older, crappier API written by myself.
+ * This is a bridge to an older, crappier API written by Bill.
  *
  * @deprecated
  *
  * @author <a href="bill at jboss.com">Bill Burke</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
  * @version $Revision: 1.1 $
  */
+ at SuppressWarnings("deprecation")
 public class VfsArchiveBrowserFactory implements ArchiveBrowserFactory
 {
+   /** VFS archive browser instance */
+   public static final VfsArchiveBrowserFactory INSTANCE = new VfsArchiveBrowserFactory();
+
    @SuppressWarnings("deprecation")
-   public Iterator create(URL url, ArchiveBrowser.Filter filter)
+   public Iterator create(URL url, org.jboss.util.file.ArchiveBrowser.Filter filter)
    {
       try
       {

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/file/FileHandler.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/file/FileHandler.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/file/FileHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -107,6 +107,11 @@
       return getVfsUrl();
    }
 
+   public URL getRealURL() throws IOException, URISyntaxException
+   {
+      return getURL();
+   }
+
    @Override
    public FileSystemContext getVFSContext()
    {

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -86,11 +86,14 @@
          log.debug("VFS forced case sensitivity is enabled.");
    }
 
+   /** The temp file */
+   private transient File file;
+
    /** The root file */
-   private final VirtualFileHandler root;
+   private VirtualFileHandler root;
    
    /** A reference to the virtual file of the root to stop it getting closed */
-   private final VirtualFile rootFile;
+   private VirtualFile rootFile;
    
    /**
     * Get the file for a url
@@ -193,21 +196,26 @@
    private FileSystemContext(URI rootURI, File file) throws IOException
    {
       super(rootURI);
-      root = createVirtualFileHandler(null, file);
-      if (root == null)
-         throw new java.io.FileNotFoundException((file == null ? "null" : file.getName())
-                 + " doesn't exist. (rootURI: " + rootURI + ", file: " + file + ")");
-
-      rootFile = root.getVirtualFile();
+      this.file = file;
    }
 
    public String getName()
    {
-      return root.getName();
+      return (root != null) ? root.getName() : file.getName();
    }
 
    public VirtualFileHandler getRoot() throws IOException
    {
+      if (root == null)
+      {
+         root = createVirtualFileHandler(null, file);
+         if (root == null)
+            throw new java.io.FileNotFoundException((file == null ? "<null>" : file.getName())
+                    + " doesn't exist. (rootURI: " + getRootURI() + ", file: " + file + ")");
+
+         rootFile = root.getVirtualFile();
+         file = null; // nullify temp file
+      }
       return root;
    }
 
@@ -304,7 +312,7 @@
          throw new IllegalArgumentException("Null uri");
 
       VirtualFileHandler handler = null;
-      if( VFSUtils.isLink(file.getName()) )
+      if(VFSUtils.isLink(file.getName()))
       {
          handler = createLinkHandler(parent, file, null);
       }

Copied: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers (from rev 81470, projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/helpers)

Deleted: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java	2008-11-24 08:58:47 UTC (rev 81470)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -1,65 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual.plugins.context.helpers;
-
-import java.util.Collections;
-import java.util.Set;
-
-import org.jboss.virtual.plugins.context.AbstractExceptionHandler;
-
-/**
- * Match names to ignore the exception.
- * 
- * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
- */
-public class NamesExceptionHandler extends AbstractExceptionHandler
-{
-   private Set<String> names;
-
-   public NamesExceptionHandler(String name)
-   {
-      this(Collections.singleton(name));
-   }
-
-   public NamesExceptionHandler(Set<String> names)
-   {
-      if (names == null)
-         throw new IllegalArgumentException("Null names");
-
-      this.names = names;
-   }
-
-   @Override
-   public void handleZipEntriesInitException(Exception e, String zipName)
-   {
-      for (String name : names)
-      {
-         if (zipName.contains(name))
-         {
-            log.debug("Exception while reading " + zipName, e);
-            return;
-         }
-      }
-
-      super.handleZipEntriesInitException(e, zipName);
-   }
-}

Copied: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java (from rev 81470, projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java)
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java	                        (rev 0)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/helpers/NamesExceptionHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -0,0 +1,65 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.virtual.plugins.context.helpers;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.jboss.virtual.plugins.context.AbstractExceptionHandler;
+
+/**
+ * Match names to ignore the exception.
+ * 
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public class NamesExceptionHandler extends AbstractExceptionHandler
+{
+   private Set<String> names;
+
+   public NamesExceptionHandler(String name)
+   {
+      this(Collections.singleton(name));
+   }
+
+   public NamesExceptionHandler(Set<String> names)
+   {
+      if (names == null)
+         throw new IllegalArgumentException("Null names");
+
+      this.names = names;
+   }
+
+   @Override
+   public void handleZipEntriesInitException(Exception e, String zipName)
+   {
+      for (String name : names)
+      {
+         if (zipName.contains(name))
+         {
+            log.debug("Exception while reading " + zipName, e);
+            return;
+         }
+      }
+
+      super.handleZipEntriesInitException(e, zipName);
+   }
+}

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -56,7 +56,9 @@
 import org.jboss.virtual.plugins.context.DelegatingHandler;
 import org.jboss.virtual.plugins.context.jar.JarUtils;
 import org.jboss.virtual.plugins.copy.AbstractCopyMechanism;
+import org.jboss.virtual.spi.ExceptionHandler;
 import org.jboss.virtual.spi.VirtualFileHandler;
+import org.jboss.virtual.spi.VFSContext;
 
 /**
  * <tt>ZipEntryContext</tt> implements a {@link org.jboss.virtual.spi.VFSContext}
@@ -86,6 +88,7 @@
  * {@link org.jboss.virtual.plugins.context.jar.JarContext}.
  *
  * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @author <a href="ales.justin at jboss.org">Ales Justin</a>
  * @version $Revision: 1.0 $
  */
 public class ZipEntryContext extends AbstractVFSContext
@@ -112,6 +115,9 @@
    /** Entry path representing a context root - archive root is not necessarily a context root */
    private String rootEntryPath = "";
 
+   /** path to zip file - used for lazy ZipWrapper initialization */
+   private String filePath = null;
+
    /** AutoClean signals if zip archive should be deleted after closing the context - true for nested archives */
    private boolean autoClean = false;
 
@@ -121,6 +127,9 @@
    /** Have zip entries been navigated yet */
    private InitializationStatus initStatus = InitializationStatus.NOT_INITIALIZED;
 
+   /** RealURL of this context */
+   private URL realURL;
+
    /**
     * Create a new ZipEntryContext
     *
@@ -213,8 +222,7 @@
             throw new IllegalArgumentException("No ZipWrapper specified and localRootURL is null");
 
          // initialize rootEntryPath and get archive file path
-         String rootPath = initRootAndPath(localRootURL);
-         zipSource = createZipSource(rootPath);
+         filePath = initRootAndPath(localRootURL);
       }
       else
       {
@@ -246,6 +254,56 @@
    }
 
    /**
+    * Get zip source.
+    * Lazy init.
+    *
+    * @return the zip source
+    */
+   protected synchronized ZipWrapper getZipSource()
+   {
+      if (zipSource == null)
+      {
+         try
+         {
+            zipSource = createZipSource(filePath);
+         }
+         catch (IOException e)
+         {
+            throw new RuntimeException("Failed to initialize ZipWrapper: " + filePath, e);
+         }
+      }
+      return zipSource;
+   }
+
+   /**
+    * Returns aggregated options.
+    *
+    * If peer exists, it uses peer context's options as a basis,
+    * and overrides them with this context's options.
+    *
+    * @return map containing aggregated options
+    */
+   public Map<String, String> getAggregatedOptions()
+   {
+      Map<String, String> options = new HashMap<String, String>();
+      VFSContext peerContext = getPeerContext();
+      if (peerContext != null)
+         options.putAll(peerContext.getOptions());
+      options.putAll(super.getOptions()); // put them after peer, possible override
+      return options;
+   }
+
+   public ExceptionHandler getExceptionHandler()
+   {
+      ExceptionHandler eh = super.getExceptionHandler();
+      if (eh != null)
+         return eh;
+
+      VFSContext peerContext = getPeerContext();
+      return peerContext != null ? peerContext.getExceptionHandler() : null;
+   }
+
+   /**
     * Create zip source.
     *
     * @param rootPath the root path
@@ -282,13 +340,18 @@
       if (file == null)
          throw new IOException("VFS file does not exist: " + rootPath);
 
+      RealURLInfo urlInfo = new RealURLInfo(file);
+
       if (relative != null)
       {
-         return findEntry(new FileInputStream(file), relative);
+         ZipWrapper wrapper = findEntry(new FileInputStream(file), relative, urlInfo);
+         realURL = urlInfo.toURL();
+         return wrapper;
       }
       else
       {
-         boolean noReaper = Boolean.valueOf(getOptions().get(VFSUtils.NO_REAPER_QUERY));
+         boolean noReaper = Boolean.valueOf(getAggregatedOptions().get(VFSUtils.NO_REAPER_QUERY));
+         realURL = urlInfo.toURL();
          return new ZipFileWrapper(file, autoClean, noReaper);
       }
    }
@@ -299,10 +362,11 @@
     *
     * @param is the input stream
     * @param relative relative path
+    * @param urlInfo url info
     * @return zip wrapper instance
     * @throws IOException for any error
     */
-   protected ZipWrapper findEntry(InputStream is, String relative) throws IOException
+   protected ZipWrapper findEntry(InputStream is, String relative, RealURLInfo urlInfo) throws IOException
    {
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       VFSUtils.copyStreamAndClose(is, baos);
@@ -355,8 +419,11 @@
          String entryName = entry.getName();
          if (entryName.equals(longestNameMatch))
          {
+            if (urlInfo != null)
+               urlInfo.relativePath = longestNameMatch;
+
             relative = relative.substring(longestNameMatch.length() + 1);
-            return findEntry(zis, relative);
+            return findEntry(zis, relative, null);
          }
       }
       throw new IllegalArgumentException("No such entry: " + is + ", " + relative);
@@ -374,7 +441,7 @@
       if (peer != null)
          return peer.getName();
       else
-         return zipSource.getName();
+         return getZipSource().getName();
    }
 
    /**
@@ -390,6 +457,7 @@
       // this way we ensure that parent entries are processed before child entries
 
       Map<String, ZipEntry> relevant = new HashMap<String, ZipEntry>();
+      ZipWrapper zipSource = getZipSource();
       zipSource.acquire();
       try
       {
@@ -428,7 +496,7 @@
                boolean useCopyMode = forceCopy;
                if (useCopyMode == false)
                {
-                  String flag = getOptions().get(VFSUtils.USE_COPY_QUERY);
+                  String flag = getAggregatedOptions().get(VFSUtils.USE_COPY_QUERY);
                   useCopyMode = Boolean.valueOf(flag);
                }
 
@@ -488,7 +556,11 @@
       }
       catch (Exception ex)
       {
-         throw new RuntimeException("Failed to read zip file: " + zipSource, ex);
+         ExceptionHandler eh = getExceptionHandler();
+         if (eh != null)
+            eh.handleZipEntriesInitException(ex, getZipSource().getName());
+         else
+            throw new RuntimeException("Failed to read zip file: " + getZipSource(), ex);
       }
       finally
       {
@@ -518,6 +590,7 @@
 
       delegatorUrl = setOptionsToURL(delegatorUrl);
       ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, fileUrl, true);
+
       VirtualFileHandler handler = ctx.getRoot();
       delegator.setDelegate(handler);
 
@@ -546,6 +619,7 @@
 
       delegatorUrl = setOptionsToURL(delegatorUrl);
       ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, wrapper, false);
+
       VirtualFileHandler handler = ctx.getRoot();
       delegator.setDelegate(handler);
 
@@ -618,13 +692,13 @@
       {
          ensureEntries();
       }
-      else if (initStatus == InitializationStatus.INITIALIZED && zipSource.hasBeenModified())
+      else if (initStatus == InitializationStatus.INITIALIZED && getZipSource().hasBeenModified())
       {
          EntryInfo rootInfo = entries.get("");
          entries = new ConcurrentHashMap<String, EntryInfo>();
          entries.put("", rootInfo);
 
-         if (zipSource.exists())
+         if (getZipSource().exists())
          {
             try
             {
@@ -704,13 +778,17 @@
       return Collections.emptyList();
    }
 
+   /**
+    * Do delete.
+    *
+    * @param handler the zip entry handler
+    * @param gracePeriod the grace period
+    * @return true if delete succeeded
+    * @throws IOException for any error
+    */
    public boolean delete(ZipEntryHandler handler, int gracePeriod) throws IOException
    {
-      if (getRoot().equals(handler))
-      {
-         return zipSource.delete(gracePeriod);
-      }
-      return false;
+      return getRoot().equals(handler) && getZipSource().delete(gracePeriod);
    }
 
    /**
@@ -731,7 +809,7 @@
          return 0;
 
       if(ei.entry == null) {
-         return zipSource.getLastModified();
+         return getZipSource().getLastModified();
       }
 
       return ei.entry.getTime();
@@ -749,7 +827,7 @@
          throw new IllegalArgumentException("Null handler");
 
       if(getRoot().equals(handler))
-         return zipSource.getSize();
+         return getZipSource().getSize();
 
       checkIfModified();
 
@@ -772,7 +850,7 @@
          throw new IllegalArgumentException("Null handler");
 
       if (getRoot().equals(handler))
-         return zipSource.exists();
+         return getZipSource().exists();
 
       checkIfModified();
       EntryInfo ei = entries.get(handler.getLocalPathName());
@@ -873,7 +951,7 @@
          throw new IllegalArgumentException("Null handler");
 
       if (getRoot().equals(handler))
-         return zipSource.getRootAsStream();
+         return getZipSource().getRootAsStream();
 
       checkIfModified();
 
@@ -896,7 +974,7 @@
       if(ei.entry == null)
          return new ByteArrayInputStream(new byte[0]);
 
-      return zipSource.openStream(ei.entry);
+      return getZipSource().openStream(ei.entry);
    }
 
    /**
@@ -978,6 +1056,19 @@
    }
 
    /**
+    * Get RealURL corresponding to root handler
+    *
+    * @return the real url
+    */
+   public URL getRealURL()
+   {
+      // make sure realURL has been initialized
+      // realURL is initialized when ZipSource is initialized
+      getZipSource();
+      return realURL;
+   }
+
+   /**
     *  Internal data structure holding meta information of a virtual file in this context
     */
    static class EntryInfo
@@ -1078,15 +1169,9 @@
       }
    }
 
-
-
-   //
-   //   Helper methods
-   //
-
-
    /**
-    * Make sure url protocol is <em>vfszip</em>
+    * Make sure url protocol is <em>vfszip</em>.
+    * Also remove any '!' from URL
     *
     * @param rootURL the root url
     * @return fixed url
@@ -1094,14 +1179,22 @@
     */
    private static URL fixUrl(URL rootURL) throws MalformedURLException
    {
+      String urlStr = rootURL.toExternalForm();
+      int pos = urlStr.indexOf("!");
+      if (pos != -1)
+      {
+         String tmp = urlStr.substring(0, pos);
+         if (pos < urlStr.length()-1)
+            tmp += urlStr.substring(pos+1);
+         urlStr = tmp;
+      }
       if ("vfszip".equals(rootURL.getProtocol()) == false)
       {
-         String url = rootURL.toString();
-         int pos = url.indexOf(":/");
+         pos = urlStr.indexOf(":/");
          if (pos != -1)
-            url = url.substring(pos);
+            urlStr = urlStr.substring(pos);
 
-         return new URL("vfszip" + url);
+         return new URL("vfszip" + urlStr);
       }
       return rootURL;
    }
@@ -1206,9 +1299,35 @@
       }
    }
 
-   static enum InitializationStatus {
+   static enum InitializationStatus
+   {
       NOT_INITIALIZED,
       INITIALIZING,
       INITIALIZED
    }
+
+   private static class RealURLInfo
+   {
+      String rootURL;
+      String relativePath;
+
+      RealURLInfo(File file) throws MalformedURLException
+      {
+         String url = file.toURL().toExternalForm();
+         if (url.endsWith("/"))
+            url = url.substring(0, url.length()-1);
+         rootURL = "jar:" + url + "!/";
+      }
+
+      URL toURL() throws MalformedURLException
+      {
+         if (relativePath == null || relativePath.length() == 0)
+            return new URL(rootURL);
+
+         if (relativePath.startsWith("/"))
+            relativePath = relativePath.substring(1);
+
+         return new URL(rootURL + relativePath);
+      }
+   }
 }

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -23,7 +23,6 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -31,7 +30,9 @@
 
 import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler;
+import org.jboss.virtual.plugins.context.file.FileSystemContext;
 import org.jboss.virtual.plugins.context.StructuredVirtualFileHandler;
+import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VirtualFileHandler;
 
 /**
@@ -192,4 +193,55 @@
       init();
       return super.getVfsUrl();
    }
+
+   public URL getRealURL() throws IOException, URISyntaxException
+   {
+      // see how far the parent contexts go
+      // if there is no parent context or it is of type FileSystemContext
+      // ZipEntryContext -> jar!/
+      // ZipEntryContext / ZipEntryContext -> jar!/jar
+      // ZipEntryConteyt / ZipEntryContext / ZipEntryContext ... -> jar!/jar
+      VFSContext ctx = getLocalVFSContext();
+      VirtualFileHandler peer = getLocalVFSContext().getRootPeer();
+
+      if (peer == null)
+      {
+         URL ctxURL = getZipEntryContext().getRealURL();
+         String ctxURLStr = ctxURL.toExternalForm();
+         if (ctxURLStr.endsWith("!/"))
+         {
+            String lpath = getLocalPathName();
+            if (lpath.startsWith("/"))
+               lpath = lpath.substring(1);
+
+            if (lpath.length() == 0)
+               return ctxURL;
+            else
+               return new URL(ctxURLStr + lpath);
+         }
+         return ctxURL;
+      }
+
+      if (peer instanceof AbstractVirtualFileHandler
+         && ((AbstractVirtualFileHandler)peer).getLocalVFSContext() instanceof FileSystemContext)
+      {
+         String lpath = getLocalPathName();
+         if (lpath.startsWith("/") == false)
+            lpath = "/" + lpath;
+         return new URL("jar:file:" + ctx.getRootURI().getPath() + "!" + lpath);
+      }
+
+      if (peer instanceof AbstractVirtualFileHandler)
+      {
+         AbstractVirtualFileHandler aPeer =(AbstractVirtualFileHandler) peer;
+         URL realUrl = aPeer.getLocalVFSContext().getRoot().getRealURL();
+         String urlStr = realUrl.toExternalForm();
+         if (urlStr.endsWith("!/"))
+            return new URL(urlStr + aPeer.getLocalPathName());
+         else
+            return realUrl;
+      }
+       
+      throw new RuntimeException("Operation not supported for handler: " + this);
+   }
 }

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/copy/AbstractCopyMechanism.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/copy/AbstractCopyMechanism.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/copy/AbstractCopyMechanism.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -30,12 +30,15 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.List;
+import java.util.Map;
 
 import org.jboss.logging.Logger;
 import org.jboss.util.id.GUID;
 import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.plugins.context.DelegatingHandler;
 import org.jboss.virtual.plugins.context.file.FileSystemContext;
-import org.jboss.virtual.plugins.context.DelegatingHandler;
+import org.jboss.virtual.spi.ExceptionHandler;
+import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VirtualFileHandler;
 
 /**
@@ -130,6 +133,19 @@
       File copy = copy(guidDir, handler);
       // create new handler
       FileSystemContext fileSystemContext = new FileSystemContext(copy);
+
+      // merge old options
+      VFSContext oldVFSContext = handler.getVFSContext();
+      Map<String, String> newOptions = fileSystemContext.getOptions();
+      Map<String, String> oldOptions = oldVFSContext.getOptions();
+      if (newOptions != null && oldOptions != null && oldOptions.isEmpty() == false)
+         newOptions.putAll(oldOptions);
+
+      // copy exception handler
+      ExceptionHandler eh = oldVFSContext.getExceptionHandler();
+      if (eh != null)
+         fileSystemContext.setExceptionHandler(eh);
+
       VirtualFileHandler newHandler = fileSystemContext.getRoot();
       VirtualFileHandler parent = handler.getParent();
       if (parent != null && replaceOldHandler(parent, handler, newHandler))

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/vfs/helpers/PathTokenizer.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/vfs/helpers/PathTokenizer.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/vfs/helpers/PathTokenizer.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -22,6 +22,7 @@
 package org.jboss.virtual.plugins.vfs.helpers;
 
 import java.io.IOException;
+import java.security.Permission;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -41,6 +42,12 @@
    /** The reverse path const */
    private static final String REVERSE_PATH = "..";
 
+   /** Catch some suspicious tokens */
+   private static boolean errorOnSuspiciousTokens;
+
+   /** Flag permission */
+   private static Permission flagPermission = new RuntimePermission(PathTokenizer.class.getName() + ".setErrorOnSuspiciousTokens");
+
    /**
     * Utility class
     */
@@ -124,7 +131,13 @@
             else if (specialToken == CURRENT_PATH && bufferLength == 0)
                specialToken = REVERSE_PATH;
             else if (specialToken == REVERSE_PATH && bufferLength == 0)
-               throw new IllegalArgumentException("Illegal token (" + specialToken + ch + ") in path: " + path);
+            {
+               if (errorOnSuspiciousTokens)
+                  throw new IllegalArgumentException("Illegal token (" + specialToken + ch + ") in path: " + path);
+
+               buffer.append(specialToken).append(ch);
+               specialToken = null;
+            }
             else
                buffer.append(ch);
          }
@@ -134,7 +147,7 @@
             if (specialToken != null)
             {
                // we don't allow tokens after '..'
-               if (specialToken == REVERSE_PATH)
+               if (errorOnSuspiciousTokens && specialToken == REVERSE_PATH)
                   throw new IllegalArgumentException("Illegal token (" + specialToken + ch + ") in path: " + path);
 
                // after '.' more path is legal == unix hidden directories
@@ -222,4 +235,18 @@
    {
       return REVERSE_PATH == token;
    }
+
+   /**
+    * Set errorOnSuspiciousTokens flag.
+    *
+    * @param errorOnSuspiciousTokens the errorOnSuspiciousTokens flag
+    */
+   public static void setErrorOnSuspiciousTokens(boolean errorOnSuspiciousTokens)
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm != null)
+         sm.checkPermission(flagPermission);
+      
+      PathTokenizer.errorOnSuspiciousTokens = errorOnSuspiciousTokens;
+   }
 }

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/protocol/AbstractVFSHandler.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/protocol/AbstractVFSHandler.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/protocol/AbstractVFSHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -30,7 +30,10 @@
 import java.util.Map;
 import java.util.WeakHashMap;
 
+import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.plugins.vfs.VirtualFileURLConnection;
+import org.jboss.virtual.spi.cache.VFSCache;
+import org.jboss.virtual.spi.cache.VFSCacheFactory;
 
 /**
  * VFS's file URL handler.
@@ -46,7 +49,7 @@
     * Get protocol name length.
     * e.g. vfsfile - 7, vfszip - 6, ...
     *
-    * @return
+    * @return protocol name lenght
     */
    protected int getProtocolNameLength()
    {
@@ -65,6 +68,11 @@
 
    protected URLConnection openConnection(URL url) throws IOException
    {
+      VFSCache cache = VFSCacheFactory.getInstance();
+      VirtualFile vf = cache.getFile(url);
+      if (vf != null)
+         return new VirtualFileURLConnection(url, vf);
+
       String file = URLDecoder.decode(url.toExternalForm(), "UTF-8").substring(getProtocolNameLength() + 1); // strip out vfs protocol + :
       URL vfsurl = null;
       String relative;

Copied: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/ExceptionHandler.java (from rev 81470, projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/ExceptionHandler.java)
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/ExceptionHandler.java	                        (rev 0)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/ExceptionHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -0,0 +1,48 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.virtual.spi;
+
+/**
+ * VFS exception handler.
+ *
+ * Custom exception handling methods shoud be added here
+ * and used at the pointcut where exception is thrown.
+ *
+ * Its abstract super class should implement them all
+ * hence back compatibility is assured by noop.
+ *
+ * Real handlers should just override some methods that
+ * they know how to handle. 
+ *
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public interface ExceptionHandler
+{
+   /**
+    * Handle zip entries initializaion exception.
+    *
+    * @param e the cause exception
+    * @param name the file name
+    * @throws RuntimeException if not handled
+    */
+   void handleZipEntriesInitException(Exception e, String name);
+}

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/VFSContext.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/VFSContext.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/VFSContext.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -113,4 +113,18 @@
     * @throws IllegalArgumentException if the handler or visitor is null
     */
    void visit(VirtualFileHandler handler, VirtualFileHandlerVisitor visitor) throws IOException;
+
+   /**
+    * Get the exception handler.
+    *
+    * @return the exception handler
+    */
+   ExceptionHandler getExceptionHandler();
+
+   /**
+    * Set exception handler.
+    *
+    * @param exceptionHandler the exception handler.
+    */
+   void setExceptionHandler(ExceptionHandler exceptionHandler);
 }

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/VirtualFileHandler.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/VirtualFileHandler.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/VirtualFileHandler.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -72,6 +72,22 @@
     */
    URL toVfsUrl() throws MalformedURLException, URISyntaxException;
    
+   /**
+    * Get a file: or jar:file: URL representing a resource as precisely as possible.
+    * file: urls can represent files in the file system  (i.e.: file:/classes/MyClass.class)
+    * jar:file: urls can represent entries within zip archives in the filesystem
+    * (i.e.: jar:file:/lib/classes.jar!/MyClass.class)
+    * There is no standard URL handler to represent entries within archives that are themselves
+    * entries within archives.
+    * (i.e.: this doesn't work: jar:file:/lib/app.ear!/classes.jar!/MyClass.class
+    * In this case the most precise supported resource locator is: jar:file:/lib/app.ear!/classes.jar
+    * )
+    *
+    * @return the url
+    * @throws URISyntaxException for an error parsing the URI
+    * @throws MalformedURLException for any error constructing the URL
+    */
+   URL getRealURL() throws IOException, URISyntaxException;
 
    /**
     * Get the VF URI (file://root/org/jboss/X.java)

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache/VFSCache.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache/VFSCache.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache/VFSCache.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -37,18 +37,22 @@
 {
    /**
     * Get the file.
+    * Check the cache for cached entry,
+    * return null if no matching entry exists.
     *
     * @param uri the file's uri
-    * @return virtual file instance
+    * @return virtual file instance or null if it doesn't exist in cache
     * @throws IOException for any error
     */
    VirtualFile getFile(URI uri) throws IOException;
 
    /**
     * Get the file.
+    * Check the cache for cached entry,
+    * return null if no matching entry exists.
     *
     * @param url the file's url
-    * @return virtual file instance
+    * @return virtual file instance or null if it doesn't exist in cache
     * @throws IOException for any error
     */
    VirtualFile getFile(URL url) throws IOException;

Modified: projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache/helpers/NoopVFSCache.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache/helpers/NoopVFSCache.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache/helpers/NoopVFSCache.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -21,12 +21,11 @@
 */
 package org.jboss.virtual.spi.cache.helpers;
 
+import java.io.IOException;
 import java.net.URI;
 import java.net.URL;
-import java.io.IOException;
 
 import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VFS;
 import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.cache.VFSCache;
 
@@ -40,12 +39,12 @@
 {
    public VirtualFile getFile(URI uri) throws IOException
    {
-      return VFS.getRoot(uri);
+      return null;
    }
 
    public VirtualFile getFile(URL url) throws IOException
    {
-      return VFS.getRoot(url);
+      return null;
    }
 
    public void putContext(VFSContext context)

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/AbstractVFSContextTest.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/AbstractVFSContextTest.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/AbstractVFSContextTest.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -23,12 +23,14 @@
 
 import java.io.IOException;
 import java.net.URI;
+import java.net.URL;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 import org.jboss.test.virtual.support.MockVirtualFileHandlerVisitor;
 import org.jboss.virtual.VFS;
+import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VirtualFileHandler;
@@ -52,12 +54,85 @@
 
    protected abstract String getSuffix();
 
+   protected abstract String getRealProtocol();
+
+   protected abstract String getRealURLEnd();
+
+   protected abstract String transformExpectedEnd(String expecetedEnd);
+
+   protected abstract boolean isRealURLSupported();
+
    /* TODO URI testing
    public void testRootURI() throws Exception
    {
    }
    */
-   
+
+   public void testRealURL() throws Exception
+   {
+      try
+      {
+         assertRealURL("children", null, null);
+         assertRealURL("children", "child1", null);
+         assertRealURL("complex", null, null);
+         assertRealURL("complex", "subfolder", null);
+         assertRealURL("complex", "subfolder/subchild", null);
+         assertRealURL("complex", "subfolder/subsubfolder", null);
+         assertRealURL("complex", "subfolder/subsubfolder/subsubchild", null);
+         assertRealURL("nested", null, null);
+         assertRealURL("nested", "complex.jar", null);
+         assertRealURL("nested", "complex.jar/subfolder", "complex.jar");
+         assertRealURL("nested", "complex.jar/subfolder/subchild", "complex.jar");
+         assertRealURL("nested", "complex.jar/subfolder/subsubfolder", "complex.jar");
+         assertRealURL("nested", "complex.jar/subfolder/subsubfolder/subsubchild", "complex.jar");
+
+         assertTrue(isRealURLSupported());
+      }
+      catch (Throwable t)
+      {
+         assertFalse(t.getMessage(), isRealURLSupported());
+      }
+   }
+
+   @SuppressWarnings("deprecation")
+   public void assertRealURL(String name, String path, String expectedEnd) throws Exception
+   {
+      VFSContext context = getVFSContext(name);
+      VirtualFile root = context.getRoot().getVirtualFile();
+      VirtualFile file = root;
+      if (path != null && path.length() > 0)
+         file = root.findChild(path);
+
+      URL realURL = VFSUtils.getRealURL(file);
+      String realURLString = realURL.toExternalForm();
+
+      URL rootURL = root.toURL();
+      String rootURLString = rootURL.toExternalForm();
+      int p = rootURLString.indexOf(":/");
+      int l = rootURLString.length() - 1;
+      if (rootURLString.charAt(l - 1) == '!')
+         l--;
+      String middle = rootURLString.substring(p, l);
+      String end;
+      expectedEnd = transformExpectedEnd(expectedEnd);
+      if (expectedEnd == null)
+      {
+         end = (path != null) ? path : "";
+      }
+      else
+      {
+         end = expectedEnd;
+      }
+
+      String expectedRealURL = getRealProtocol() + middle + getRealURLEnd() + end;
+      if (expectedRealURL.endsWith("/") && realURLString.endsWith("/") == false)
+         realURLString += "/";
+      if (expectedRealURL.endsWith("/") == false && realURLString.endsWith("/"))
+         expectedRealURL += "/";
+
+      assertEquals("Different real URL:", expectedRealURL, realURLString);
+   }
+
    public void testGetVFS() throws Exception
    {
       VFSContext context = getVFSContext("simple");

Copied: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/ExceptionHandlerTestCase.java (from rev 81470, projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/ExceptionHandlerTestCase.java)
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/ExceptionHandlerTestCase.java	                        (rev 0)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/ExceptionHandlerTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -0,0 +1,60 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.virtual.test;
+
+import java.net.URL;
+import java.util.List;
+
+import junit.framework.Test;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.plugins.context.helpers.NamesExceptionHandler;
+
+/**
+ * ExceptionHandlerTestCase.
+ *
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public class ExceptionHandlerTestCase extends AbstractVFSTest
+{
+   public static Test suite()
+   {
+      return suite(ExceptionHandlerTestCase.class);
+   }
+
+   public ExceptionHandlerTestCase(String name)
+   {
+      super(name, true);
+   }
+
+   public void testZipEntriesInit() throws Exception
+   {
+      URL url = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(url);
+      vfs.setExceptionHandler(new NamesExceptionHandler("_sqljdbc.jar"));
+      VirtualFile root = vfs.getRoot();
+      VirtualFile zipeinit = root.findChild("zipeinit.jar");
+      VirtualFile child = zipeinit.findChild("sqljdbc.jar");
+      List<VirtualFile> children = child.getChildren();
+      assertTrue(children.isEmpty());
+   }
+}

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSContextUnitTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSContextUnitTestCase.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSContextUnitTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -63,4 +63,24 @@
    {
       return "";
    }
+
+   protected String getRealProtocol()
+   {
+      return "file";
+   }
+
+   protected String getRealURLEnd()
+   {
+      return "/";
+   }
+
+   protected String transformExpectedEnd(String expecetedEnd)
+   {
+      return null;
+   }
+
+   protected boolean isRealURLSupported()
+   {
+      return true;
+   }
 }

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -1608,15 +1608,16 @@
    {
       File tmpRoot = File.createTempFile("vfs", ".root");
       VFS vfs = VFS.getVFS(tmpRoot.toURL());
+      VirtualFile root = vfs.getRoot();
 
       // non-existent directory - exists() not
       tmpRoot.delete();
-      assertFalse(tmpRoot + ".exits() == false", vfs.getRoot().exists());
+      assertFalse(tmpRoot + ".exits() == false", root.exists());
 
       // existing directory - exists(), delete()
       tmpRoot.mkdir();
-      assertTrue(tmpRoot + ".exits()", vfs.getRoot().exists());
-      assertTrue(tmpRoot + ".delete()", vfs.getRoot().delete());
+      assertTrue(tmpRoot + ".exits()", root.exists());
+      assertTrue(tmpRoot + ".delete()", root.delete());
       tmpRoot.mkdir();
 
       // non-empty directory - delete()
@@ -1648,7 +1649,7 @@
       assertNull(tmpRoot + ".getChild('" + tmp.getName() + "') == null", tmpVF);
 
       // directory delete()
-      assertTrue(tmpRoot + ".delete()", vfs.getRoot().delete());
+      assertTrue(tmpRoot + ".delete()", root.delete());
    }
 
    /**

Copied: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/IterableTimedCacheTestCase.java (from rev 81470, projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/IterableTimedCacheTestCase.java)
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/IterableTimedCacheTestCase.java	                        (rev 0)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/IterableTimedCacheTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -0,0 +1,49 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.virtual.test;
+
+import junit.framework.Test;
+import org.jboss.virtual.plugins.cache.IterableTimedVFSCache;
+import org.jboss.virtual.spi.cache.VFSCache;
+
+/**
+ * Iterable timed VFSCache Test.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public class IterableTimedCacheTestCase extends TimedCacheTestCase
+{
+   public IterableTimedCacheTestCase(String name)
+   {
+      super(name);
+   }
+
+   public static Test suite()
+   {
+      return suite(IterableTimedCacheTestCase.class);
+   }
+
+   protected VFSCache createCache()
+   {
+      return new IterableTimedVFSCache(5);
+   }
+}
\ No newline at end of file

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/JARVFSContextUnitTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/JARVFSContextUnitTestCase.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/JARVFSContextUnitTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -94,6 +94,26 @@
       return ".jar";
    }
 
+   protected String getRealProtocol()
+   {
+      return "jar:file";
+   }
+
+   protected String getRealURLEnd()
+   {
+      return "!/";
+   }
+
+   protected String transformExpectedEnd(String expecetedEnd)
+   {
+      return expecetedEnd;
+   }
+
+   protected boolean isRealURLSupported()
+   {
+      return false;
+   }
+
    /**
     * Was having problems with a jar entry as root of VFS.
     *

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/PathTokensTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/PathTokensTestCase.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/PathTokensTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -80,15 +80,23 @@
 
    public void testSpecialTokens() throws Throwable
    {
-      testBrokenPath("/.../");
-      testBrokenPath(".../");
-      testBrokenPath("/...");
-      testBrokenPath("...");
-      testBrokenPath("/..somemorepath/");
-      testBrokenPath("..somemorepath/");
-      testBrokenPath("/..somemorepath");
-      testBrokenPath("..somemorepath");
+      PathTokenizer.setErrorOnSuspiciousTokens(true);
+      try
+      {
+         testBrokenPath("/.../");
+         testBrokenPath(".../");
+         testBrokenPath("/...");
+         testBrokenPath("...");
+         testBrokenPath("/..somemorepath/");
+         testBrokenPath("..somemorepath/");
+         testBrokenPath("/..somemorepath");
+         testBrokenPath("..somemorepath");
       }
+      finally
+      {
+         PathTokenizer.setErrorOnSuspiciousTokens(false);
+      }
+   }
 
    public void testRepeatedSlashes() throws Throwable
    {
@@ -107,12 +115,32 @@
       testValidPath("//context///jar///");
    }
 
-   public void testHiddenUnixPath() throws Throwable
+   public void testSuspiciousTokens() throws Throwable
    {
-      // the trick is the .hudson bit
-      String path = "/home/hudson/.hudson/";
-      List<String> tokens = PathTokenizer.getTokens(path);
-      List<String> expected = Arrays.asList("home", "hudson", ".hudson");
-      assertEquals(expected, tokens);
+      testSuspiciousTokens(false);
+      testSuspiciousTokens(true);      
    }
+
+   public void testSuspiciousTokens(boolean flag) throws Throwable
+   {
+      PathTokenizer.setErrorOnSuspiciousTokens(flag);
+      try
+      {
+         String path = "/.hudson/..hudson/...hudson/./../.../.*foo/foo.bar";
+         List<String> tokens = PathTokenizer.getTokens(path);
+         List<String> expected = Arrays.asList(".hudson", "..hudson", "...hudson", ".", "..", "...", ".*foo", "foo.bar");
+         assertEquals(expected, tokens);
+         if (flag)
+            fail("Should not be here.");
+      }
+      catch (Throwable t)
+      {
+         if (!flag)
+            throw t;
+      }
+      finally
+      {
+         PathTokenizer.setErrorOnSuspiciousTokens(!flag);
+      }
+   }
 }
\ No newline at end of file

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -26,6 +26,7 @@
 
 import org.jboss.virtual.plugins.cache.TimedVFSCache;
 import org.jboss.virtual.spi.cache.VFSCache;
+import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.VFSUtils;
 import junit.framework.Test;
 
@@ -51,6 +52,12 @@
       return new TimedVFSCache(5);
    }
 
+   protected void testCachedContexts(Iterable<VFSContext> iter)
+   {
+      VFSContext context = iter.iterator().next();
+      assertNotNull(context);
+   }
+
    protected Map<Object, Object> getMap()
    {
       Map<Object, Object> map = new HashMap<Object, Object>();

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -89,8 +89,11 @@
       // cache
       suite.addTest(LRUCacheTestCase.suite());
       suite.addTest(TimedCacheTestCase.suite());
+      suite.addTest(IterableTimedCacheTestCase.suite());
       suite.addTest(SoftRefCacheTestCase.suite());
       suite.addTest(WeakRefCacheTestCase.suite());
+      // exception handler
+      suite.addTest(ExceptionHandlerTestCase.suite());
 
       return suite;
    }

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSUnitTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSUnitTestCase.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSUnitTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -35,6 +35,7 @@
 import org.jboss.test.virtual.support.MockVirtualFileFilter;
 import org.jboss.virtual.VFS;
 import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.plugins.vfs.helpers.FilterVirtualFileVisitor;
 
 /**
@@ -55,6 +56,24 @@
       return new TestSuite(VFSUnitTestCase.class);
    }
 
+   public void testVFSOptions() throws Exception
+   {
+      URL url = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(url);
+
+      // currently we don't test any vfs root's behavior
+
+      VFSUtils.enableCopy(vfs);
+      VFSUtils.disableCopy(vfs);
+
+      VFSUtils.enableNoReaper(vfs);
+      VFSUtils.disableNoReaper(vfs);
+
+      VFSUtils.enableCaseSensitive(vfs);
+      VFSUtils.disableCaseSensitive(vfs);
+   }
+
+
    public void testGetVFSURI() throws Exception
    {
       MockVFSContext context = registerSimpleVFSContext();

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSUtilTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -22,19 +22,20 @@
 package org.jboss.test.virtual.test;
 
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.ArrayList;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import org.jboss.virtual.VFS;
+import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VFSUtils;
 
 /**
  * VFSUtilTestCase.
  *
  * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @author anil.saldhana at jboss.com
  */
 public class VFSUtilTestCase extends AbstractMockVFSTest
 {
@@ -58,4 +59,62 @@
       VFSUtils.addManifestLocations(file, paths);
       assertEquals(3, paths.size());
    }
+
+   public void testOptionsPropagation() throws Exception
+   {
+      URL url = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(url);
+      VFSUtils.enableNoReaper(vfs);
+      VirtualFile root = vfs.getRoot();
+      assertOption(root, "nested", VFSUtils.NO_REAPER_QUERY);
+      assertOption(root, "nested/nested.jar", VFSUtils.NO_REAPER_QUERY);
+      assertOption(root, "nested/nested.jar/META-INF", VFSUtils.NO_REAPER_QUERY);
+      assertOption(root, "nested/nested.jar/META-INF/empty.txt", VFSUtils.NO_REAPER_QUERY);
+      assertOption(root, "nested/nested.jar/complex.jar", VFSUtils.NO_REAPER_QUERY);
+      assertOption(root, "nested/nested.jar/complex.jar/subfolder", VFSUtils.NO_REAPER_QUERY);
+      assertOption(root, "nested/nested.jar/complex.jar/subfolder/subchild", VFSUtils.NO_REAPER_QUERY);
+
+      VirtualFile subchild = root.findChild("nested/nested.jar/complex.jar/subfolder/subchild");
+      VFSUtils.disableNoReaper(subchild);
+      assertNull(VFSUtils.getOption(subchild, VFSUtils.NO_REAPER_QUERY));
+   }
+
+   protected void assertOption(VirtualFile root, String path, String optionKey) throws Exception
+   {
+      VirtualFile child = root.findChild(path);
+      String optionValue = VFSUtils.getOption(root, optionKey);
+      assertNotNull(optionValue);
+      assertEquals(optionValue, VFSUtils.getOption(child, optionKey));
+   }
+
+   public void testRealURL() throws Exception
+   {
+	   //Regular jar
+	   URL url = getResource("/vfs/test");
+	   VirtualFile root = VFS.getRoot(url);
+	   VirtualFile jarFile = root.getChild("badmf.jar");
+	      
+	   URL vfsURL = jarFile.toURL(); 
+	   assertTrue(vfsURL.toExternalForm().startsWith("vfszip"));
+	   URL realURL = VFSUtils.getRealURL(jarFile);
+      // TODO - JBVFS-77 --> do proper tests!
+	   assertTrue(realURL.toExternalForm().startsWith("jar:"));
+	   
+	   //Nested file in a jar
+	   url = getResource("/vfs/test/nested");
+	   root = VFS.getRoot(url);
+	   VirtualFile nestedFile = root.getChild("/nested.jar/META-INF/empty.txt");
+	   realURL = VFSUtils.getRealURL(nestedFile);
+      // TODO - JBVFS-77 --> do proper tests!
+	   assertTrue(realURL.toExternalForm().startsWith("jar:"));
+	     
+	   //Regular file
+	   url = getResource("/vfs/context/file/simple");
+	   VirtualFile regularFile = VFS.getRoot(url).getChild("tomodify");
+	   vfsURL = regularFile.toURL();
+	   assertTrue(vfsURL.getProtocol().startsWith("vfsfile"));
+	   realURL = VFSUtils.getRealURL(regularFile);
+      // TODO - JBVFS-77 --> do proper tests!
+	   assertTrue(realURL.toExternalForm().startsWith("file:"));
+   }
 }
\ No newline at end of file

Modified: projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java	2008-11-24 09:35:43 UTC (rev 81471)
+++ projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java	2008-11-24 09:47:04 UTC (rev 81472)
@@ -26,11 +26,14 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.IOException;
 import java.net.URL;
+import java.util.List;
 
 import junit.framework.Test;
 import org.jboss.virtual.VFS;
 import org.jboss.virtual.VFSUtils;
+import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.plugins.context.file.FileSystemContext;
 import org.jboss.virtual.plugins.context.jar.JarUtils;
 import org.jboss.virtual.plugins.context.zip.ZipEntryContext;
@@ -152,6 +155,75 @@
    }
 
    /**
+    * Real URL test
+    *
+    * @throws Exception for any error
+    */
+   public void testCustomRealURL() throws Exception
+   {
+      URL url = getResource("/vfs/context/jar/");
+      FileSystemContext ctx = new FileSystemContext(url);
+
+      // valid archive
+      VirtualFileHandler root = ctx.getRoot();
+      assertEquals("Context Real URL", url.toExternalForm(), root.getRealURL().toExternalForm());
+      String jarName = "archive.jar";
+      VirtualFileHandler archive = root.getChild(jarName);
+      assertEquals("Child Real URL", "jar:" + url.toExternalForm() + jarName + "!/", archive.getRealURL().toExternalForm());
+
+      url = getResource("/vfs/test/");
+      ctx = new FileSystemContext(url);
+      root = ctx.getRoot();
+
+      jarName = "level1.zip";
+      archive = root.getChild(jarName);
+      String nestedName = "level2.zip";
+      VirtualFileHandler nested = archive.getChild(nestedName);
+
+      String jarURL = "jar:" + url.toExternalForm() + jarName + "!/" + nestedName;
+      assertEquals("First level nested Real URL", jarURL, nested.getRealURL().toExternalForm());
+
+      nested = nested.getChild("level3.zip");
+      assertEquals("Second level nested Real URL", jarURL, nested.getRealURL().toExternalForm());
+
+      // nested root test
+      url = getResource("/vfs/test/");
+      ZipEntryContext zctx = new ZipEntryContext(new URL("vfszip:" + url.getPath() + "/level1.zip/level2.zip/level3.zip"));
+
+      VirtualFileHandler handler = zctx.getRoot();
+      assertEquals("Nested root Real URL", jarURL, handler.getRealURL().toExternalForm());
+
+      List<VirtualFileHandler> children = handler.getChildren(false);
+      for (VirtualFileHandler child: children)
+      {
+         assertEquals("Nested root Real URL", jarURL, child.getRealURL().toExternalForm());
+      }
+   }
+
+   /**
+    * Test that options are properly propagated to mounted subcontexts
+    *
+    * @throws IOException
+    */
+   public void testOptionPropagation() throws IOException
+   {
+      // jar:file: url test
+      URL url = getResource("/vfs/test/level1.zip");
+      VFS vfs = VFS.getVFS(new URL("jar:file:" + url.getPath() + "!/"));
+      VFSUtils.enableNoReaper(vfs);
+
+      VirtualFile vf = vfs.getChild("level2.zip/level3.zip");
+      assertEquals("jar:file: option propagation", VFSUtils.getOption(vf, VFSUtils.NO_REAPER_QUERY), "true");
+
+      // vfszip: url test
+      vfs = VFS.getVFS(new URL("vfszip:" + url.getPath()));
+      VFSUtils.enableNoReaper(vfs);
+
+      vf = vfs.getChild("level2.zip/level3.zip");
+      assertEquals("vfszip: option propagation", VFSUtils.getOption(vf, VFSUtils.NO_REAPER_QUERY), "true");
+   }
+
+   /**
     * Handler representing a directory must return a recomposed zip archive
     * that has requested entry as its root.
     *
@@ -174,4 +246,9 @@
    {
       return "vfszip";
    }
+
+   protected boolean isRealURLSupported()
+   {
+      return true;
+   }
 }
\ No newline at end of file

Copied: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested (from rev 81470, projects/vfs/trunk/src/test/resources/vfs/context/file/nested)

Copied: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar (from rev 81470, projects/vfs/trunk/src/test/resources/vfs/context/file/nested/complex.jar)

Copied: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder (from rev 81470, projects/vfs/trunk/src/test/resources/vfs/context/file/nested/complex.jar/subfolder)

Deleted: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild
===================================================================
--- projects/vfs/trunk/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild	2008-11-24 08:58:47 UTC (rev 81470)
+++ projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild	2008-11-24 09:47:04 UTC (rev 81472)
@@ -1 +0,0 @@
-empty
\ No newline at end of file

Copied: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild (from rev 81470, projects/vfs/trunk/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild)
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild	                        (rev 0)
+++ projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subchild	2008-11-24 09:47:04 UTC (rev 81472)
@@ -0,0 +1 @@
+empty
\ No newline at end of file

Copied: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder (from rev 81470, projects/vfs/trunk/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder)

Deleted: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild
===================================================================
--- projects/vfs/trunk/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild	2008-11-24 08:58:47 UTC (rev 81470)
+++ projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild	2008-11-24 09:47:04 UTC (rev 81472)
@@ -1 +0,0 @@
-complex/subsubfolder/subsubchild
\ No newline at end of file

Copied: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild (from rev 81470, projects/vfs/trunk/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild)
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild	                        (rev 0)
+++ projects/vfs/branches/Branch_2_0/src/test/resources/vfs/context/file/nested/complex.jar/subfolder/subsubfolder/subsubchild	2008-11-24 09:47:04 UTC (rev 81472)
@@ -0,0 +1 @@
+complex/subsubfolder/subsubchild
\ No newline at end of file

Copied: projects/vfs/branches/Branch_2_0/src/test/resources/vfs/test/zipeinit.jar (from rev 81470, projects/vfs/trunk/src/test/resources/vfs/test/zipeinit.jar)
===================================================================
(Binary files differ)




More information about the jboss-cvs-commits mailing list