[jboss-cvs] JBossAS SVN: r68554 - in projects/vfs/trunk: src/main/java/org/jboss/virtual and 13 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Dec 25 19:56:59 EST 2007


Author: alesj
Date: 2007-12-25 19:56:58 -0500 (Tue, 25 Dec 2007)
New Revision: 68554

Added:
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/AbstractStructuredJarHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarEntryContents.java
   projects/vfs/trunk/src/test/java/META-INF/
   projects/vfs/trunk/src/test/java/META-INF/services/
   projects/vfs/trunk/src/test/java/META-INF/services/org.jboss.virtual.spi.VFSContextFactory
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/FileOAContextFactory.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/JarOAContextFactory.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/OptionsAwareURI.java
Modified:
   projects/vfs/trunk/pom.xml
   projects/vfs/trunk/src/main/java/org/jboss/virtual/VFS.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/VFSUtils.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractURIHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/VfsArchiveBrowser.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/FileHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/LinkHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/AbstractJarHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarContext.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarEntryHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarUtils.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NestedJarFromStream.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NestedJarHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NoCopyNestedJarHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/SynthenticDirEntryHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/memory/MemoryContextHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledContextFactory.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledDirectory.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledDirectoryHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledFileHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/ByteArrayHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileUrlStreamHandler.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/ExtensibleFilter.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/PathTokenizer.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/SuffixMatchFilter.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/LinkInfo.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/VFSContextFactoryLocator.java
   projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/VirtualFileHandler.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARCacheUnitTestCase.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARVFSContextUnitTestCase.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARVirtualFileHandlerUnitTestCase.java
   projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/URLExistsUnitTestCase.java
Log:
Initial NoCopy fixes.
Simple refactorings, pom update.
Still a TODO on Serialization issues + better NoCopy tests.

Modified: projects/vfs/trunk/pom.xml
===================================================================
--- projects/vfs/trunk/pom.xml	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/pom.xml	2007-12-26 00:56:58 UTC (rev 68554)
@@ -8,7 +8,7 @@
   <groupId>org.jboss</groupId>
   <artifactId>jboss-vfs</artifactId>
   <packaging>jar</packaging>
-  <version>2.0.0.Beta6</version>
+  <version>2.0.0-SNAPSHOT</version>
   <name>JBoss VFS</name>
   <url>http://www.jboss.org</url>
   <description>A VFS library</description>
@@ -27,6 +27,14 @@
     <name>JBoss, A division of Red Hat, Inc</name>
     <url>http://www.jboss.org</url>
   </organization>
+
+  <properties>
+    <version.jboss.common.core>2.2.3.GA</version.jboss.common.core>
+    <version.jboss.logging>2.0.4.GA</version.jboss.logging>
+    <version.jboss.test>1.0.4.GA</version.jboss.test>
+    <version.junit>3.8.1</version.junit>
+  </properties>
+
   <build>
     <sourceDirectory>src/main/java</sourceDirectory>
     <finalName>${artifactId}</finalName>
@@ -81,12 +89,12 @@
     <dependency>
       <groupId>org.jboss</groupId>
       <artifactId>jboss-common-core</artifactId>
-      <version>2.2.1.GA</version>
+      <version>${version.jboss.common.core}</version>
     </dependency>
     <dependency>
       <groupId>jboss</groupId>
       <artifactId>jboss-common-logging-spi</artifactId>
-      <version>2.0.4.GA</version>
+      <version>${version.jboss.logging}</version>
     </dependency>
     <dependency>
       <groupId>org.jboss</groupId>
@@ -97,13 +105,13 @@
           <artifactId>jboss-common-core</artifactId>
         </exclusion>
       </exclusions>
-      <version>1.0.4.GA</version>
+      <version>${version.jboss.test}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>3.8.1</version>
+      <version>${version.junit}</version>
       <scope>test</scope>
     </dependency>
   </dependencies>

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/VFS.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/VFS.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/VFS.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -51,6 +51,9 @@
       init();
    }
 
+   /**
+    * Initialize VFS protocol handlers package property. 
+    */
    public static void init()
    {
       String pkgs = System.getProperty("java.protocol.handler.pkgs");

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/VFSUtils.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/VFSUtils.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/VFSUtils.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -121,9 +121,9 @@
       if (parent == null)
          throw new IllegalStateException(file + " has no parent.");
 
-      URL parentURL = null;
-      URL vfsRootURL = null;
-      int rootPathLength = 0;
+      URL parentURL;
+      URL vfsRootURL;
+      int rootPathLength;
       try
       {
          parentURL = parent.toURL();
@@ -141,7 +141,6 @@
       while (tokenizer.hasMoreTokens())
       {
          String path = tokenizer.nextToken();
-
          try
          {
             URL libURL = new URL(parentURL, path);
@@ -275,7 +274,7 @@
     */
    public static Map<String, String> parseURLQuery(String query)
    {
-	   HashMap<String, String> pairsMap = new HashMap<String, String>();
+	   Map<String, String> pairsMap = new HashMap<String, String>();
       if( query != null )
       {
    	   StringTokenizer tokenizer = new StringTokenizer(query, "=&");
@@ -313,7 +312,7 @@
    public static List<LinkInfo> readLinkInfo(InputStream is, String name, Properties props)
       throws IOException, URISyntaxException
    {
-      ArrayList<LinkInfo> info = new ArrayList<LinkInfo>();
+      List<LinkInfo> info = new ArrayList<LinkInfo>();
       if( name.endsWith(".properties") )
          parseLinkProperties(is, info, props);
       else

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractURIHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractURIHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractURIHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -23,7 +23,6 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.Serializable;
 import java.net.URI;
 
 import org.jboss.virtual.spi.VFSContext;
@@ -36,7 +35,6 @@
  * @version $Revision: 1.1 $
  */
 public abstract class AbstractURIHandler extends AbstractVirtualFileHandler
-   implements Serializable
 {
    private static final long serialVersionUID = 1L;
 

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -25,15 +25,16 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
 import org.jboss.logging.Logger;
 import org.jboss.virtual.VFS;
-import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.VirtualFileFilter;
 import org.jboss.virtual.VisitorAttributes;
+import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VirtualFileHandler;
 import org.jboss.virtual.spi.VirtualFileHandlerVisitor;
@@ -55,6 +56,7 @@
    
    /** The root url */
    private final URI rootURI;
+
    /** Options associated with the root URL */
    private Map<String, String> rootOptions;
 
@@ -72,15 +74,15 @@
       String query = rootURI.getQuery();
       rootOptions = VFSUtils.parseURLQuery(query);
    }
+
    /**
     * Create a new AbstractVFSContext.
     * 
     * @param rootURL the root url
-    * @throws URISyntaxException 
+    * @throws URISyntaxException for illegal URL
     * @throws IllegalArgumentException if rootURI is null
     */
-   protected AbstractVFSContext(URL rootURL)
-      throws URISyntaxException
+   protected AbstractVFSContext(URL rootURL) throws URISyntaxException
    {
       this(rootURL.toURI());
    }
@@ -97,9 +99,14 @@
       return rootURI;
    }
 
+   protected void addOption(String key, String value)
+   {
+      rootOptions.put(key, value);
+   }
+
    public Map<String, String> getOptions()
    {
-      return rootOptions;
+      return Collections.unmodifiableMap(rootOptions);
    }
 
    public List<VirtualFileHandler> getChildren(VirtualFileHandler parent, boolean ignoreErrors) throws IOException

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -46,6 +46,7 @@
 /**
  * AbstractVirtualFileHandler.
  * 
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @author Scott.Stark at jboss.org
  * @version $Revision: 1.1 $
@@ -83,7 +84,7 @@
    private transient String vfsPath;
 
    /** The vfs URL */
-   protected URL vfsUrl;
+   private URL vfsUrl;
 
    /** The reference count */
    private transient AtomicInteger references = new AtomicInteger(0);
@@ -110,6 +111,57 @@
       this.name = VFSUtils.fixName(name);
    }
 
+   /**
+    * Check if parent exists.
+    */
+   protected void checkParentExists()
+   {
+      if (parent == null)
+         throw new IllegalArgumentException("Parent must exist!");
+   }
+
+   /**
+    * Get child url.
+    *
+    * @param childPath the child path
+    * @param isDirectory is directory
+    * @return full child URL
+    * @throws IOException for any io error
+    * @throws URISyntaxException for any uri error
+    */
+   protected URL getChildVfsUrl(String childPath, boolean isDirectory) throws IOException, URISyntaxException
+   {
+      checkParentExists();
+      URL parentVfsUrl = getParent().toVfsUrl();
+      String vfsUrlString = parentVfsUrl.toString();
+      if (vfsUrlString.length() > 0 && vfsUrlString.endsWith("/") == false)
+         vfsUrlString += "/";
+      vfsUrlString += childPath;
+      if (isDirectory)
+         vfsUrlString += "/";
+      return new URL(vfsUrlString);
+   }
+
+   /**
+    * Get child path name.
+    *
+    * @param childPath the child path
+    * @param isDirectory is directory
+    * @return full child URL
+    * @throws IOException for any io error
+    */
+   protected String getChildPathName(String childPath, boolean isDirectory) throws IOException
+   {
+      checkParentExists();
+      String childPathName = getParent().getPathName();
+      if (childPathName.length() > 0 && childPathName.endsWith("/") == false)
+         childPathName += "/";
+      childPathName += childPath;
+      if (isDirectory)
+         childPathName += "/";
+      return childPathName;
+   }
+
    public boolean hasBeenModified() throws IOException
    {
       boolean hasBeenModified = false;
@@ -122,7 +174,6 @@
       return hasBeenModified;
    }
 
-
    public String getName()
    {
       return name;
@@ -149,20 +200,37 @@
       this.vfsPath = path;
    }
 
-
-
    public URL toURL() throws MalformedURLException, URISyntaxException
    {
       return toURI().toURL();
    }
 
-
    public URL toVfsUrl() throws MalformedURLException, URISyntaxException
    {
       return vfsUrl;
    }
 
    /**
+    * Get VFS url.
+    *
+    * @return vfs url
+    */
+   protected URL getVfsUrl()
+   {
+      return vfsUrl;
+   }
+
+   /**
+    * Set the vfs URL.
+    *
+    * @param vfsUrl vfs url
+    */
+   protected void setVfsUrl(URL vfsUrl)
+   {
+      this.vfsUrl = vfsUrl;
+   }
+
+   /**
     * Initialise the path into the path name
     * 
     * @param pathName the path name

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -57,10 +57,11 @@
     * @param name - the name of the delegate in this VFS
     * @param delegate - the handler delegate
     */
-   public DelegatingHandler(VFSContext context, VirtualFileHandler parent, String name,
-         VirtualFileHandler delegate)
+   public DelegatingHandler(VFSContext context, VirtualFileHandler parent, String name, VirtualFileHandler delegate)
    {
       super(context, parent, name);
+      if (delegate == null)
+         throw new IllegalArgumentException("Null delegate");
       this.delegate = delegate;
    }
 

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/VfsArchiveBrowser.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/VfsArchiveBrowser.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/VfsArchiveBrowser.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -43,26 +43,22 @@
  */
 public class VfsArchiveBrowser implements Iterator
 {
-   /** TODO WHAT DOES THIS DO? It is unused */
-   private ArchiveBrowser.Filter filter;
    private VirtualFile vf;
    private Iterator<VirtualFile> it;
 
-
-   public VfsArchiveBrowser(final ArchiveBrowser.Filter filter, VirtualFile vf)
+   public VfsArchiveBrowser(ArchiveBrowser.Filter filter, VirtualFile vf)
    {
-      this.filter = filter;
       this.vf = vf;
-      List<VirtualFile> classes = getResources(new VirtualFileFilter() {
-         public boolean accepts(VirtualFile file)
-         {
-            return filter.accept(file.getName());
-         }
-      });
-
+      List<VirtualFile> classes = getResources(new ArchiveBrowserFilter(filter));
       it = classes.iterator();
    }
 
+   /**
+    * Get resources.
+    *
+    * @param filter the filter
+    * @return resources list
+    */
    public List<VirtualFile> getResources(VirtualFileFilter filter)
    {
       VisitorAttributes va = new VisitorAttributes();
@@ -70,7 +66,6 @@
       SuffixesExcludeFilter noJars = new SuffixesExcludeFilter(JarUtils.getSuffixes());
       va.setRecurseFilter(noJars);
       FilterVirtualFileVisitor visitor = new FilterVirtualFileVisitor(filter, va);
-
       try
       {
          vf.visit(visitor);
@@ -82,7 +77,6 @@
       return visitor.getMatched();
    }
 
-
    public boolean hasNext()
    {
       return it.hasNext();
@@ -104,4 +98,24 @@
    {
       it.remove();
    }
+
+   /**
+    * Archive browser delegate filter.
+    */
+   private class ArchiveBrowserFilter implements VirtualFileFilter
+   {
+      private ArchiveBrowser.Filter filter;
+
+      public ArchiveBrowserFilter(ArchiveBrowser.Filter filter)
+      {
+         if (filter == null)
+            throw new IllegalArgumentException("Null filter");
+         this.filter = filter;
+      }
+
+      public boolean accepts(VirtualFile file)
+      {
+         return filter.accept(file.getName());
+      }
+   }
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/FileHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/FileHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/FileHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -46,13 +46,12 @@
  * @author Scott.Stark at jboss.org
  * @version $Revision: 1.1 $
  */
-public class FileHandler extends AbstractURLHandler
-   implements StructuredVirtualFileHandler
+public class FileHandler extends AbstractURLHandler implements StructuredVirtualFileHandler
 {
    private static final long serialVersionUID = 1;
    /** The file */
    private transient File file;
-   
+   /** The child cache */
    private transient Map<String, VirtualFileHandler> childCache = Collections.synchronizedMap(new HashMap<String, VirtualFileHandler>());
 
    /**
@@ -72,7 +71,7 @@
       this.file = file;
       if (file.exists() == false)
          throw new FileNotFoundException("File does not exist: " + file.getCanonicalPath());
-      this.vfsUrl = new URL("vfs" + url.toString());
+      setVfsUrl(new URL("vfs" + url.toString()));
    }
    /**
     * Create a new FileHandler
@@ -89,14 +88,13 @@
       this(context, parent, file, uri.toURL());
    }
 
-
    public URL toVfsUrl() throws MalformedURLException, URISyntaxException
    {
-      if (vfsUrl == null)
+      if (getVfsUrl() == null)
       {
-         vfsUrl = new URL("vfs" + getURL().toString());
+         setVfsUrl(new URL("vfs" + getURL().toString()));
       }
-      return vfsUrl;
+      return getVfsUrl();
    }
 
    @Override
@@ -219,12 +217,11 @@
       return handler;
    }
 
-   private void readObject(ObjectInputStream in)
-      throws IOException, ClassNotFoundException
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
    {
       in.defaultReadObject();
       // Initialize the transient values
       this.file = new File(getURL().getPath());
+      this.childCache = Collections.synchronizedMap(new HashMap<String, VirtualFileHandler>());
    }
-
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -81,15 +81,18 @@
    {
       if (file == null)
          throw new IllegalArgumentException("Null file");
+
       URI url = file.toURI();
       String path = url.getPath();
       if (file.isDirectory() == false)
+      {
          path = VFSUtils.fixName(path);
-      else
+      }
+      else if (path.endsWith("/") == false)
       {
-         if (path.endsWith("/") == false)
             path = path + '/';
       }
+
       try
       {
          return new URI("file", null, path, null);
@@ -140,13 +143,13 @@
    /**
     * Create a new FileSystemContext.
     * 
-    * @param rootURL the root url
+    * @param rootURI the root uri
     * @param file the file
     * @throws IOException for an error accessing the file system
     */
-   private FileSystemContext(URI rootURL, File file) throws IOException
+   private FileSystemContext(URI rootURI, File file) throws IOException
    {
-      super(rootURL);
+      super(rootURI);
       root = createVirtualFileHandler(null, file);
       rootFile = root.getVirtualFile();
    }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/LinkHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/LinkHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/file/LinkHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -48,8 +48,7 @@
  * @author Scott.Stark at jboss.org
  * @version $Revision: 1.1 $
  */
-public class LinkHandler extends AbstractURLHandler
-   implements StructuredVirtualFileHandler
+public class LinkHandler extends AbstractURLHandler implements StructuredVirtualFileHandler
 {
    private static final long serialVersionUID = 1;
    /** The link information */
@@ -57,20 +56,18 @@
    /** The link targets */
    private HashMap<String, VirtualFileHandler> linkTargets = new HashMap<String, VirtualFileHandler>(3);
 
-   class ParentOfLink extends AbstractURLHandler
-      implements StructuredVirtualFileHandler
+   class ParentOfLink extends AbstractURLHandler implements StructuredVirtualFileHandler
    {
       private static final long serialVersionUID = 1;
 
-      private HashMap<String, VirtualFileHandler> children =
-         new HashMap<String, VirtualFileHandler>(1);
+      private HashMap<String, VirtualFileHandler> children = new HashMap<String, VirtualFileHandler>(1);
 
       public ParentOfLink(VFSContext context, VirtualFileHandler parent, URL url, String name)
       {
          super(context, parent, url, name);
          try
          {
-            this.vfsUrl = new URL("vfs" + url.toString());
+            setVfsUrl(new URL("vfs" + url.toString()));
          }
          catch (MalformedURLException e)
          {
@@ -123,7 +120,7 @@
       // TODO: This URL is not consistent with the getName, but does point to the raw link file
       super(context, parent, uri.toURL(), name);
       this.links = links;
-      this.vfsUrl = new URL("vfs" + uri.toURL().toString());
+      setVfsUrl(new URL("vfs" + uri.toURL().toString()));
       // Create handlers for the links and add
       for(LinkInfo link : links)
       {
@@ -174,7 +171,7 @@
             {
                linkTargets.put(atom, linkHandler);
             }
-            else
+            else if (linkParent instanceof ParentOfLink)
             {
                ParentOfLink prevPOL = (ParentOfLink) linkParent;
                prevPOL.addChild(linkHandler, atom);

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/AbstractJarHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/AbstractJarHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/AbstractJarHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -21,39 +21,31 @@
 */
 package org.jboss.virtual.plugins.context.jar;
 
-import java.io.FileNotFoundException;
+import java.io.File;
 import java.io.IOException;
 import java.io.ObjectInputStream;
-import java.io.File;
 import java.net.JarURLConnection;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.jar.JarEntry;
+import java.util.Stack;
 import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
 
 import org.jboss.virtual.plugins.context.AbstractURLHandler;
-import org.jboss.virtual.plugins.context.StructuredVirtualFileHandler;
-import org.jboss.virtual.plugins.vfs.helpers.PathTokenizer;
 import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VirtualFileHandler;
 
 /**
  * AbstractJarHandler.
  *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @author Scott.Stark at jboss.org
  * @version $Revision: 1.1 $
  */
-public class AbstractJarHandler extends AbstractURLHandler
-        implements StructuredVirtualFileHandler
+public abstract class AbstractJarHandler extends AbstractURLHandler
 {
    /**
     * serialVersionUID
@@ -64,40 +56,28 @@
     * The jar file
     */
    private transient JarFile jar;
-
    /**
-    * The jar entries
+    * The jar entry
     */
-   private transient List<VirtualFileHandler> entries;
-   private transient Map<String, VirtualFileHandler> entryMap;
+   private transient ZipEntry entry;
 
    /**
-    * Get a jar entry name
-    *
-    * @param entry the entry
-    * @return the name
-    * @throws IllegalArgumentException for a null entry
-    */
-   protected static String getEntryName(JarEntry entry)
-   {
-      if (entry == null)
-         throw new IllegalArgumentException("Null entry");
-      return entry.getName();
-   }
-
-   /**
     * Create a new JarHandler.
     *
     * @param context the context
     * @param parent  the parent
     * @param url     the url
+    * @param jar     the jar
+    * @param entry   the entry
     * @param name    the name
     * @throws IOException              for an error accessing the file system
     * @throws IllegalArgumentException for a null context, url or vfsPath
     */
-   protected AbstractJarHandler(VFSContext context, VirtualFileHandler parent, URL url, String name) throws IOException
+   protected AbstractJarHandler(VFSContext context, VirtualFileHandler parent, URL url, JarFile jar, ZipEntry entry, String name) throws IOException
    {
       super(context, parent, url, name);
+      this.jar = jar;
+      this.entry = entry;
    }
 
    /**
@@ -107,178 +87,34 @@
     */
    public JarFile getJar()
    {
+      if (jar == null)
+         throw new IllegalArgumentException("Null jar");
       return jar;
    }
 
    /**
-    * Initialise the jar file
+    * Get the entry.
     *
-    * @param jarFile the jar file
-    * @throws IOException              for any error reading the jar file
-    * @throws IllegalArgumentException for a null jarFile
+    * @return jar entry
     */
-   protected void initJarFile(JarFile jarFile) throws IOException
+   public ZipEntry getEntry()
    {
-      /* This cannot be checked because of serialization
-      if (this.jar != null)
-         throw new IllegalStateException("jarFile has already been set");
-      */
-
-      this.jar = jarFile;
-
-      Enumeration<JarEntry> enumeration = jar.entries();
-      if (enumeration.hasMoreElements() == false)
-      {
-         entries = Collections.emptyList();
-         entryMap = Collections.emptyMap();
-         return;
-      }
-
-      // Go through and create a structured representation of the jar
-      Map<String, VirtualFileHandler> parentMap = new HashMap<String, VirtualFileHandler>();
-      ArrayList<ArrayList<JarEntry>> levelMapList = new ArrayList<ArrayList<JarEntry>>();
-      entries = new ArrayList<VirtualFileHandler>();
-      entryMap = new HashMap<String, VirtualFileHandler>();
-      boolean trace = log.isTraceEnabled();
-      while (enumeration.hasMoreElements())
-      {
-         JarEntry entry = enumeration.nextElement();
-         String[] paths = entry.getName().split("/");
-         int depth = paths.length;
-         if (depth >= levelMapList.size())
-         {
-            for (int n = levelMapList.size(); n <= depth; n++)
-               levelMapList.add(new ArrayList<JarEntry>());
-         }
-         ArrayList<JarEntry> levelMap = levelMapList.get(depth);
-         levelMap.add(entry);
-         if (trace)
-            log.trace("added " + entry.getName() + " at depth " + depth);
-      }
-      // Process each level to build the handlers in parent first order
-      int level = 0;
-      for (ArrayList<JarEntry> levels : levelMapList)
-      {
-         if (trace)
-            log.trace("Level(" + level++ + "): " + levels);
-         for (JarEntry entry : levels)
-         {
-            String name = entry.getName();
-            int slash = entry.isDirectory() ? name.lastIndexOf('/', name.length() - 2) :
-                    name.lastIndexOf('/', name.length() - 1);
-            VirtualFileHandler parent = this;
-            String entryName = name;
-            if (slash >= 0)
-            {
-               // Need to include the slash in the name to match the JarEntry.name
-               String parentName = name.substring(0, slash + 1);
-               parent = parentMap.get(parentName);
-               if (parent == null)
-               {
-                  // Build up the parent(s) 
-                  parent = buildParents(parentName, parentMap, entry);
-               }
-            }
-            // Get the entry name without any directory '/' ending
-            int start = slash + 1;
-            int end = entry.isDirectory() ? name.length() - 1 : name.length();
-            entryName = name.substring(start, end);
-            VirtualFileHandler handler = this.createVirtualFileHandler(parent, entry, entryName);
-            if (entry.isDirectory())
-            {
-               parentMap.put(name, handler);
-               if (trace)
-                  log.trace("Added parent: " + name);
-            }
-            if (parent == this)
-            {
-               // This is an immeadiate child of the jar handler
-               entries.add(handler);
-               entryMap.put(entryName, handler);
-            }
-            else if (parent instanceof JarEntryHandler)
-            {
-               // This is a child of the jar entry handler
-               JarEntryHandler ehandler = (JarEntryHandler) parent;
-               ehandler.addChild(handler);
-            }
-            else if (parent instanceof SynthenticDirEntryHandler)
-            {
-               // This is a child of the jar entry handler
-               SynthenticDirEntryHandler ehandler = (SynthenticDirEntryHandler) parent;
-               ehandler.addChild(handler);
-            }
-         }
-      }
+      checkClosed();
+      if (entry == null)
+         throw new IllegalArgumentException("Null entry");
+      return entry;
    }
 
    /**
-    * Create any missing parents.
-    *
-    * @param parentName full vfs path name of parent
-    * @param parentMap  initJarFile parentMap
-    * @param entry      JarEntry missing a parent
-    * @return the VirtualFileHandler for the parent
-    * @throws IOException
-    */
-   protected VirtualFileHandler buildParents(String parentName,
-                                             Map<String, VirtualFileHandler> parentMap, JarEntry entry)
-           throws IOException
-   {
-      VirtualFileHandler parent = this;
-      String[] paths = PathTokenizer.getTokens(parentName);
-      StringBuilder pathName = new StringBuilder();
-      for (String path : paths)
-      {
-         VirtualFileHandler next = null;
-         pathName.append(path);
-         pathName.append('/');
-         try
-         {
-            next = parent.findChild(path);
-         }
-         catch (IOException e)
-         {
-            // Create a synthetic parent
-            URL url = getURL(parent, path, true);
-            next = new SynthenticDirEntryHandler(getVFSContext(), parent, path,
-                    entry.getTime(), url);
-            parentMap.put(pathName.toString(), next);
-            if (parent == this)
-            {
-               // This is an immeadiate child of the jar handler
-               entries.add(next);
-               entryMap.put(path, next);
-            }
-            else if (parent instanceof JarEntryHandler)
-            {
-               // This is a child of the jar entry handler
-               JarEntryHandler ehandler = (JarEntryHandler) parent;
-               ehandler.addChild(next);
-            }
-            else if (parent instanceof SynthenticDirEntryHandler)
-            {
-               // This is a child of the jar entry handler
-               SynthenticDirEntryHandler ehandler = (SynthenticDirEntryHandler) parent;
-               ehandler.addChild(next);
-            }
-         }
-         parent = next;
-      }
-      return parent;
-   }
-
-   /**
     * Create the URL for the entry represented by path.
     * 
     * @param parent - the parent handler
     * @param path - the simple path to the entry without any trailing '/'
     * @param isDirEntry - whether this is a directory entry
     * @return the jar entry URL
-    * @throws MalformedURLException
+    * @throws MalformedURLException if illegal URL form
     */
-   protected URL getURL(VirtualFileHandler parent, String path, boolean isDirEntry)
-           throws MalformedURLException
+   protected URL getURL(VirtualFileHandler parent, String path, boolean isDirEntry) throws MalformedURLException
    {
       StringBuilder buffer = new StringBuilder();
       try
@@ -305,96 +141,21 @@
       // Jar directory URLs must end in /
       if( isDirEntry && buffer.charAt(buffer.length() - 1) != '/')
          buffer.append('/');
-      URL url = new URL(buffer.toString());
-      return url;
+      return new URL(buffer.toString());
    }
 
-   protected void doClose()
-   {
-      /* TODO Figure out why this breaks things randomly
-      try
-      {
-         if (jar != null)
-            jar.close();
-      }
-      catch (IOException ignored)
-      {
-      }
-      */
-   }
-
    public boolean isLeaf()
    {
       checkClosed();
       return false;
    }
 
-   public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
-   {
-      checkClosed();
-      return entries;
-   }
-
-   public VirtualFileHandler findChild(String path) throws IOException
-   {
-      return structuredFindChild(path);
-   }
-
-   public VirtualFileHandler createChildHandler(String name) throws IOException
-   {
-      VirtualFileHandler child = entryMap.get(name);
-      if (child == null)
-         throw new FileNotFoundException(this + " has no child: " + name);
-      return child;
-   }
-
    /**
-    * Create a new virtual file handler
-    *
-    * @param parent the parent
-    * @param entry  the entry
-    * @param entryName - the entry name without any trailing '/'
-    * @return the handler
-    * @throws IOException              for any error accessing the file system
-    * @throws IllegalArgumentException for a null parent or entry
-    */
-   protected VirtualFileHandler createVirtualFileHandler(VirtualFileHandler parent,
-         JarEntry entry, String entryName)
-           throws IOException
-   {
-      if (parent == null)
-         throw new IllegalArgumentException("Null parent");
-      if (entry == null)
-         throw new IllegalArgumentException("Null entry");
-
-      URL url = getURL(parent, entryName, entry.isDirectory());
-      VFSContext context = parent.getVFSContext();
-
-      VirtualFileHandler vfh;
-      if (JarUtils.isArchive(entry.getName()))
-      {
-         String flag = context.getOptions().get("useNoCopyJarHandler");
-         boolean useNoCopyJarHandler = Boolean.valueOf(flag);
-
-         if (useNoCopyJarHandler)
-            vfh = new NoCopyNestedJarHandler(context, parent, jar, entry, url);
-         else
-            vfh = NestedJarHandler.create(context, parent, jar, entry, url, entryName);
-      }
-      else
-      {
-         vfh = new JarEntryHandler(context, parent, jar, entry, entryName, url);
-      }
-
-      return vfh;
-   }
-
-   /**
     * Convert a URL into a JarFIle
     *
     * @param url the url to convert
     * @return the jar file
-    * @throws IOException
+    * @throws IOException for any IO error
     */
    public static JarFile fromURL(URL url) throws IOException
    {
@@ -423,23 +184,20 @@
          throw e;
 
       }
-
    }
 
-
    /**
     * Restore the jar file from the jar URL
     *
-    * @param in
-    * @throws IOException
-    * @throws ClassNotFoundException
+    * @param in object input string
+    * @throws IOException for any IO error
+    * @throws ClassNotFoundException if any error reading object 
     */
-   private void readObject(ObjectInputStream in)
-           throws IOException, ClassNotFoundException
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
    {
       in.defaultReadObject();
       // Initialize the transient values
-      URL jarURL = super.getURL();
+      URL jarURL = getURL();
       String jarAsString = jarURL.toString();
       if (jarAsString.startsWith("file:"))
       {
@@ -459,6 +217,32 @@
             throw new IOException("Cannot restore from non-JarURLConnection, url: " + jarURL);
          }
       }
+      handleJarFile();
    }
 
+   /**
+    * Handle jar file after read.
+    * Find the real jar file, if nested.
+    *
+    * @throws IOException for any error
+    */
+   protected void handleJarFile() throws IOException
+   {
+      Stack<AbstractJarHandler> handlers = new Stack<AbstractJarHandler>();
+      AbstractJarHandler current = this;
+      while(current.getParent() instanceof AbstractJarHandler)
+      {
+         handlers.push(current);
+         current = (AbstractJarHandler)current.getParent();
+      }
+      while(handlers.isEmpty() == false)
+      {
+         if (entry != null)
+         {
+            // TODO - change jar
+         }
+         current = handlers.pop();
+         entry = jar.getEntry(current.getName());
+      }
+   }
 }

Added: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/AbstractStructuredJarHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/AbstractStructuredJarHandler.java	                        (rev 0)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/AbstractStructuredJarHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -0,0 +1,303 @@
+/*
+* 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.jar;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.jboss.virtual.plugins.context.StructuredVirtualFileHandler;
+import org.jboss.virtual.plugins.vfs.helpers.PathTokenizer;
+import org.jboss.virtual.spi.VFSContext;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
+/**
+ * AbstractStructuredJarHandler.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public class AbstractStructuredJarHandler extends AbstractJarHandler implements StructuredVirtualFileHandler
+{
+   /**
+    * serialVersionUID
+    */
+   private static final long serialVersionUID = 1;
+
+   /**
+    * The jar entries
+    */
+   private transient List<VirtualFileHandler> entries;
+   private transient Map<String, VirtualFileHandler> entryMap;
+
+   /**
+    * Create a new JarHandler.
+    *
+    * @param context the context
+    * @param parent  the parent
+    * @param url     the url
+    * @param jar     the jar
+    * @param entry   the entry
+    * @param name    the name
+    * @throws java.io.IOException              for an error accessing the file system
+    * @throws IllegalArgumentException for a null context, url or vfsPath
+    */
+   protected AbstractStructuredJarHandler(VFSContext context, VirtualFileHandler parent, URL url, JarFile jar, JarEntry entry, String name) throws IOException
+   {
+      super(context, parent, url, jar, entry, name);
+   }
+
+   /**
+    * Initialise the jar file
+    *
+    * @throws java.io.IOException for any error reading the jar file
+    * @throws IllegalArgumentException for a null jarFile
+    */
+   protected void initJarFile() throws IOException
+   {
+      /* This cannot be checked because of serialization
+      if (this.jar != null)
+         throw new IllegalStateException("jarFile has already been set");
+      */
+
+      Enumeration<JarEntry> enumeration = getJar().entries();
+      if (enumeration.hasMoreElements() == false)
+      {
+         entries = Collections.emptyList();
+         entryMap = Collections.emptyMap();
+         return;
+      }
+
+      // Go through and create a structured representation of the jar
+      Map<String, VirtualFileHandler> parentMap = new HashMap<String, VirtualFileHandler>();
+      ArrayList<ArrayList<JarEntry>> levelMapList = new ArrayList<ArrayList<JarEntry>>();
+      entries = new ArrayList<VirtualFileHandler>();
+      entryMap = new HashMap<String, VirtualFileHandler>();
+      boolean trace = log.isTraceEnabled();
+      while (enumeration.hasMoreElements())
+      {
+         JarEntry entry = enumeration.nextElement();
+         String[] paths = entry.getName().split("/");
+         int depth = paths.length;
+         if (depth >= levelMapList.size())
+         {
+            for (int n = levelMapList.size(); n <= depth; n++)
+               levelMapList.add(new ArrayList<JarEntry>());
+         }
+         ArrayList<JarEntry> levelMap = levelMapList.get(depth);
+         levelMap.add(entry);
+         if (trace)
+            log.trace("added " + entry.getName() + " at depth " + depth);
+      }
+      // Process each level to build the handlers in parent first order
+      int level = 0;
+      for (ArrayList<JarEntry> levels : levelMapList)
+      {
+         if (trace)
+            log.trace("Level(" + level++ + "): " + levels);
+         for (JarEntry entry : levels)
+         {
+            String name = entry.getName();
+            int slash = entry.isDirectory() ? name.lastIndexOf('/', name.length() - 2) :
+                    name.lastIndexOf('/', name.length() - 1);
+            VirtualFileHandler parent = this;
+            if (slash >= 0)
+            {
+               // Need to include the slash in the name to match the JarEntry.name
+               String parentName = name.substring(0, slash + 1);
+               parent = parentMap.get(parentName);
+               if (parent == null)
+               {
+                  // Build up the parent(s)
+                  parent = buildParents(parentName, parentMap, entry);
+               }
+            }
+            // Get the entry name without any directory '/' ending
+            int start = slash + 1;
+            int end = entry.isDirectory() ? name.length() - 1 : name.length();
+            String entryName = name.substring(start, end);
+            VirtualFileHandler handler = createVirtualFileHandler(parent, entry, entryName);
+            if (entry.isDirectory())
+            {
+               parentMap.put(name, handler);
+               if (trace)
+                  log.trace("Added parent: " + name);
+            }
+            if (parent == this)
+            {
+               // This is an immeadiate child of the jar handler
+               entries.add(handler);
+               entryMap.put(entryName, handler);
+            }
+            else if (parent instanceof JarEntryHandler)
+            {
+               // This is a child of the jar entry handler
+               JarEntryHandler ehandler = (JarEntryHandler) parent;
+               ehandler.addChild(handler);
+            }
+            else if (parent instanceof SynthenticDirEntryHandler)
+            {
+               // This is a child of the jar entry handler
+               SynthenticDirEntryHandler ehandler = (SynthenticDirEntryHandler) parent;
+               ehandler.addChild(handler);
+            }
+         }
+      }
+   }
+
+   /**
+    * Create any missing parents.
+    *
+    * @param parentName full vfs path name of parent
+    * @param parentMap  initJarFile parentMap
+    * @param entry      JarEntry missing a parent
+    * @return the VirtualFileHandler for the parent
+    * @throws java.io.IOException for any IO error
+    */
+   protected VirtualFileHandler buildParents(String parentName, Map<String, VirtualFileHandler> parentMap, JarEntry entry)
+           throws IOException
+   {
+      VirtualFileHandler parent = this;
+      String[] paths = PathTokenizer.getTokens(parentName);
+      StringBuilder pathName = new StringBuilder();
+      for (String path : paths)
+      {
+         VirtualFileHandler next;
+         pathName.append(path);
+         pathName.append('/');
+         try
+         {
+            next = parent.findChild(path);
+         }
+         catch (IOException e)
+         {
+            // Create a synthetic parent
+            URL url = getURL(parent, path, true);
+            next = new SynthenticDirEntryHandler(getVFSContext(), parent, path, entry.getTime(), url);
+            if (parent == this)
+            {
+               // This is an immeadiate child of the jar handler
+               entries.add(next);
+               entryMap.put(path, next);
+            }
+            else if (parent instanceof JarEntryHandler)
+            {
+               // This is a child of the jar entry handler
+               JarEntryHandler ehandler = (JarEntryHandler) parent;
+               ehandler.addChild(next);
+            }
+            else if (parent instanceof SynthenticDirEntryHandler)
+            {
+               // This is a child of the jar entry handler
+               SynthenticDirEntryHandler ehandler = (SynthenticDirEntryHandler) parent;
+               ehandler.addChild(next);
+            }
+         }
+         parentMap.put(pathName.toString(), next);
+         parent = next;
+      }
+      return parent;
+   }
+
+   public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
+   {
+      checkClosed();
+      if (entries == null)
+         return Collections.emptyList();
+      else
+         return Collections.unmodifiableList(entries);
+   }
+
+   public VirtualFileHandler findChild(String path) throws IOException
+   {
+      return structuredFindChild(path);
+   }
+
+   public VirtualFileHandler createChildHandler(String name) throws IOException
+   {
+      VirtualFileHandler child = entryMap.get(name);
+      if (child == null)
+         throw new FileNotFoundException(this + " has no child: " + name);
+      return child;
+   }
+
+   /**
+    * Create a new virtual file handler
+    *
+    * @param parent the parent
+    * @param entry  the entry
+    * @param entryName - the entry name without any trailing '/'
+    * @return the handler
+    * @throws java.io.IOException              for any error accessing the file system
+    * @throws IllegalArgumentException for a null parent or entry
+    */
+   protected VirtualFileHandler createVirtualFileHandler(VirtualFileHandler parent, JarEntry entry, String entryName)
+           throws IOException
+   {
+      if (parent == null)
+         throw new IllegalArgumentException("Null parent");
+      if (entry == null)
+         throw new IllegalArgumentException("Null entry");
+
+      URL url = getURL(parent, entryName, entry.isDirectory());
+      VFSContext context = parent.getVFSContext();
+
+      VirtualFileHandler vfh;
+      if (JarUtils.isArchive(entry.getName()))
+      {
+         String flag = context.getOptions().get("useNoCopyJarHandler");
+         boolean useNoCopyJarHandler = Boolean.valueOf(flag);
+
+         if (useNoCopyJarHandler)
+            vfh = new NoCopyNestedJarHandler(context, parent, getJar(), entry, url, entryName);
+         else
+            vfh = NestedJarHandler.create(context, parent, getJar(), entry, url, entryName);
+      }
+      else
+      {
+         vfh = new JarEntryHandler(context, parent, getJar(), entry, entryName, url);
+      }
+
+      return vfh;
+   }
+
+   /**
+    * Restore the jar file
+    *
+    * @param in the input stream
+    * @throws IOException for any error reading the jar file
+    * @throws ClassNotFoundException for any jar class finding errors
+    */
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+   {
+      // Initial the parent jar entries
+      initJarFile();
+   }
+}

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarContext.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarContext.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarContext.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -102,7 +102,8 @@
       {
          entryName = null;
       }
-      if (entryName.trim().equals("")) return null;
+      if (entryName == null || "".equals(entryName.trim()))
+         return null;
       
       return entryName;
    }
@@ -126,5 +127,4 @@
          rootFile.close();
       super.finalize();
    }
-
 }

Added: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarEntryContents.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarEntryContents.java	                        (rev 0)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarEntryContents.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -0,0 +1,215 @@
+/*
+* 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.jar;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.jboss.virtual.spi.VFSContext;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
+/**
+ * A nested jar contents implementation used to represent a jar within a jar.
+ *
+ * @author Ales.Justin at jboss.org
+ * @author Scott.Stark at jboss.org
+ */
+public class JarEntryContents extends AbstractJarHandler
+{
+   /**
+    * serialVersionUID
+    */
+   private static final long serialVersionUID = 1L;
+
+   private URL entryURL;
+   private byte[] contents;
+   private boolean isJar;
+   private NestedJarFromStream njar;
+   private InputStream openStream;
+
+   JarEntryContents(VFSContext context, VirtualFileHandler parent, ZipEntry entry, URL jarURL, URL entryURL, InputStream zis)
+           throws IOException
+   {
+      super(context, parent, jarURL, null, entry, entry.getName());
+      String entryName = entry.getName();
+      try
+      {
+         setPathName(getChildPathName(entryName, false));
+         setVfsUrl(getChildVfsUrl(entryName, false));
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+      this.entryURL = entryURL;
+      this.isJar = JarUtils.isArchive(entryName);
+      int size = (int) entry.getSize();
+      if (size <= 0)
+         return;
+
+      ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
+      byte[] tmp = new byte[1024];
+      while (zis.available() > 0)
+      {
+         int length = zis.read(tmp);
+         if (length > 0)
+            baos.write(tmp, 0, length);
+      }
+      contents = baos.toByteArray();
+   }
+
+   /**
+    * TODO: removing the entry/jar that resulted in this needs
+    * to be detected.
+    */
+   public boolean exists() throws IOException
+   {
+      return true;
+   }
+
+   public boolean isHidden() throws IOException
+   {
+      return false;
+   }
+
+   byte[] getContents()
+   {
+      return contents;
+   }
+
+   public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
+   {
+      List<VirtualFileHandler> children = null;
+      if (isJar)
+      {
+         initNestedJar();
+         children = njar.getChildren(ignoreErrors);
+      }
+      if (children == null)
+         return Collections.emptyList();
+      else
+         return Collections.unmodifiableList(children);
+   }
+
+   public VirtualFileHandler findChild(String path) throws IOException
+   {
+      if (isJar)
+      {
+         initNestedJar();
+         return njar.findChild(path);
+      }
+      else
+      {
+         throw new FileNotFoundException("JarEntryContents(" + getName() + ") has no children");
+      }
+   }
+
+   // Convience attribute accessors
+   public long getLastModified()
+   {
+      return getEntry().getTime();
+   }
+
+   public long getSize()
+   {
+      return getEntry().getSize();
+   }
+
+   public boolean isLeaf()
+   {
+      return isJar == false && getEntry().isDirectory() == false;
+   }
+
+   // Stream accessor
+   public synchronized InputStream openStream() throws IOException
+   {
+      initNestedJar();
+      if (njar != null)
+         openStream = njar.openStream();
+      else
+         openStream = new ByteArrayInputStream(contents);
+      return openStream;
+   }
+
+   public synchronized void close()
+   {
+      if (openStream != null)
+      {
+         try
+         {
+            openStream.close();
+         }
+         catch (IOException e)
+         {
+            log.error("close error", e);
+         }
+         openStream = null;
+      }
+   }
+
+   public URI toURI() throws URISyntaxException
+   {
+      return entryURL.toURI();
+   }
+
+   public String toString()
+   {
+      StringBuffer tmp = new StringBuffer(super.toString());
+      tmp.append('[');
+      tmp.append("name=");
+      tmp.append(getName());
+      tmp.append(",size=");
+      tmp.append(getSize());
+      tmp.append(",time=");
+      tmp.append(getLastModified());
+      tmp.append(",URI=");
+      try
+      {
+         tmp.append(toURI());
+      }
+      catch (URISyntaxException ignored)
+      {
+      }
+      tmp.append(']');
+      return tmp.toString();
+   }
+
+   protected synchronized void initNestedJar() throws IOException
+   {
+      if (isJar && njar == null)
+      {
+         ByteArrayInputStream bais = new ByteArrayInputStream(contents);
+         ZipInputStream zis = new ZipInputStream(bais);
+         njar = new NestedJarFromStream(getVFSContext(), this, zis, entryURL, null, getEntry());
+      }
+   }
+}

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarEntryHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarEntryHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarEntryHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -34,72 +34,54 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
-import org.jboss.virtual.plugins.context.AbstractURLHandler;
 import org.jboss.virtual.plugins.context.StructuredVirtualFileHandler;
 import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VirtualFileHandler;
 
 /**
  * JarEntryHandler.
- * 
+ *
+ * @author <a href="ales.justin at jboss.org">Ales Justin</a>
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @author Scott.Stark at jboss.org
  * @version $Revision: 1.1 $
  */
-public class JarEntryHandler extends AbstractURLHandler
-   implements StructuredVirtualFileHandler
+public class JarEntryHandler extends AbstractJarHandler implements StructuredVirtualFileHandler
 {
-   /** serialVersionUID */
+   /**
+    * serialVersionUID
+    */
    private static final long serialVersionUID = 1L;
 
-   /** The jar file */
-   private transient final JarFile jar;
-   
-   /** The jar entry */
-   private transient final JarEntry entry;
-   private transient List<VirtualFileHandler> entryChildren;
+   private List<VirtualFileHandler> entryChildren;
    private transient Map<String, VirtualFileHandler> entryMap;
-   
+
    /**
     * Create a new JarHandler.
-    * 
-    * @param context the context
-    * @param parent the parent
-    * @param jar the jar file
-    * @param entry the entry
+    *
+    * @param context   the context
+    * @param parent    the parent
+    * @param jar       the jar file
+    * @param entry     the entry
     * @param entryName the entry name
-    * @param url the url
-    * @throws IOException for an error accessing the file system
+    * @param url       the url
+    * @throws IOException              for an error accessing the file system
     * @throws IllegalArgumentException for a null context, url, jar or entry
     */
-   public JarEntryHandler(VFSContext context, VirtualFileHandler parent, JarFile jar,
-      JarEntry entry, String entryName, URL url)
-      throws IOException
+   public JarEntryHandler(VFSContext context, VirtualFileHandler parent, JarFile jar, JarEntry entry, String entryName, URL url)
+         throws IOException
    {
-      super(context, parent, url, entryName);
+      super(context, parent, url, jar, entry, entryName);
       try
       {
-         URL parentVfsUrl = parent.toVfsUrl();
-         String vfsParentUrl = parentVfsUrl.toString();
-         String vfsUrlString = null;
-         if (vfsParentUrl.endsWith("/")) vfsUrlString = vfsParentUrl + entryName;
-         else vfsUrlString = vfsParentUrl + "/" + entryName;
-         if (entry.isDirectory()) vfsUrlString += "/";
-         vfsUrl = new URL(vfsUrlString);
+         setVfsUrl(getChildVfsUrl(entryName, entry.isDirectory()));
       }
       catch (URISyntaxException e)
       {
          throw new RuntimeException(e);
       }
-
-      if (jar == null)
-         throw new IllegalArgumentException("Null jar");
-      
-      this.jar = jar;
-      this.entry = entry;
    }
 
-
    @Override
    protected void initCacheLastModified()
    {
@@ -114,26 +96,16 @@
 
    /**
     * Add a child to an entry
-    * @param child
+    *
+    * @param child the child
     */
    public void addChild(VirtualFileHandler child)
    {
-      if( entryChildren == null )
+      if (entryChildren == null)
          entryChildren = new ArrayList<VirtualFileHandler>();
       entryChildren.add(child);
    }
 
-   /**
-    * Get the entry
-    * 
-    * @return the file
-    */
-   protected JarEntry getEntry()
-   {
-      checkClosed();
-      return entry;
-   }
-   
    @Override
    public long getLastModified()
    {
@@ -160,10 +132,9 @@
    public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
    {
       checkClosed();
-      List<VirtualFileHandler> children = entryChildren;
-      if( entryChildren == null )
-         children = Collections.emptyList();
-      return children;
+      if (entryChildren == null)
+         return Collections.emptyList();
+      return Collections.unmodifiableList(entryChildren);
    }
 
    public VirtualFileHandler findChild(String path) throws IOException
@@ -174,28 +145,25 @@
    @Override
    public InputStream openStream() throws IOException
    {
-      return jar.getInputStream(getEntry());
+      return getJar().getInputStream(getEntry());
    }
 
-
-
    /**
     * TODO: synchronization on lazy entryMap creation
     */
    public VirtualFileHandler createChildHandler(String name) throws IOException
    {
-      if( entryChildren == null )
-         throw new FileNotFoundException(this+" has no children");
-      if( entryMap == null )
+      if (entryChildren == null)
+         throw new FileNotFoundException(this + " has no children");
+      if (entryMap == null)
       {
          entryMap = new HashMap<String, VirtualFileHandler>();
-         for(VirtualFileHandler child : entryChildren)
+         for (VirtualFileHandler child : entryChildren)
             entryMap.put(child.getName(), child);
       }
       VirtualFileHandler child = entryMap.get(name);
-      if( child == null )
-         throw new FileNotFoundException(this+" has no child: "+name);
+      if (child == null)
+         throw new FileNotFoundException(this + " has no child: " + name);
       return child;
    }
-
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -37,7 +37,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class JarHandler extends AbstractJarHandler
+public class JarHandler extends AbstractStructuredJarHandler
 {
    /** serialVersionUID */
    private static final long serialVersionUID = 1L;
@@ -54,13 +54,12 @@
     */
    public JarHandler(VFSContext context, VirtualFileHandler parent, URL url, String name) throws IOException
    {
-      super(context, parent, url, name);
-      this.vfsUrl = new URL("vfs" + url.toString());
+      super(context, parent, url, ((JarURLConnection) url.openConnection()).getJarFile(), null, name);
+      setVfsUrl(new URL("vfs" + url.toString()));
 
       try
       {
-         JarURLConnection connection =  (JarURLConnection) url.openConnection();
-         initJarFile(connection.getJarFile());
+         initJarFile();
       }
       catch (IOException original)
       {
@@ -73,12 +72,12 @@
 
    public JarHandler(VFSContext context, VirtualFileHandler parent, File file, URL url, String name) throws IOException
    {
-      super(context, parent, url, name);
-      this.vfsUrl = new URL("vfs" + url.toString());
+      super(context, parent, url, new JarFile(file), null, name);
+      setVfsUrl(new URL("vfs" + url.toString()));
 
       try
       {
-         initJarFile(new JarFile(file));
+         initJarFile();
       }
       catch (IOException original)
       {
@@ -88,20 +87,4 @@
          throw e;
       }
    }
-
-   /**
-    * Restore the jar file from the parent jar and entry name
-    *
-    * @param in
-    * @throws IOException
-    * @throws ClassNotFoundException
-    */
-   private void readObject(ObjectInputStream in)
-      throws IOException, ClassNotFoundException
-   {
-      JarFile parentJar = super.getJar();
-      // Initial the parent jar entries
-      initJarFile(parentJar);
-   }
-
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarUtils.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarUtils.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/JarUtils.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -128,12 +128,13 @@
    {
       if (name == null)
          throw new IllegalArgumentException("Null name");
-      
-      int index = name.lastIndexOf('.');
-      if (index == -1)
-         return false;
-      String suffix = name.substring(index);
-      return jarSuffixes.contains(suffix);
+
+      for(String suffix : jarSuffixes)
+      {
+         if (name.endsWith(suffix))
+            return true;
+      }
+      return false;
    }
    
    /**

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NestedJarFromStream.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NestedJarFromStream.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NestedJarFromStream.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -3,34 +3,33 @@
  */
 package org.jboss.virtual.plugins.context.jar;
 
-import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler;
-import org.jboss.virtual.spi.VFSContext;
-import org.jboss.virtual.spi.VirtualFileHandler;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.ObjectOutputStream;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.ArrayList;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
+import org.jboss.virtual.spi.VFSContext;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
 /**
  * A nested jar implementation used to represent a jar within a jar.
  *
  * @author Scott.Stark at jboss.org
  * @version $Revision: 44334 $
  */
-public class NestedJarFromStream
-        extends AbstractVirtualFileHandler
+public class NestedJarFromStream extends AbstractJarHandler
 {
    /**
     * serialVersionUID
@@ -38,14 +37,12 @@
    private static final long serialVersionUID = 1L;
 
    private ZipInputStream zis;
-   private HashMap<String, JarEntryContents> entries = new HashMap<String, JarEntryContents>();
+   private Map<String, JarEntryContents> entries = new HashMap<String, JarEntryContents>();
    private URL jarURL;
    private URL entryURL;
-   private String vfsPath;
-   private String name;
    private long lastModified;
    private long size;
-   private boolean inited;
+   private AtomicBoolean inited = new AtomicBoolean(false);
 
    /**
     * Create a nested jar from the parent zip inputstream/zip entry.
@@ -54,24 +51,21 @@
     * @param parent  - the jar handler for this nested jar
     * @param zis     - the jar zip input stream
     * @param jarURL  - the URL to use as the jar URL
+    * @param jar     - the parent jar file for the nested jar
     * @param entry   - the parent jar ZipEntry for the nested jar
+    * @throws IOException for any error
     */
-   public NestedJarFromStream(VFSContext context, VirtualFileHandler parent, ZipInputStream zis, URL jarURL, ZipEntry entry)
+   public NestedJarFromStream(VFSContext context, VirtualFileHandler parent, ZipInputStream zis, URL jarURL, JarFile jar, ZipEntry entry) throws IOException
    {
-      super(context, parent, entry.getName());
+      super(context, parent, jarURL, jar, entry, entry.getName());
       this.jarURL = jarURL;
-      this.name = entry.getName();
       this.lastModified = entry.getTime();
       this.size = entry.getSize();
       this.zis = zis;
       try
       {
-         if (parent != null)
-         {
-            String vfsParentUrl = parent.toVfsUrl().toString();
-            if (vfsParentUrl.endsWith("/")) vfsUrl = new URL(vfsParentUrl + this.name);
-            else vfsUrl = new URL(vfsParentUrl + "/" + this.name);
-         }
+         setPathName(getChildPathName(getName(), false));
+         setVfsUrl(getChildVfsUrl(getName(), false));
       }
       catch (Exception e)
       {
@@ -79,21 +73,70 @@
       }
    }
 
+   protected void initCacheLastModified()
+   {
+      cachedLastModified = lastModified;
+   }
 
+   /**
+    * Initialize entries.
+    *
+    * @throws IOException for any error
+    */
+   protected void init() throws IOException
+   {
+      if (inited.get())
+         return;
+
+      inited.set(true);
+      try
+      {
+         ZipEntry entry = zis.getNextEntry();
+         while (entry != null)
+         {
+            try
+            {
+               String entryName = entry.getName();
+               String url = toURI().toASCIIString() + "!/" + entryName;
+               URL jecURL = new URL(url);
+               JarEntryContents jec = new JarEntryContents(getVFSContext(), this, entry, toURL(), jecURL, zis);
+               entries.put(entryName, jec);
+               entry = zis.getNextEntry();
+            }
+            catch (Throwable t)
+            {
+               IOException ioe = new IOException("Exception while reading nested jar entry: " + this);
+               ioe.initCause(t);
+               ioe.setStackTrace(t.getStackTrace());
+               throw ioe;
+            }
+         }
+      }
+      finally
+      {
+         try
+         {
+            zis.close();
+         }
+         catch (IOException ignored)
+         {
+         }
+         zis = null;
+      }
+   }
+
    public VirtualFileHandler findChild(String path) throws IOException
    {
-      if (inited == false)
-         init();
-      return entries.get(name);
+      JarEntryContents handler = getEntry(path);
+      if (handler == null)
+         throw new IOException("No such child: " + path);
+      return handler;
    }
 
    public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
    {
-      if (inited == false)
-         init();
-      List<VirtualFileHandler> children = new ArrayList<VirtualFileHandler>();
-      children.addAll(entries.values());
-      return children;
+      init();
+      return new ArrayList<VirtualFileHandler>(entries.values());
    }
 
    /**
@@ -105,11 +148,6 @@
       return true;
    }
 
-   public boolean isLeaf() throws IOException
-   {
-      return false;
-   }
-
    public boolean isHidden()
    {
       return false;
@@ -125,51 +163,30 @@
       return lastModified;
    }
 
-
-   public Iterator<JarEntryContents> getEntries()
-           throws IOException
+   public Iterator<JarEntryContents> getEntries() throws IOException
    {
-      if (inited == false)
-         init();
+      init();
       return entries.values().iterator();
    }
 
-   public JarEntryContents getEntry(String name)
-           throws IOException
+   public JarEntryContents getEntry(String name) throws IOException
    {
-      if (inited == false)
-         init();
+      init();
       return entries.get(name);
    }
 
-   public ZipEntry getJarEntry(String name)
-           throws IOException
+   public ZipEntry getZipEntry(String name) throws IOException
    {
-      if (inited == false)
-         init();
-      JarEntryContents jec = entries.get(name);
+      JarEntryContents jec = getEntry(name);
       return (jec != null ? jec.getEntry() : null);
    }
 
-   public byte[] getContents(String name)
-           throws IOException
+   public byte[] getContents(String name) throws IOException
    {
-      if (inited == false)
-         init();
-      JarEntryContents jec = entries.get(name);
+      JarEntryContents jec = getEntry(name);
       return (jec != null ? jec.getContents() : null);
    }
 
-   public String getName()
-   {
-      return name;
-   }
-
-   public String getPathName()
-   {
-      return vfsPath;
-   }
-
    // Stream accessor
    public InputStream openStream() throws IOException
    {
@@ -229,211 +246,16 @@
       return tmp.toString();
    }
 
-   protected void init()
-           throws IOException
+   /**
+    * First, if not already, initialize entries.
+    * Then do simple write. 
+    *
+    * @param out object output stream
+    * @throws IOException for any error
+    */
+   private void writeObject(ObjectOutputStream out) throws IOException
    {
-      inited = true;
-      ZipEntry entry = zis.getNextEntry();
-      while (entry != null)
-      {
-         try
-         {
-            String url = toURI().toASCIIString() + "!/" + entry.getName();
-            URL jecURL = new URL(url);
-            JarEntryContents jec = new JarEntryContents(getVFSContext(), this, entry, jecURL, zis, getPathName());
-            entries.put(entry.getName(), jec);
-            entry = zis.getNextEntry();
-         }
-         catch (URISyntaxException e)
-         {
-            e.printStackTrace();
-         }
-      }
-      zis.close();
-      zis = null;
+      init();
+      out.defaultWriteObject();
    }
-
-   public static class JarEntryContents
-           extends AbstractVirtualFileHandler
-   {
-      /**
-       * serialVersionUID
-       */
-      private static final long serialVersionUID = 1L;
-      private ZipEntry entry;
-      private URL entryURL;
-      private String vfsPath;
-      private byte[] contents;
-      private boolean isJar;
-      private NestedJarFromStream njar;
-      private InputStream openStream;
-
-      JarEntryContents(VFSContext context, VirtualFileHandler parent, ZipEntry entry, URL entryURL, InputStream zis,
-                       String parentVfsPath)
-              throws IOException
-      {
-         super(context, parent, entry.getName());
-         this.entry = entry;
-         this.entryURL = entryURL;
-         this.vfsPath = parentVfsPath + "/" + entry.getName();
-         this.isJar = JarUtils.isArchive(entry.getName());
-         int size = (int) entry.getSize();
-         if (size <= 0)
-            return;
-
-         ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
-         byte[] tmp = new byte[1024];
-         while (zis.available() > 0)
-         {
-            int length = zis.read(tmp);
-            if (length > 0)
-               baos.write(tmp, 0, length);
-         }
-         contents = baos.toByteArray();
-      }
-
-      /**
-       * TODO: removing the entry/jar that resulted in this needs
-       * to be detected.
-       */
-      public boolean exists() throws IOException
-      {
-         return true;
-      }
-
-      public boolean isHidden() throws IOException
-      {
-         return false;
-      }
-
-      public ZipEntry getEntry()
-      {
-         return entry;
-      }
-
-      public byte[] getContents()
-      {
-         return contents;
-      }
-
-      public String getName()
-      {
-         return entry.getName();
-      }
-
-      public String getPathName()
-      {
-         return vfsPath;
-      }
-
-      public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
-      {
-         List<VirtualFileHandler> children = null;
-         if (isJar)
-         {
-            initNestedJar();
-            children = njar.getChildren(ignoreErrors);
-         }
-         return children;
-      }
-
-      public VirtualFileHandler findChild(String path) throws IOException
-      {
-         VirtualFileHandler child;
-         if (isJar)
-         {
-            initNestedJar();
-            child = njar.findChild(path);
-         }
-         else
-         {
-            throw new FileNotFoundException("JarEntryContents(" + entry.getName() + ") has no children");
-         }
-         return child;
-      }
-
-      // Convience attribute accessors
-      public long getLastModified()
-      {
-         return entry.getTime();
-      }
-
-      public long getSize()
-      {
-         return entry.getSize();
-      }
-
-      public boolean isLeaf()
-      {
-         if (isJar)
-            return false;
-         return entry.isDirectory() == false;
-      }
-
-      // Stream accessor
-      public synchronized InputStream openStream()
-              throws IOException
-      {
-         initNestedJar();
-         if (njar != null)
-            openStream = njar.openStream();
-         else
-            openStream = new ByteArrayInputStream(contents);
-         return openStream;
-      }
-
-      public synchronized void close()
-      {
-         if (openStream != null)
-         {
-            try
-            {
-               openStream.close();
-            }
-            catch (IOException e)
-            {
-               log.error("close error", e);
-            }
-            openStream = null;
-         }
-      }
-
-      public URI toURI() throws URISyntaxException
-      {
-         return entryURL.toURI();
-      }
-
-      public String toString()
-      {
-         StringBuffer tmp = new StringBuffer(super.toString());
-         tmp.append('[');
-         tmp.append("name=");
-         tmp.append(entry.getName());
-         tmp.append(",size=");
-         tmp.append(entry.getSize());
-         tmp.append(",time=");
-         tmp.append(entry.getTime());
-         tmp.append(",URI=");
-         try
-         {
-            tmp.append(toURI());
-         }
-         catch (URISyntaxException e)
-         {
-         }
-         tmp.append(']');
-         return tmp.toString();
-      }
-
-      private synchronized void initNestedJar()
-              throws IOException
-      {
-         if (isJar && njar == null)
-         {
-            ByteArrayInputStream bais = new ByteArrayInputStream(contents);
-            ZipInputStream zis = new ZipInputStream(bais);
-            njar = new NestedJarFromStream(getVFSContext(), this, zis, entryURL, entry);
-         }
-      }
-   }
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NestedJarHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NestedJarHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NestedJarHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -42,14 +42,11 @@
  * @author Scott.Stark at jboss.org
  * @version $Revision: 1.1 $
  */
-public class NestedJarHandler extends AbstractJarHandler
+public class NestedJarHandler extends AbstractStructuredJarHandler
 {
    /** serialVersionUID */
    private static final long serialVersionUID = 1L;
 
-   /** The jar entry */
-   private transient JarEntry entry;
-   
    /** The temporary file */
    private transient File temp;
 
@@ -103,8 +100,7 @@
    public static NestedJarHandler create(VFSContext context, VirtualFileHandler parent,
          JarFile parentJar, JarEntry entry, URL url, String entryName) throws IOException
    {
-      File temp = null;
-
+      File temp;
       try
       {
          temp = File.createTempFile("nestedjar", null);
@@ -133,17 +129,14 @@
     * @throws IOException for an error accessing the file system
     * @throws IllegalArgumentException for a null context, url or vfsPath
     */
-   protected NestedJarHandler(VFSContext context, VirtualFileHandler parent,
-         JarFile parentJar, JarEntry entry, URL original, File temp, String entryName)
+   protected NestedJarHandler(VFSContext context, VirtualFileHandler parent, JarFile parentJar, JarEntry entry, URL original, File temp, String entryName)
       throws IOException
    {
-      super(context, parent, temp.toURL(), entryName);
+      super(context, parent, temp.toURL(), createTempJar(temp, parentJar, entry), entry, entryName);
 
       try
       {
-         String vfsParentUrl = parent.toVfsUrl().toString();
-         if (vfsParentUrl.endsWith("/")) vfsUrl = new URL(vfsParentUrl + entryName);
-         else vfsUrl = new URL(vfsParentUrl + "/" + entryName);
+         setVfsUrl(getChildVfsUrl(entryName, false));
       }
       catch (URISyntaxException e)
       {
@@ -155,7 +148,7 @@
       
       try
       {
-         initJarFile(createTempJar(temp, parentJar, entry));
+         initJarFile();
       }
       catch (IOException old)
       {
@@ -164,20 +157,7 @@
          e.setStackTrace(old.getStackTrace());
          throw e;
       }
-      
-      this.entry = entry;
    }
-   
-   /**
-    * Get the entry
-    * 
-    * @return the file
-    */
-   protected JarEntry getEntry()
-   {
-      checkClosed();
-      return entry;
-   }
 
    @Override
    public long getLastModified() throws IOException
@@ -197,23 +177,6 @@
    @Override
    public InputStream openStream() throws IOException
    {
-      FileInputStream fis = new FileInputStream(temp);
-      return fis;
+      return new FileInputStream(temp);
    }
-
-   /**
-    * Restore the jar file from the parent jar and entry name
-    * 
-    * @param in
-    * @throws IOException
-    * @throws ClassNotFoundException
-    */
-   private void readObject(ObjectInputStream in)
-      throws IOException, ClassNotFoundException
-   {
-      JarFile parentJar = super.getJar();
-      // Initial the parent jar entries
-      super.initJarFile(parentJar);
-   }
-
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NoCopyNestedJarHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NoCopyNestedJarHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/NoCopyNestedJarHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -27,6 +27,7 @@
 import java.util.List;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
 import java.util.zip.ZipInputStream;
 
 import org.jboss.virtual.spi.VFSContext;
@@ -43,8 +44,7 @@
    /** serialVersionUID */
    private static final long serialVersionUID = 1L;
 
-   /** The jar entry */
-   private transient JarEntry entry;
+   /** The nested jar */
    private NestedJarFromStream njar;
 
    /**
@@ -55,27 +55,27 @@
     * @param parentJar the parent jar file
     * @param entry the jar entry
     * @param url the url
+    * @param entryName the entry name
     * @throws IOException for an error accessing the file system
     * @throws IllegalArgumentException for a null context, url or vfsPath
     */
-   public NoCopyNestedJarHandler(VFSContext context, VirtualFileHandler parent, JarFile parentJar, JarEntry entry, URL url) throws IOException
+   public NoCopyNestedJarHandler(VFSContext context, VirtualFileHandler parent, JarFile parentJar, JarEntry entry, URL url, String entryName) throws IOException
    {
-      super(context, parent, url, getEntryName(entry));
-
+      super(context, parent, url, parentJar, entry, entryName);
       
       try
       {
          InputStream is = parentJar.getInputStream(entry);
-         ZipInputStream jis;
+         ZipInputStream zis;
          if( (is instanceof ZipInputStream) )
          {
-            jis = (ZipInputStream) is;
+            zis = (JarInputStream) is;
          }
          else
          {
-            jis = new ZipInputStream(is);
+            zis = new ZipInputStream(is);
          }
-         njar = new NestedJarFromStream(context, parent, jis, url, entry); 
+         njar = new NestedJarFromStream(context, parent, zis, url, parentJar, entry);
       }
       catch (IOException original)
       {
@@ -84,19 +84,10 @@
          e.setStackTrace(original.getStackTrace());
          throw e;
       }
-      
-      this.entry = entry;
    }
    
-   /**
-    * Get the entry
-    * 
-    * @return the file
-    */
-   protected JarEntry getEntry()
+   protected void initCacheLastModified()
    {
-      checkClosed();
-      return entry;
    }
 
    @Override
@@ -117,16 +108,13 @@
       return getJar().getInputStream(getEntry());
    }
 
-   @Override
    public VirtualFileHandler findChild(String path) throws IOException
    {
       return njar.findChild(path);
    }
 
-   @Override
    public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
    {
-      return super.getChildren(ignoreErrors);
+      return njar.getChildren(ignoreErrors);
    }
-   
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/SynthenticDirEntryHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/SynthenticDirEntryHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/jar/SynthenticDirEntryHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -24,8 +24,8 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URL;
 import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -39,49 +39,46 @@
 
 /**
  * SynthenticDirEntryHandler represents non-existent directory jar entry.
- * 
+ *
  * @author Scott.Stark at jboss.org
  * @version $Revision: 1.1 $
  */
 public class SynthenticDirEntryHandler extends AbstractURLHandler
-   implements StructuredVirtualFileHandler
+      implements StructuredVirtualFileHandler
 {
-   /** serialVersionUID */
+   /**
+    * serialVersionUID
+    */
    private static final long serialVersionUID = 1L;
 
-   /** The jar file */
+   /**
+    * The jar file
+    */
    private long lastModified;
    private transient List<VirtualFileHandler> entryChildren;
    private transient Map<String, VirtualFileHandler> entryMap;
-   
+
    /**
     * Create a new SynthenticDirEntryHandler.
-    * 
-    * @param context the context
-    * @param parent the parent
-    * @param entryName - the simple name for the dir
+    *
+    * @param context      the context
+    * @param parent       the parent
+    * @param entryName    - the simple name for the dir
     * @param lastModified the timestamp for the dir
-    * @param url the full url
-    * @throws IOException for an error accessing the file system
+    * @param url          the full url
+    * @throws IOException              for an error accessing the file system
     * @throws IllegalArgumentException for a null context, url, jar or entry
     */
    public SynthenticDirEntryHandler(VFSContext context, VirtualFileHandler parent,
-      String entryName, long lastModified, URL url)
-      throws IOException
+                                    String entryName, long lastModified, URL url)
+         throws IOException
    {
       super(context, parent, url, entryName);
       try
       {
          URL parentVfsUrl = parent.toVfsUrl();
          String vfsParentUrl = parentVfsUrl.toString();
-         if (vfsParentUrl.endsWith("/"))
-         {
-            vfsUrl = new URL(vfsParentUrl + entryName);
-         }
-         else
-         {
-            vfsUrl = new URL(vfsParentUrl + "/" + entryName + "/");
-         }
+         setVfsUrl(getChildVfsUrl(entryName, vfsParentUrl.endsWith("/") == false));
       }
       catch (URISyntaxException e)
       {
@@ -92,14 +89,15 @@
 
    /**
     * Add a child to an entry
-    * @param child
+    *
+    * @param child the child file handler
     */
    public synchronized void addChild(VirtualFileHandler child)
    {
-      if( entryChildren == null )
+      if (entryChildren == null)
          entryChildren = new ArrayList<VirtualFileHandler>();
       entryChildren.add(child);
-      if( entryMap != null )
+      if (entryMap != null)
          entryMap.put(child.getName(), child);
    }
 
@@ -144,10 +142,9 @@
    public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
    {
       checkClosed();
-      List<VirtualFileHandler> children = entryChildren;
-      if( entryChildren == null )
-         children = Collections.emptyList();
-      return children;
+      if (entryChildren == null)
+         return Collections.emptyList();
+      return Collections.unmodifiableList(entryChildren);
    }
 
    public VirtualFileHandler findChild(String path) throws IOException
@@ -158,26 +155,26 @@
    /**
     * Create a child handler for the given name. This looks to the entryMap
     * for an existing child.
+    *
     * @param name - the simple name of an immeadiate child.
     * @return the VirtualFileHandler previously added via addChild.
     * @throws IOException - thrown if there are no children or the
-    *  name does not match a child
+    *                     name does not match a child
     */
    public synchronized VirtualFileHandler createChildHandler(String name)
-      throws IOException
+         throws IOException
    {
-      if( entryChildren == null )
-         throw new FileNotFoundException(this+" has no children");
-      if( entryMap == null )
+      if (entryChildren == null)
+         throw new FileNotFoundException(this + " has no children");
+      if (entryMap == null)
       {
          entryMap = new HashMap<String, VirtualFileHandler>();
-         for(VirtualFileHandler child : entryChildren)
+         for (VirtualFileHandler child : entryChildren)
             entryMap.put(child.getName(), child);
       }
       VirtualFileHandler child = entryMap.get(name);
-      if( child == null )
-         throw new FileNotFoundException(this+" has no child: "+name);
+      if (child == null)
+         throw new FileNotFoundException(this + " has no child: " + name);
       return child;
    }
-
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/memory/MemoryContextHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/memory/MemoryContextHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/memory/MemoryContextHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -165,19 +165,19 @@
    @Override
    public URL toVfsUrl() throws MalformedURLException, URISyntaxException
    {
-      if (vfsUrl == null)
+      if (getVfsUrl() == null)
       {
          if (isLeaf())
          {
-            vfsUrl = getURL();
+            setVfsUrl(getURL());
          }
          else
          {
             String vfsString = getURL().toString(); 
             if (vfsString.endsWith("/") == false)
-               vfsUrl = new URL(vfsString + "/");
+               setVfsUrl(new URL(vfsString + "/"));
          }
       }
-      return vfsUrl;
+      return getVfsUrl();
    }
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledContextFactory.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledContextFactory.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledContextFactory.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -35,7 +35,7 @@
 {
    private ConcurrentHashMap<String, AssembledDirectory> registry = new ConcurrentHashMap<String, AssembledDirectory>();
    private volatile int count;
-   private static  AssembledContextFactory instance = new AssembledContextFactory();
+   private static AssembledContextFactory instance = new AssembledContextFactory();
 
    /**
     * Creates an assembly returning the root AssembledDirectory .
@@ -47,7 +47,8 @@
     */
    public AssembledDirectory create(String name, String rootName)
    {
-      if (registry.containsKey(name)) throw new RuntimeException("Assembled context already exists for name: " + name);
+      if (registry.containsKey(name))
+         throw new RuntimeException("Assembled context already exists for name: " + name);
       try
       {
          AssembledContext context = new AssembledContext(name, rootName);

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledDirectory.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledDirectory.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledDirectory.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -33,12 +33,11 @@
 import org.jboss.virtual.plugins.context.jar.JarUtils;
 import org.jboss.virtual.plugins.vfs.helpers.FilterVirtualFileVisitor;
 import org.jboss.virtual.plugins.vfs.helpers.SuffixesExcludeFilter;
-import org.jboss.virtual.spi.VirtualFileHandler;
 
 /**
  * Extension of VirtualFile that represents a virtual directory that can be composed of arbitrary files and resources
  * spread throughout the file system or embedded in jar files.
- *
+ *
  * @author <a href="bill at jboss.com">Bill Burke</a>
  * @version $Revision: 1.1 $
  */
@@ -46,10 +45,10 @@
 {
    private AssembledDirectoryHandler directory;
 
-   public AssembledDirectory(VirtualFileHandler handler)
+   public AssembledDirectory(AssembledDirectoryHandler handler)
    {
       super(handler);
-      directory = (AssembledDirectoryHandler) handler;
+      directory = handler;
    }
 
    /**
@@ -59,11 +58,11 @@
     * So, if you added com.acme.Customer class, then a directory structure com/acme would be created
     * and an entry in the acme directory would be the .class file.
     *
-    * @param clazz
+    * @param clazz the class
     */
    public void addClass(Class clazz)
    {
-      if (clazz == null)
+      if (clazz == null)
          throw new IllegalArgumentException("Null clazz");
       addClass(clazz.getName(), clazz.getClassLoader());
    }
@@ -94,9 +93,9 @@
     */
    public void addClass(String className, ClassLoader loader)
    {
-      if (className == null)
+      if (className == null)
          throw new IllegalArgumentException("Null className");
-      if (loader == null)
+      if (loader == null)
          throw new IllegalArgumentException("Null loader");
       String resource = className.replace('.', '/') + ".class";
       URL url = loader.getResource(resource);
@@ -113,7 +112,7 @@
     */
    public AssembledDirectory mkdirs(String path)
    {
-      if (path == null)
+      if (path == null)
          throw new IllegalArgumentException("Null path");
       String[] pkgs = path.split("/");
       AssembledDirectoryHandler dir = directory;
@@ -134,8 +133,7 @@
          }
          dir = next;
       }
-      AssembledDirectory p = (AssembledDirectory) dir.getVirtualFile();
-      return p;
+      return (AssembledDirectory) dir.getVirtualFile();
    }
 
    /**
@@ -153,8 +151,8 @@
     * @param excludes
     */
    public void addResources(Class baseResource, String[] includes, String[] excludes)
-   {
-      if (baseResource == null)
+   {
+      if (baseResource == null)
          throw new IllegalArgumentException("Null base resource");
       String resource = baseResource.getName().replace('.', '/') + ".class";
       addResources(resource, includes, excludes, baseResource.getClassLoader());
@@ -176,8 +174,8 @@
     */
    public void addResources(String baseResource, final String[] includes, final String[] excludes)
    {
-      if (baseResource == null)
-         throw new IllegalArgumentException("Null base resource");
+      if (baseResource == null)
+         throw new IllegalArgumentException("Null base resource");
       addResources(baseResource, includes, excludes, Thread.currentThread().getContextClassLoader());   
    }
 
@@ -198,9 +196,9 @@
     */
    public void addResources(String baseResource, final String[] includes, final String[] excludes, ClassLoader loader)
    {
-      if (baseResource == null)
+      if (baseResource == null)
          throw new IllegalArgumentException("Null baseResource");
-      if (loader == null)
+      if (loader == null)
          throw new IllegalArgumentException("Null loader");
       URL url = loader.getResource(baseResource);
       if (url == null) throw new RuntimeException("Could not find baseResource: " + baseResource);
@@ -232,12 +230,14 @@
                      break;
                   }
                }
-               if (!matched) return false;
+               if (matched == false)
+                  return false;
                if (excludes != null)
                {
                   for (String exclude : excludes)
                   {
-                     if (antMatch(path, exclude)) return false;
+                     if (antMatch(path, exclude))
+                        return false;
                   }
                }
                return true;
@@ -267,7 +267,7 @@
     */
    public static Pattern getPattern(String matcher)
    {
-      if (matcher == null)
+      if (matcher == null)
          throw new IllegalArgumentException("Null matcher");
       matcher = matcher.replace(".", "\\.");
       matcher = matcher.replace("*", ".*");
@@ -285,9 +285,9 @@
     */
    public static boolean antMatch(String path, String expression)
    {
-      if (path == null)
+      if (path == null)
          throw new IllegalArgumentException("Null path");
-      if (expression == null)
+      if (expression == null)
          throw new IllegalArgumentException("Null expression");
       if (path.startsWith("/")) path = path.substring(1);
       if (expression.endsWith("/")) expression += "**";
@@ -305,7 +305,8 @@
             {
                x++;
             } while (x < expressions.length && expressions[x].equals("**"));
-            if (x == expressions.length) return true; // "**" with nothing after it
+            if (x == expressions.length)
+               return true; // "**" with nothing after it
             pattern = getPattern(expressions[x]);
          }
          String element = paths[p];
@@ -322,8 +323,10 @@
             return false;
          }
       }
-      if (p < paths.length) return false;
-      if (x < expressions.length) return false;
+      if (p < paths.length)
+         return false;
+      if (x < expressions.length)
+         return false;
       return true;
    }
 
@@ -334,7 +337,7 @@
     */
    public VirtualFile addChild(VirtualFile vf)
    {
-      if (vf == null)
+      if (vf == null)
          throw new IllegalArgumentException("Null virtual file");
       return directory.addChild(vf.getHandler()).getVirtualFile();
    }
@@ -397,13 +400,14 @@
     * @param loader
     */
    public VirtualFile addResource(String resource, ClassLoader loader)
-   {
-      if (resource == null)
-         throw new IllegalArgumentException("Null resource");
-      if (loader == null)
+   {
+      if (resource == null)
+         throw new IllegalArgumentException("Null resource");
+      if (loader == null)
          throw new IllegalArgumentException("Null loader");
       URL url = loader.getResource(resource);
-      if (url == null) throw new RuntimeException("Could not find resource: " + resource);
+      if (url == null)
+         throw new RuntimeException("Could not find resource: " + resource);
 
       return addResource(url);
    }
@@ -414,9 +418,9 @@
     * @param url
     */
    public VirtualFile addResource(URL url)
-   {
-      if (url == null)
-         throw new IllegalArgumentException("Null url");
+   {
+      if (url == null)
+         throw new IllegalArgumentException("Null url");
    
       try
       {
@@ -441,15 +445,16 @@
     */
    public VirtualFile addResource(String resource, ClassLoader loader, String newName)
    {
-      if (resource == null)
-         throw new IllegalArgumentException("Null resource");
-      if (loader == null)
+      if (resource == null)
+         throw new IllegalArgumentException("Null resource");
+      if (loader == null)
          throw new IllegalArgumentException("Null loader");
-      if (newName == null)
+      if (newName == null)
          throw new IllegalArgumentException("Null newName");
-
+
       URL url = loader.getResource(resource);
-      if (url == null) throw new RuntimeException("Could not find resource: " + resource);
+      if (url == null)
+         throw new RuntimeException("Could not find resource: " + resource);
       try
       {
          VirtualFile vf = VFS.getRoot(url);
@@ -471,9 +476,9 @@
     */
    public VirtualFile addBytes(byte[] bytes, String name)
    {
-      if (bytes == null)
+      if (bytes == null)
          throw new IllegalArgumentException("Null bytes");
-      if (name == null)
+      if (name == null)
          throw new IllegalArgumentException("Null name");
       ByteArrayHandler handler = null;
       try
@@ -496,7 +501,7 @@
     */
    public AssembledDirectory mkdir(String name)
    {
-      if (name == null)
+      if (name == null)
          throw new IllegalArgumentException("Null name");
       AssembledDirectoryHandler handler = null;
       try

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledDirectoryHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledDirectoryHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledDirectoryHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -54,13 +54,14 @@
    {
       super(context, parent, name);
       String path = getPathName();
-      if (!path.endsWith("/")) path += "/";
-      vfsUrl = new URL("vfs", context.getName(), -1, path, new AssembledUrlStreamHandler(context));
+      if (path.endsWith("/") == false)
+         path += "/";
+      setVfsUrl(new URL("vfs", context.getName(), -1, path, new AssembledUrlStreamHandler(context)));
    }
 
    public VirtualFileHandler addChild(VirtualFileHandler handler)
    {
-      if (!handler.getClass().isAnnotationPresent(Assembled.class))
+      if (handler.getClass().isAnnotationPresent(Assembled.class) == false)
       {
          try
          {
@@ -84,7 +85,7 @@
 
    public URI toURI() throws URISyntaxException
    {
-      return vfsUrl.toURI();
+      return getVfsUrl().toURI();
    }
 
    public long getLastModified() throws IOException
@@ -125,7 +126,8 @@
    public VirtualFileHandler createChildHandler(String name) throws IOException
    {
       VirtualFileHandler handler = childrenMap.get(name);
-      if (handler == null) throw new IOException("Could not locate child: " + name);
+      if (handler == null)
+         throw new IOException("Could not locate child: " + name);
       return handler;
    }
 
@@ -145,6 +147,6 @@
    @Override
    public URL toURL() throws MalformedURLException, URISyntaxException
    {
-      return vfsUrl;
+      return getVfsUrl();
    }
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledFileHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledFileHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/AssembledFileHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -46,9 +46,10 @@
    public AssembledFileHandler(AssembledContext context, AssembledDirectoryHandler parent, String name, VirtualFileHandler delegate) throws IOException
    {
       super(context, parent, name);
+      if (delegate == null)
+         throw new IllegalArgumentException("Null delegate");
       this.delegate = delegate;
-      vfsUrl = new URL("vfs", context.getName(), -1, getPathName(), new AssembledUrlStreamHandler(context));
-
+      setVfsUrl(new URL("vfs", context.getName(), -1, getPathName(), new AssembledUrlStreamHandler(context)));
    }
 
    public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
@@ -61,56 +62,47 @@
       throw new IOException("File cannot have children: " + this);
    }
 
-   public URL toURL()
-           throws MalformedURLException, URISyntaxException
+   public URL toURL() throws MalformedURLException, URISyntaxException
    {
       return delegate.toURL();
    }
 
-   public long getLastModified()
-           throws IOException
+   public long getLastModified() throws IOException
    {
       return delegate.getLastModified();
    }
 
-   public boolean hasBeenModified()
-           throws IOException
+   public boolean hasBeenModified() throws IOException
    {
       return delegate.hasBeenModified();
    }
 
-   public long getSize()
-           throws IOException
+   public long getSize() throws IOException
    {
       return delegate.getSize();
    }
 
-   public boolean exists()
-           throws IOException
+   public boolean exists() throws IOException
    {
       return delegate.exists();
    }
 
-   public boolean isLeaf()
-           throws IOException
+   public boolean isLeaf() throws IOException
    {
       return delegate.isLeaf();
    }
 
-   public boolean isHidden()
-           throws IOException
+   public boolean isHidden() throws IOException
    {
       return delegate.isHidden();
    }
 
-   public InputStream openStream()
-           throws IOException
+   public InputStream openStream() throws IOException
    {
       return delegate.openStream();
    }
 
-   public URI toURI()
-           throws URISyntaxException
+   public URI toURI() throws URISyntaxException
    {
       return delegate.toURI();
    }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/ByteArrayHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/ByteArrayHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/context/vfs/ByteArrayHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -21,19 +21,18 @@
 */
 package org.jboss.virtual.plugins.context.vfs;
 
-import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler;
-import org.jboss.virtual.spi.VFSContext;
-import org.jboss.virtual.spi.VirtualFileHandler;
-
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.net.MalformedURLException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ByteArrayInputStream;
 import java.util.List;
 
+import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
 /**
  * comment
  *
@@ -44,26 +43,25 @@
 public class ByteArrayHandler extends AbstractVirtualFileHandler
 {
    private byte[] bytes;
-   private final long lastModified = System.currentTimeMillis();
+   private final long lastModified;
 
-
    public ByteArrayHandler(AssembledContext context, VirtualFileHandler parent, String name, byte[] bytes) throws IOException
    {
       super(context, parent, name);
       this.bytes = bytes;
-      vfsUrl = new URL("vfs", context.getName(), -1, getPathName(), new AssembledUrlStreamHandler(context));
+      lastModified = System.currentTimeMillis();
+      setVfsUrl(new URL("vfs", context.getName(), -1, getPathName(), new AssembledUrlStreamHandler(context)));
    }
 
-
    @Override
    public URL toURL() throws MalformedURLException, URISyntaxException
    {
-      return vfsUrl;
+      return getVfsUrl();
    }
 
    public URI toURI() throws URISyntaxException
    {
-      return vfsUrl.toURI();
+      return getVfsUrl().toURI();
    }
 
    public long getLastModified() throws IOException

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileUrlStreamHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileUrlStreamHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileUrlStreamHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -56,10 +56,6 @@
       {
          throw new RuntimeException(e);
       }
-      catch (IOException e)
-      {
-         throw new RuntimeException(e);
-      }
       String urlString = u.toString();
       int idx = urlString.indexOf(baseRootUrl);
       if (idx == -1)

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/ExtensibleFilter.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/ExtensibleFilter.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/ExtensibleFilter.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -25,6 +25,7 @@
 import java.util.Comparator;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.VirtualFileFilter;
@@ -77,13 +78,13 @@
           "SCCS", "TAGS", "core", "tags"};
 
    /** The list of disallowed suffixes, sorted using reverse values */
-   private ArrayList<String> suffixes;
+   private List<String> suffixes;
 
    /** The sorted list of disallowed prefixes */
-   private ArrayList<String> prefixes;
+   private List<String> prefixes;
 
    /** The sorted list of disallowed values */
-   private ArrayList<String> matches;
+   private List<String> matches;
 
    /** Use the default values for suffixes, prefixes, and matches */
    public ExtensibleFilter()

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/PathTokenizer.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/PathTokenizer.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/PathTokenizer.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -27,6 +27,7 @@
 /**
  * PathTokenizer.
  * 
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/SuffixMatchFilter.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/SuffixMatchFilter.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/plugins/vfs/helpers/SuffixMatchFilter.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -21,9 +21,9 @@
  */
 package org.jboss.virtual.plugins.vfs.helpers;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.LinkedHashSet;
 
 import org.jboss.logging.Logger;
 import org.jboss.virtual.VirtualFile;
@@ -65,9 +65,7 @@
    @SuppressWarnings("unchecked")      
    public SuffixMatchFilter(String suffix, VisitorAttributes attributes)
    {
-      this(Collections.EMPTY_LIST, attributes);
-      suffixes.add(suffix);
-      trace = log.isTraceEnabled();
+      this(Collections.singleton(suffix), attributes);
    }
    /**
     * Create a new SuffixMatchFilter.
@@ -89,8 +87,9 @@
       super(attributes == null ? VisitorAttributes.DEFAULT : attributes);
       if (suffixes == null)
          throw new IllegalArgumentException("Null suffixes");
-      this.suffixes = new ArrayList<String>();
+      this.suffixes = new LinkedHashSet<String>();
       this.suffixes.addAll(suffixes);
+      trace = log.isTraceEnabled();
    }
 
    /**

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/LinkInfo.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/LinkInfo.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/LinkInfo.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -60,5 +60,4 @@
    {
       return name;
    }
-
 }

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/VFSContextFactoryLocator.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/VFSContextFactoryLocator.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/VFSContextFactoryLocator.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -34,6 +34,7 @@
 import java.util.Enumeration;
 import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.jboss.logging.Logger;
@@ -132,7 +133,7 @@
       if (factory == null)
          throw new IllegalArgumentException("Null VFSContextFactory");
 
-      ArrayList<String> protocols = new ArrayList<String>();
+      List<String> protocols = new ArrayList<String>();
       for (Map.Entry<String, VFSContextFactory> entry : factoryByProtocol.entrySet())
       {
          if (factory == entry.getValue())
@@ -262,7 +263,7 @@
     */
    private static VFSContextFactory[] loadFactories(URL serviceURL, ClassLoader loader)
    {
-      ArrayList<VFSContextFactory> temp = new ArrayList<VFSContextFactory>();
+      List<VFSContextFactory> temp = new ArrayList<VFSContextFactory>();
       try
       {
          InputStream is = serviceURL.openStream();
@@ -305,6 +306,7 @@
     * 
     * @param cl the classloader
     * @param className the class name
+    * @param context the context
     * @return the vfs context factory
     */
    private static VFSContextFactory createVFSContextFactory(ClassLoader cl, String className, String context)

Modified: projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/VirtualFileHandler.java
===================================================================
--- projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/VirtualFileHandler.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/main/java/org/jboss/virtual/spi/VirtualFileHandler.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -59,8 +59,8 @@
     * Get a VFS-based URL
     *
     * @return the url
-    * @throws MalformedURLException
-    * @throws URISyntaxException
+    * @throws URISyntaxException for an error parsing the URI
+    * @throws MalformedURLException for any error
     */
    URL toVfsUrl() throws MalformedURLException, URISyntaxException;
    
@@ -95,8 +95,8 @@
     * Returns true if the file has been modified since this method was last called
     * Last modified time is initialized at handler instantiation.
     *
-    * @return
-    * @throws IOException
+    * @return true if modified, false otherwise
+    * @throws IOException for any error
     */
    boolean hasBeenModified() throws IOException;
    

Added: projects/vfs/trunk/src/test/java/META-INF/services/org.jboss.virtual.spi.VFSContextFactory
===================================================================
--- projects/vfs/trunk/src/test/java/META-INF/services/org.jboss.virtual.spi.VFSContextFactory	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/META-INF/services/org.jboss.virtual.spi.VFSContextFactory	2007-12-26 00:56:58 UTC (rev 68554)
@@ -0,0 +1,2 @@
+# org.jboss.test.virtual.support.FileOAContextFactory
+org.jboss.test.virtual.support.JarOAContextFactory

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/FileOAContextFactory.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/FileOAContextFactory.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/FileOAContextFactory.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -0,0 +1,45 @@
+/*
+* 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.support;
+
+import java.net.URL;
+import java.net.URI;
+import java.io.IOException;
+
+import org.jboss.virtual.plugins.context.file.FileSystemContextFactory;
+import org.jboss.virtual.spi.VFSContext;
+
+/**
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public class FileOAContextFactory extends FileSystemContextFactory
+{
+   public VFSContext getVFS(URL root) throws IOException
+   {
+      return super.getVFS(OptionsAwareURI.toURL(root));
+   }
+
+   public VFSContext getVFS(URI root) throws IOException
+   {
+      return super.getVFS(OptionsAwareURI.toURI(root));
+   }
+}

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/JarOAContextFactory.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/JarOAContextFactory.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/JarOAContextFactory.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -0,0 +1,45 @@
+/*
+* 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.support;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+
+import org.jboss.virtual.plugins.context.jar.JarContextFactory;
+import org.jboss.virtual.spi.VFSContext;
+
+/**
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public class JarOAContextFactory extends JarContextFactory
+{
+   public VFSContext getVFS(URL root) throws IOException
+   {
+      return super.getVFS(OptionsAwareURI.toURL(root));
+   }
+
+   public VFSContext getVFS(URI root) throws IOException
+   {
+      return getVFS(OptionsAwareURI.toURI(root).toURL());
+   }
+}

Added: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/OptionsAwareURI.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/OptionsAwareURI.java	                        (rev 0)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/support/OptionsAwareURI.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -0,0 +1,89 @@
+/*
+* 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.support;
+
+import java.net.URI;
+import java.net.URL;
+import java.net.URISyntaxException;
+import java.io.IOException;
+
+/**
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public class OptionsAwareURI
+{
+   private static final String NoCopy = "useNoCopyJarHandler=true";
+
+   private static ThreadLocal<Boolean> flag = new ThreadLocal<Boolean>()
+   {
+      protected Boolean initialValue()
+      {
+         return Boolean.FALSE;
+      }
+   };
+
+   public static void set()
+   {
+      flag.set(true);
+   }
+
+   public static void clear()
+   {
+      flag.set(false);
+   }
+
+   public static URL toURL(URL url) throws IOException
+   {
+      if (flag.get())
+      {
+         try
+         {
+            URI uri = toURI(url.toURI());
+            return uri.toURL();
+         }
+         catch (URISyntaxException e)
+         {
+            throw new IOException(e.getReason());
+         }
+      }
+      else
+         return url;
+   }
+
+   public static URI toURI(URI uri) throws IOException
+   {
+      if (flag.get())
+      {
+         try
+         {
+            return new URI(uri.toString() + "?" + NoCopy);
+//            return new URI(uri.getScheme(), uri.getUserInfo(), uri.getPath(), NoCopy, uri.getFragment());
+         }
+         catch (URISyntaxException e)
+         {
+            throw new IOException(e.getReason());
+         }
+      }
+      else
+         return uri;
+   }
+}

Modified: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -43,15 +43,15 @@
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
-
 import org.jboss.test.BaseTestCase;
 import org.jboss.test.virtual.support.ClassPathIterator;
+import org.jboss.test.virtual.support.ClassPathIterator.ClassPathEntry;
 import org.jboss.test.virtual.support.MetaDataMatchFilter;
-import org.jboss.test.virtual.support.ClassPathIterator.ClassPathEntry;
 import org.jboss.virtual.VFS;
 import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.VisitorAttributes;
+import org.jboss.virtual.plugins.context.jar.JarEntryContents;
 import org.jboss.virtual.plugins.context.jar.NestedJarFromStream;
 import org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter;
 import org.jboss.virtual.spi.LinkInfo;
@@ -125,12 +125,15 @@
 
       JarEntry jar1 = jf.getJarEntry("jar1.jar");
       URL jar1URL = new URL(outerJar.toURL(), "jar1.jar");
+      VFSContextFactory pf1 = VFSContextFactoryLocator.getFactory(jar1URL);
+      VFSContext parent1 = pf1.getVFS(jar1URL);
+
       ZipInputStream jis1 = new ZipInputStream(jf.getInputStream(jar1));
-      NestedJarFromStream njfs = new NestedJarFromStream(context, null, jis1, jar1URL, jar1);
-      NestedJarFromStream.JarEntryContents e1 = njfs.getEntry("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
+      NestedJarFromStream njfs = new NestedJarFromStream(context, parent1.getRoot(), jis1, jar1URL, jf, jar1);
+      JarEntryContents e1 = njfs.getEntry("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
       assertNotNull(e1);
       log.info("org/jboss/test/vfs/support/CommonClass.class: "+e1);
-      NestedJarFromStream.JarEntryContents mfe1 = njfs.getEntry("META-INF/MANIFEST.MF");
+      JarEntryContents mfe1 = njfs.getEntry("META-INF/MANIFEST.MF");
       assertNotNull("jar1!/META-INF/MANIFEST.MF", mfe1);
       InputStream mfIS = mfe1.openStream();
       Manifest mf = new Manifest(mfIS);
@@ -142,12 +145,15 @@
 
       JarEntry jar2 = jf.getJarEntry("jar2.jar");
       URL jar2URL = new URL(outerJar.toURL(), "jar2.jar");
+      VFSContextFactory pf2 = VFSContextFactoryLocator.getFactory(jar2URL);
+      VFSContext parent2 = pf2.getVFS(jar2URL);
+
       ZipInputStream jis2 = new ZipInputStream(jf.getInputStream(jar2));
-      NestedJarFromStream njfs2 = new NestedJarFromStream(context, null, jis2, jar2URL, jar2);
-      NestedJarFromStream.JarEntryContents e2 = njfs2.getEntry("org/jboss/test/vfs/support/jar2/ClassInJar2.class");
+      NestedJarFromStream njfs2 = new NestedJarFromStream(context, parent2.getRoot(), jis2, jar2URL, jf, jar2);
+      JarEntryContents e2 = njfs2.getEntry("org/jboss/test/vfs/support/jar2/ClassInJar2.class");
       assertNotNull(e2);
       log.info("org/jboss/test/vfs/support/CommonClass.class: "+e2);
-      NestedJarFromStream.JarEntryContents mfe2 = njfs2.getEntry("META-INF/MANIFEST.MF");
+      JarEntryContents mfe2 = njfs2.getEntry("META-INF/MANIFEST.MF");
       assertNotNull("jar2!/META-INF/MANIFEST.MF", mfe2);
       InputStream mf2IS = mfe2.openStream();
       Manifest mf2 = new Manifest(mf2IS);
@@ -855,7 +861,6 @@
       ObjectOutputStream oos = new ObjectOutputStream(fos);
       oos.writeObject(inner);
       oos.close();
-
       
       // Read in the VF from the serialized file
       FileInputStream fis = new FileInputStream(vfsSer);

Modified: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARCacheUnitTestCase.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARCacheUnitTestCase.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARCacheUnitTestCase.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -24,7 +24,6 @@
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.InputStream;
 import java.util.jar.Attributes;
 import java.util.jar.JarFile;
 import java.util.jar.JarOutputStream;
@@ -32,7 +31,6 @@
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
-
 import org.jboss.test.BaseTestCase;
 import org.jboss.virtual.VFS;
 import org.jboss.virtual.VirtualFile;

Modified: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARVFSContextUnitTestCase.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARVFSContextUnitTestCase.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARVFSContextUnitTestCase.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -26,9 +26,9 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import org.jboss.virtual.VFS;
+import org.jboss.virtual.plugins.context.file.FileSystemContext;
 import org.jboss.virtual.plugins.context.jar.JarContext;
 import org.jboss.virtual.plugins.context.jar.JarUtils;
-import org.jboss.virtual.plugins.context.file.FileSystemContext;
 import org.jboss.virtual.spi.VFSContext;
 
 /**

Modified: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARVirtualFileHandlerUnitTestCase.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARVirtualFileHandlerUnitTestCase.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/JARVirtualFileHandlerUnitTestCase.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -29,7 +29,6 @@
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
-
 import org.jboss.virtual.plugins.context.jar.JarContext;
 import org.jboss.virtual.plugins.context.jar.JarUtils;
 import org.jboss.virtual.spi.VFSContext;

Modified: projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/URLExistsUnitTestCase.java
===================================================================
--- projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/URLExistsUnitTestCase.java	2007-12-25 08:11:40 UTC (rev 68553)
+++ projects/vfs/trunk/src/test/java/org/jboss/test/virtual/test/URLExistsUnitTestCase.java	2007-12-26 00:56:58 UTC (rev 68554)
@@ -24,7 +24,6 @@
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.InputStream;
-import java.net.JarURLConnection;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.jar.JarOutputStream;




More information about the jboss-cvs-commits mailing list