[jboss-cvs] JBossAS SVN: r57713 - in projects/microcontainer/trunk/container/src: main/org/jboss/virtual/plugins/context/jar tests/org/jboss/test/virtual/test

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Oct 18 18:21:44 EDT 2006


Author: scott.stark at jboss.org
Date: 2006-10-18 18:21:38 -0400 (Wed, 18 Oct 2006)
New Revision: 57713

Modified:
   projects/microcontainer/trunk/container/src/main/org/jboss/virtual/plugins/context/jar/AbstractJarHandler.java
   projects/microcontainer/trunk/container/src/main/org/jboss/virtual/plugins/context/jar/JarEntryHandler.java
   projects/microcontainer/trunk/container/src/tests/org/jboss/test/virtual/test/AbstractVirtualFileHandlerTest.java
   projects/microcontainer/trunk/container/src/tests/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
Log:
Rewrite the jar handler to be proper structured file handler with parent/child relationships between the jar entries

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/virtual/plugins/context/jar/AbstractJarHandler.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/virtual/plugins/context/jar/AbstractJarHandler.java	2006-10-18 21:30:51 UTC (rev 57712)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/virtual/plugins/context/jar/AbstractJarHandler.java	2006-10-18 22:21:38 UTC (rev 57713)
@@ -21,6 +21,7 @@
 */
 package org.jboss.virtual.plugins.context.jar;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.net.JarURLConnection;
@@ -31,11 +32,15 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 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;
 
@@ -47,6 +52,7 @@
  * @version $Revision: 1.1 $
  */
 public class AbstractJarHandler extends AbstractURLHandler
+   implements StructuredVirtualFileHandler
 {
    /** serialVersionUID */
    private static final long serialVersionUID = 1;
@@ -56,6 +62,7 @@
 
    /** The jar entries */
    private transient List<VirtualFileHandler> entries;
+   private transient Map<String, VirtualFileHandler> entryMap;
 
    /**
     * Get a jar entry name
@@ -114,16 +121,68 @@
       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<LinkedHashMap<String,JarEntry>> levelMapList = new ArrayList<LinkedHashMap<String,JarEntry>>();
       entries = new ArrayList<VirtualFileHandler>();
+      entryMap = new HashMap<String, VirtualFileHandler>();
+      boolean trace = log.isTraceEnabled();
       while (enumeration.hasMoreElements())
       {
          JarEntry entry = enumeration.nextElement();
-         VirtualFileHandler handler = createVirtualFileHandler(this, entry);
-         entries.add(handler);
+         String[] paths = entry.getName().split("/");
+         int depth = paths.length;
+         if( depth >= levelMapList.size() )
+         {
+            for(int n = levelMapList.size(); n <= depth; n ++)
+               levelMapList.add(new LinkedHashMap<String,JarEntry>());
+         }
+         LinkedHashMap<String,JarEntry> levelMap = levelMapList.get(depth);
+         levelMap.put(paths[depth-1], entry);
+         if( trace )
+            log.trace("added "+entry.getName()+" at depth "+depth);
       }
+      // Process each level to build the handlers in parent first order
+      for(LinkedHashMap<String,JarEntry> levelMap : levelMapList)
+      {
+         for(JarEntry entry : levelMap.values())
+         {
+            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);
+            }
+            // 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( 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);
+            }
+         }
+      }
    }
 
    protected void doClose()
@@ -160,28 +219,15 @@
 
    public VirtualFileHandler findChild(String path) throws IOException
    {
-      if (path == null)
-         throw new IllegalArgumentException("Null path");
+      return super.structuredFindChild(path);
+   }
 
-      if (path.length() == 0)
-         return this;
-      
-      List<VirtualFileHandler> children = getChildren(false);
-      for (VirtualFileHandler child : children)
-      {
-         // Try a simple match
-         String name = child.getName();
-         if (name.equals(path))
-            return child;
-         
-         // Try a partial match on a nested jar
-         if (child.isArchive() && path.startsWith(name))
-         {
-            String remainingPath = path.substring(name.length()+1);
-            return child.findChild(remainingPath);
-         }
-      }
-      throw new IOException("Child not found " + path + " for " + this);
+   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;
    }
 
    /**
@@ -193,7 +239,9 @@
     * @throws IOException for any error accessing the file system
     * @throws IllegalArgumentException for a null parent or entry
     */
-   public VirtualFileHandler createVirtualFileHandler(VirtualFileHandler parent, JarEntry entry) throws IOException
+   protected VirtualFileHandler createVirtualFileHandler(VirtualFileHandler parent, JarEntry entry,
+         String entryName)
+      throws IOException
    {
       if (parent == null)
          throw new IllegalArgumentException("Null parent");
@@ -214,7 +262,7 @@
       }
       if (buffer.charAt(buffer.length()-1) != '/')
          buffer.append('/');
-      buffer.append(entry.getName());
+      buffer.append(entryName);
       URL url = new URL(buffer.toString());
 
       VFSContext context = parent.getVFSContext();
@@ -232,8 +280,9 @@
       }
       else
       {
-         vfh = new JarEntryHandler(context, parent, jar, entry, url);         
+         vfh = new JarEntryHandler(context, parent, jar, entry, entryName, url);
       }
+
       return vfh;
    }
 

Modified: projects/microcontainer/trunk/container/src/main/org/jboss/virtual/plugins/context/jar/JarEntryHandler.java
===================================================================
--- projects/microcontainer/trunk/container/src/main/org/jboss/virtual/plugins/context/jar/JarEntryHandler.java	2006-10-18 21:30:51 UTC (rev 57712)
+++ projects/microcontainer/trunk/container/src/main/org/jboss/virtual/plugins/context/jar/JarEntryHandler.java	2006-10-18 22:21:38 UTC (rev 57713)
@@ -21,17 +21,20 @@
 */
 package org.jboss.virtual.plugins.context.jar;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 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.AbstractURLHandler;
+import org.jboss.virtual.plugins.context.StructuredVirtualFileHandler;
 import org.jboss.virtual.spi.VFSContext;
 import org.jboss.virtual.spi.VirtualFileHandler;
 
@@ -39,9 +42,11 @@
  * JarEntryHandler.
  * 
  * @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
 {
    /** serialVersionUID */
    private static final long serialVersionUID = 1L;
@@ -52,6 +57,7 @@
    /** The jar entry */
    private final JarEntry entry;
    private transient List<VirtualFileHandler> entryChildren;
+   private transient Map<String, VirtualFileHandler> entryMap;
    
    /**
     * Create a new JarHandler.
@@ -64,17 +70,30 @@
     * @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, URL url) throws IOException
+   public JarEntryHandler(VFSContext context, VirtualFileHandler parent, JarFile jar,
+      JarEntry entry, String entryName, URL url)
+      throws IOException
    {
-      super(context, parent, url, AbstractJarHandler.getEntryName(entry));
+      super(context, parent, url, entryName);
       if (jar == null)
          throw new IllegalArgumentException("Null jar");
       
       this.jar = jar;
       this.entry = entry;
    }
-   
+
    /**
+    * Add a child to an entry
+    * @param child
+    */
+   public void addChild(VirtualFileHandler child)
+   {
+      if( entryChildren == null )
+         entryChildren = new ArrayList<VirtualFileHandler>();
+      entryChildren.add(child);
+   }
+
+   /**
     * Get the entry
     * 
     * @return the file
@@ -123,49 +142,29 @@
    public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
    {
       checkClosed();
+      List<VirtualFileHandler> children = entryChildren;
       if( entryChildren == null )
-         entryChildren = findChildren(jar, this);
-      return entryChildren;
+         children = Collections.emptyList();
+      return children;
    }
 
    public VirtualFileHandler findChild(String path) throws IOException
    {
-      checkClosed();
-      VirtualFileHandler handler = getParent();
-      if (handler == null)
-         throw new IOException("A JarEntry has no children: " + path + " for " + this);
-      else
-         return handler.findChild(getName() +"/" + path);
+      return super.structuredFindChild(path);
    }
 
-   /**
-    * Go through the jar entries and find the entries that are the immeadiate children of
-    * the given parent entry. This is based on the entry name being a substring of the
-    * parent name, and the number of '/' separarted paths in the name being equal to the
-    * parent paths + 1.
-    * @param jar
-    * @param parent
-    * @return
-    * @throws IOException
-    */
-   public static List<VirtualFileHandler> findChildren(JarFile jar, JarEntryHandler parent)
-      throws IOException
+   public VirtualFileHandler createChildHandler(String name) throws IOException
    {
-      ArrayList<VirtualFileHandler> children = new ArrayList<VirtualFileHandler>();
-      String parentName = parent.getEntry().getName();
-      String[] parentPaths = parentName.split("/");
-      Enumeration<JarEntry> entries = jar.entries();
-      while( entries.hasMoreElements() )
+      if( entryMap == null )
       {
-         JarEntry entry = entries.nextElement();
-         String name = entry.getName();
-         if( name.startsWith(parentName) && name.split("/").length == parentPaths.length+1 )
-         {
-            URL childURL = new URL(parent.getURL(), name.substring(parentName.length()));
-            JarEntryHandler child = new JarEntryHandler(parent.getVFSContext(), parent, parent.jar, entry, childURL);
-            children.add(child);
-         }
+         entryMap = new HashMap<String, VirtualFileHandler>();
+         for(VirtualFileHandler child : entryChildren)
+            entryMap.put(child.getName(), child);
       }
-      return children;
+      VirtualFileHandler child = entryMap.get(name);
+      if( child == null )
+         throw new FileNotFoundException(this+" has no child: "+name);
+      return child;
    }
+
 }

Modified: projects/microcontainer/trunk/container/src/tests/org/jboss/test/virtual/test/AbstractVirtualFileHandlerTest.java
===================================================================
--- projects/microcontainer/trunk/container/src/tests/org/jboss/test/virtual/test/AbstractVirtualFileHandlerTest.java	2006-10-18 21:30:51 UTC (rev 57712)
+++ projects/microcontainer/trunk/container/src/tests/org/jboss/test/virtual/test/AbstractVirtualFileHandlerTest.java	2006-10-18 22:21:38 UTC (rev 57713)
@@ -25,6 +25,7 @@
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
@@ -133,6 +134,14 @@
       assertEquals("subfolder/subsubfolder/subsubchild", child.getPathName());
       VirtualFileHandler parent = context.findChild(root, "subfolder/subsubfolder");
       List<VirtualFileHandler> children = parent.getChildren(false);
+      // Filter out an .svn stuff since this is run from the source tree
+      Iterator<VirtualFileHandler> iter = children.iterator();
+      while( iter.hasNext() )
+      {
+         child = iter.next();
+         if( child.getName().endsWith(".svn") )
+          iter.remove();
+      }
       assertEquals("subfolder/subsubfolder has one child", 1, children.size());
       child = children.get(0);
       assertEquals("subfolder/subsubfolder/subsubchild", child.getPathName());

Modified: projects/microcontainer/trunk/container/src/tests/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/container/src/tests/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2006-10-18 21:30:51 UTC (rev 57712)
+++ projects/microcontainer/trunk/container/src/tests/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2006-10-18 22:21:38 UTC (rev 57713)
@@ -316,6 +316,7 @@
       expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
       expectedClasses.add("jar2.jar/org/jboss/test/vfs/support/jar2/ClassInJar2.class");
       expectedClasses.add("org/jboss/test/vfs/support/CommonClass.class");
+      super.enableTrace("org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter");
       SuffixMatchFilter classVisitor = new SuffixMatchFilter(".class");
       List<VirtualFile> classes = vfs.getChildren(classVisitor);
       int count = 0;




More information about the jboss-cvs-commits mailing list