[jboss-cvs] JBossAS SVN: r72878 - in projects/vfs/branches/jar-alter-work/src: main/java/org/jboss/virtual/plugins/context/file and 5 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Apr 29 18:30:10 EDT 2008
Author: mstruk
Date: 2008-04-29 18:30:10 -0400 (Tue, 29 Apr 2008)
New Revision: 72878
Added:
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContextFactory.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/protocol/vfszip/
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/protocol/vfszip/Handler.java
projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryHandlerUnitTestCase.java
projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java
Modified:
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/spi/VFSContext.java
Log:
Alternative implementation of jar vfs - initial commit
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java 2008-04-29 22:26:48 UTC (rev 72877)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -59,6 +59,9 @@
/** Options associated with the root URL */
private Map<String, String> rootOptions;
+ /** Root's peer within another context */
+ private VirtualFileHandler rootPeer;
+
/**
* Create a new AbstractVFSContext.
*
@@ -98,6 +101,16 @@
return rootURI;
}
+ public void setRootPeer(VirtualFileHandler handler)
+ {
+ this.rootPeer = handler;
+ }
+
+ public VirtualFileHandler getRootPeer()
+ {
+ return rootPeer;
+ }
+
protected void addOption(String key, String value)
{
rootOptions.put(key, value);
@@ -124,6 +137,30 @@
return parent.getChild(path);
}
+ public URL getChildURL(VirtualFileHandler parent, String name) throws IOException
+ {
+ StringBuilder urlStr = new StringBuilder(256);
+ urlStr.append(getRootURI().toString());
+ if(parent != null)
+ {
+ String pPathName = null;
+ if(parent instanceof AbstractVirtualFileHandler)
+ pPathName = ((AbstractVirtualFileHandler)parent).getLocalPathName();
+ else
+ pPathName = parent.getPathName();
+
+ if(pPathName.length() != 0)
+ urlStr.append("/").append(pPathName);
+
+ if (urlStr.charAt( urlStr.length()-1) != '/')
+ urlStr.append("/");
+
+ urlStr.append(name);
+ }
+
+ return new URL(urlStr.toString());
+ }
+
public void visit(VirtualFileHandler handler, VirtualFileHandlerVisitor visitor) throws IOException
{
if (handler == null)
@@ -204,7 +241,10 @@
{
try
{
- visit(child, visitor, false, leavesOnly, ignoreErrors, includeHidden, recurseFilter);
+ if (handler instanceof DelegatingHandler)
+ child.getVFSContext().visit(child, visitor);
+ else
+ visit(child, visitor, false, leavesOnly, ignoreErrors, includeHidden, recurseFilter);
}
catch (StackOverflowError e)
{
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java 2008-04-29 22:26:48 UTC (rev 72877)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVirtualFileHandler.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -109,6 +109,7 @@
this.context = context;
this.parent = parent;
this.name = VFSUtils.fixName(name);
+ this.vfsPath = null; // nullify possible invalid vfsPath initializations when running with debugger
}
/**
@@ -200,6 +201,29 @@
this.vfsPath = path;
}
+ public String getLocalPathName()
+ {
+ try
+ {
+ VirtualFileHandler handler = getVFSContext().getRoot();
+ String rootPathName = handler.getPathName();
+ String pathName = getPathName();
+ int len = rootPathName.length();
+ if (len == 0)
+ return pathName;
+ else if (rootPathName.length() < pathName.length())
+ return pathName.substring(rootPathName.length() + 1);
+ else
+ return "";
+ }
+ catch (IOException ex)
+ {
+ log.warn("Failed to compose local path name: context: " + getVFSContext() + ", name: " + getName(), ex);
+ }
+
+ return getPathName();
+ }
+
public URL toURL() throws MalformedURLException, URISyntaxException
{
return toURI().toURL();
@@ -238,6 +262,10 @@
*/
private boolean initPath(StringBuilder pathName)
{
+ if (context.getRootPeer() != null)
+ if (initPeerPath(pathName))
+ return true;
+
if (parent != null)
{
if (parent instanceof AbstractVirtualFileHandler)
@@ -255,7 +283,56 @@
}
return false;
}
-
+
+
+ private boolean initPeerPath(StringBuilder pathName)
+ {
+ VirtualFileHandler grandParent = null;
+
+ if (parent != null)
+ {
+ try
+ {
+ grandParent = parent.getParent();
+ }
+ catch(IOException ex)
+ {
+ // if we throw exception here we'll most likely cause an infinite recursion
+ log.warn("AbstractVirtualFileHandler.initPath failed: ctx: " + context
+ + ", parent: " + parent + " name: " + name, ex);
+ }
+ }
+
+ VirtualFileHandler peer = context.getRootPeer();
+
+
+ if (grandParent == null)
+ {
+ // bypass parent and delegate straight to peer
+
+ if (peer instanceof AbstractVirtualFileHandler)
+ {
+ AbstractVirtualFileHandler handler = (AbstractVirtualFileHandler) peer;
+ if (handler.initPath(pathName) && parent != null)
+ pathName.append('/');
+ }
+ else
+ {
+ pathName.append(peer.getPathName());
+ }
+
+ if (parent != null)
+ {
+ // if it's a root node we skip adding '/' and a name
+ pathName.append(getName());
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
public VirtualFile getVirtualFile()
{
checkClosed();
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java 2008-04-29 22:26:48 UTC (rev 72877)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/DelegatingHandler.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -50,6 +50,18 @@
private VirtualFileHandler delegate;
/**
+ * Create a DelegatingHandler without a delegate - which will have to be set afterwards
+ *
+ * @param context - the context for the parent
+ * @param parent - the parent of the delegate in this VFS
+ * @param name - the name of the delegate in this VFS
+ */
+ public DelegatingHandler(VFSContext context, VirtualFileHandler parent, String name)
+ {
+ this(context, parent, name, null);
+ }
+
+ /**
* Create a DelegatingHandler
*
* @param context - the context for the parent
@@ -60,11 +72,21 @@
public DelegatingHandler(VFSContext context, VirtualFileHandler parent, String name, VirtualFileHandler delegate)
{
super(context, parent, name);
- if (delegate == null)
- throw new IllegalArgumentException("Null delegate");
+ //if (delegate == null)
+ // throw new IllegalArgumentException("Null delegate");
this.delegate = delegate;
}
+ public void setDelegate(VirtualFileHandler handler)
+ {
+ this.delegate = handler;
+ }
+
+ public VirtualFileHandler getDelegate()
+ {
+ return delegate;
+ }
+
public VirtualFileHandler getChild(String path) throws IOException
{
return delegate.getChild(path);
@@ -119,4 +141,9 @@
{
delegate.replaceChild(original, replacement);
}
+
+ public URL toVfsUrl() throws MalformedURLException, URISyntaxException
+ {
+ return delegate.toVfsUrl();
+ }
}
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java 2008-04-29 22:26:48 UTC (rev 72877)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -33,7 +33,8 @@
import org.jboss.virtual.VFSUtils;
import org.jboss.virtual.VirtualFile;
import org.jboss.virtual.plugins.context.AbstractVFSContext;
-import org.jboss.virtual.plugins.context.jar.JarHandler;
+import org.jboss.virtual.plugins.context.DelegatingHandler;
+import org.jboss.virtual.plugins.context.zip.ZipEntryContext;
import org.jboss.virtual.plugins.context.jar.JarUtils;
import org.jboss.virtual.spi.LinkInfo;
import org.jboss.virtual.spi.VirtualFileHandler;
@@ -190,9 +191,11 @@
{
try
{
- return new JarHandler(this, parent, file, file.toURL(), name);
+ //return new JarHandler(this, parent, file, file.toURL(), name);
+ DelegatingHandler delegator = mountZipFS(parent, name, file);
+ return delegator;
}
- catch (IOException e)
+ catch (Exception e)
{
log.debug("Exception while trying to handle file (" + name + ") as a jar: " + e.getMessage());
}
@@ -200,6 +203,23 @@
return createVirtualFileHandler(parent, file, getFileURI(file));
}
+ protected DelegatingHandler mountZipFS(VirtualFileHandler parent, String name, File file) throws IOException, URISyntaxException
+ {
+ DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
+ URL fileUrl = file.toURL();
+ URL delegatorUrl = fileUrl;
+
+ if (parent != null)
+ delegatorUrl = getChildURL(parent, name);
+
+ ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, fileUrl);
+
+ VirtualFileHandler handler = ctx.getRoot();
+ delegator.setDelegate(handler);
+
+ return delegator;
+ }
+
/**
* Create a new virtual file handler
*
Added: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -0,0 +1,639 @@
+package org.jboss.virtual.plugins.context.zip;
+
+import org.jboss.virtual.plugins.context.AbstractVFSContext;
+import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler;
+import org.jboss.virtual.plugins.context.DelegatingHandler;
+import org.jboss.virtual.plugins.context.jar.JarUtils;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * VFSContext exposing a zip archive file as a virtual file system
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+
+public class ZipEntryContext extends AbstractVFSContext
+{
+ static
+ {
+ deleteTmpDirContents();
+ }
+
+ /** File representing a zip archive that is virtualized with this context */
+ private File rootFile;
+
+ /** ZipFile opened around rootFile */
+ private ZipFileWrapper zipFile;
+
+ /** Entry path representing a context root */
+ private String rootEntryPath = "";
+
+ /** Auto clean signals if rootFile should be deleted after closing the context */
+ private boolean autoClean = false;
+
+ /** Entries in a hierarchy */
+ private ConcurrentHashMap<String, EntryInfo> entries = new ConcurrentHashMap<String, EntryInfo>();
+
+ /**
+ * Create a new ZipEntryContext
+ *
+ * @param rootURL - file or jar:file url
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+ public ZipEntryContext(URL rootURL) throws URISyntaxException, IOException
+ {
+ this(rootURL, false);
+ }
+
+ /**
+ * Create a new ZipEntryContext
+ *
+ * @param rootURL - file or jar:file url
+ * @param autoClean - true if file represented by rootURL should be deleted after this context is closed
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+ public ZipEntryContext(URL rootURL, boolean autoClean) throws URISyntaxException, IOException
+ {
+ super(fixUrl(rootURL));
+ this.autoClean = autoClean;
+ init(rootURL, null);
+ }
+
+ /**
+ * Create a new ZipEntryContext being mounted into another context
+ *
+ * @param rootURL - url representing this context within another context
+ * @param peer - file handler in another context through which this context is being mounted
+ * @param localRootUrl - file or jar:file url
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+ public ZipEntryContext(URL rootURL, VirtualFileHandler peer, URL localRootUrl) throws URISyntaxException, IOException
+ {
+ this(rootURL, peer, localRootUrl, false);
+ }
+
+ /**
+ * Create a new ZipEntryContext being mounted into another context
+ *
+ * @param rootURL - url representing this context within another context
+ * @param peer - file handler in another context through which this context is being mounted
+ * @param localRootUrl - file or jar:file url
+ * @param autoClean - true if file represented by localRootURL should be deleted after this context is closed
+ * @throws URISyntaxException
+ * @throws IOException
+ */
+ public ZipEntryContext(URL rootURL, VirtualFileHandler peer, URL localRootUrl, boolean autoClean) throws URISyntaxException, IOException
+ {
+ super(fixUrl(rootURL));
+ this.autoClean = autoClean;
+ init(localRootUrl, peer);
+ }
+
+ private void init(URL localRootURL, VirtualFileHandler peer) throws IOException, URISyntaxException
+ {
+ initFileAndPath(localRootURL);
+
+ if(!rootFile.isFile())
+ throw new RuntimeException("File not found: " + rootFile);
+
+ //try
+ //{
+ zipFile = new ZipFileWrapper(rootFile);
+ //}
+ //catch(Exception ex)
+ //{
+ // throw new RuntimeException("Failed to open the file as zip: " + rootFile, ex);
+ //}
+
+ setRootPeer(peer);
+
+ String name = getRootURI().toString(); // rootFile.getName()
+ int toPos = name.length();
+ if(name.length() != 0 && name.charAt(name.length()-1) == '/')
+ toPos --;
+
+ int namePos = name.lastIndexOf("/", toPos-1);
+ name = name.substring(namePos+1, toPos);
+
+ if(name.length() != 0 && name.charAt(name.length()-1) == '!')
+ name = name.substring(0, name.length()-1);
+
+ // init initial root that will be overwritten if it exists as ZipEntry
+ entries.put("", new EntryInfo(new ZipEntryHandler(this, null, name), null));
+
+ initEntries();
+
+ ZipEntryContextFactory.registerContext(this);
+ }
+
+ public String getName()
+ {
+ VirtualFileHandler peer = getRootPeer();
+ if (peer != null)
+ return peer.getName();
+ else
+ return rootFile.getName();
+ }
+
+
+/*
+ public URL getChildURL(AbstractVirtualFileHandler parent, String name) {
+ try
+ {
+ // --
+ StringBuilder url = new StringBuilder();
+ VirtualFileHandler peer = getRootPeer();
+ if (peer != null)
+ {
+ VFSContext peerCtx = peer.getVFSContext();
+ if (peerCtx instanceof AbstractVFSContext)
+
+ url.append( ((AbstractVirtualFileHandler) peer).getGlobalChildURI() );
+ }
+ String parentPath = parent.getLocalPathName();
+ url.append(parentPath);
+ if(!"".equals(parentPath))
+ url.append("/");
+ url.append(name);
+ // --
+
+ StringBuilder urlStr = new StringBuilder(250);
+ urlStr.append(getRootURI().toString());
+ if(parent != null)
+ {
+ String pPathName = parent.getLocalPathName();
+ if(pPathName.length() != 0)
+ urlStr.append("/").append(pPathName);
+
+ urlStr.append("/").append(name);
+ }
+
+ return new URL(urlStr.toString());
+ }
+ catch(Exception ex)
+ {
+ throw new IllegalArgumentException("Name could not be converted to URL: " + name, ex);
+ }
+ }
+*/
+
+ private synchronized void initEntries() throws IOException, URISyntaxException
+ {
+
+ // we're using a two phase approach - we first select the relevant ones
+ // then we order these by name and only then we process them
+ // this way we ensure that parent entries are processed before child entries
+
+ HashMap<String, ZipEntry> relevant = new HashMap<String, ZipEntry>();
+ ZipFile zFile = zipFile.acquire();
+ try
+ {
+ Enumeration<? extends ZipEntry> zipEntries = zFile.entries();
+ while(zipEntries.hasMoreElements())
+ {
+ ZipEntry ent = zipEntries.nextElement();
+ if(ent.getName().startsWith(rootEntryPath))
+ {
+ relevant.put(ent.getName(), ent);
+ }
+ }
+
+ TreeMap<String, ZipEntry> orderedRelevant = new TreeMap<String, ZipEntry>(relevant);
+
+ for(Map.Entry<String, ZipEntry> entry : orderedRelevant.entrySet())
+ {
+ ZipEntry ent = entry.getValue();
+ String fullName = ent.getName().substring(rootEntryPath.length());
+
+ String [] split = splitParentChild(fullName);
+ String parentPath = split[0];
+ String name = split[1];
+
+ EntryInfo ei = entries.get(parentPath);
+ if(ei == null)
+ ei = makeDummyParent(parentPath);
+
+ AbstractVirtualFileHandler parent = ei != null ? ei.handler : null;
+
+ if(!ent.isDirectory() && JarUtils.isArchive(ent.getName()))
+ {
+ // extract it to temp dir
+ File dest = new File(getTempDir() + "/" + getTempFileName(ent.getName()));
+ dest.getParentFile().mkdirs(); // ensure parent exists
+ InputStream is = zipFile.openStream(ent);
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
+ copyStreamAndClose(is, os);
+
+ // mount FS
+ DelegatingHandler delegator = mountZipFS(parent, name, dest);
+
+ entries.put(delegator.getLocalPathName(), new EntryInfo(delegator, ent));
+ addChild(parent, delegator);
+ }
+ else
+ {
+ ZipEntryHandler wrapper = new ZipEntryHandler(this, parent, name);
+ entries.put(wrapper.getLocalPathName(), new EntryInfo(wrapper, ent));
+ }
+
+ }
+ }
+ finally
+ {
+ zipFile.release();
+ }
+
+ }
+
+ protected DelegatingHandler mountZipFS(VirtualFileHandler parent, String name, File file) throws IOException, URISyntaxException
+ {
+ DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
+ URL fileUrl = file.toURL();
+ URL delegatorUrl = fileUrl;
+
+ if (parent != null)
+ delegatorUrl = getChildURL(parent, name);
+ //delegatorUrl = new URL(VFSUtils.getChildURLString(parent.toURL(), name));
+
+
+ ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, fileUrl, true);
+
+ VirtualFileHandler handler = ctx.getRoot();
+ delegator.setDelegate(handler);
+
+ return delegator;
+ }
+
+ private EntryInfo makeDummyParent(String parentPath) throws IOException
+ {
+ // get grand parent first
+ String [] split = splitParentChild(parentPath);
+ String grandPa = split[0];
+
+ EntryInfo eiParent = entries.get(grandPa);
+ if(eiParent == null)
+ eiParent = makeDummyParent(grandPa);
+
+ ZipEntryHandler handler = new ZipEntryHandler(this, eiParent.handler, split[1]);
+ EntryInfo ei = new EntryInfo(handler, null);
+ entries.put(parentPath, ei);
+ return ei;
+ }
+
+ private void initFileAndPath(URL localRootUrl)
+ {
+ String filePath = localRootUrl.toString();
+ String zipPath = filePath;
+
+ int pos = filePath.indexOf("!");
+ if(pos > 0)
+ {
+ zipPath = filePath.substring(0, pos);
+ rootEntryPath = filePath.substring(pos+2);
+ if(rootEntryPath.length() != 0)
+ rootEntryPath += "/";
+ }
+
+ try
+ {
+ // find where schema ends - all schemas when you have wrapping ...
+ pos= zipPath.indexOf(":/");
+ filePath = "file:" + zipPath.substring(pos+1);
+ rootFile = new File(new URI(filePath));
+ if (autoClean)
+ rootFile.deleteOnExit();
+ }
+ catch(Exception ex)
+ {
+ throw new RuntimeException("ASSERTION ERROR - Could not create URI: " + filePath, ex);
+ }
+ }
+
+ public VirtualFileHandler getRoot() throws IOException
+ {
+ return entries.get("").handler;
+ }
+
+ private synchronized void checkIfModified()
+ {
+ // our rootFile may be a derivative - the extracted insides of another archive
+ // if RootContextInfo is available - delegate to it
+ // otherwise work on the file directly
+ if (zipFile.hasBeenModified())
+ {
+ EntryInfo rootInfo = entries.get("");
+ entries = new ConcurrentHashMap<String, EntryInfo>();
+ entries.put("", rootInfo);
+
+ if (zipFile.exists())
+ {
+ try
+ {
+ initEntries();
+ }
+ catch(Exception ex)
+ {
+ log.warn("Failed to reinitialize context: " + getRootURI());
+ }
+ }
+ }
+
+ }
+
+ public VirtualFileHandler getChild(ZipEntryHandler parent, String name)
+ {
+ checkIfModified();
+ String pathName = parent.getLocalPathName();
+ if("".equals(pathName))
+ pathName = name;
+ else
+ pathName = pathName + "/" + name;
+
+ EntryInfo ei = entries.get(pathName);
+
+ if(ei != null)
+ return ei.handler;
+
+ return null;
+ }
+
+
+ public List<VirtualFileHandler> getChildren(VirtualFileHandler parent, boolean ignoreErrors) throws IOException
+ {
+ checkIfModified();
+ if(parent instanceof AbstractVirtualFileHandler)
+ {
+ AbstractVirtualFileHandler parentHandler = (AbstractVirtualFileHandler) parent;
+ EntryInfo parentEntry = entries.get(parentHandler.getLocalPathName());
+ if (parentEntry != null)
+ {
+ if (parentEntry.handler instanceof DelegatingHandler)
+ return parentEntry.handler.getChildren(ignoreErrors);
+
+ List<AbstractVirtualFileHandler> children = parentEntry.getChildren();
+ return Collections.unmodifiableList(new LinkedList<VirtualFileHandler>(children));
+ }
+ }
+ return Collections.emptyList();
+ }
+
+
+ public long getLastModified(ZipEntryHandler handler)
+ {
+ checkIfModified();
+ EntryInfo ei = entries.get(handler.getLocalPathName());
+ if(ei == null)
+ return 0;
+
+ if(ei.entry == null) {
+ return rootFile.lastModified();
+ }
+
+ return ei.entry.getTime();
+ }
+
+ public long getSize(ZipEntryHandler handler)
+ {
+ checkIfModified();
+ String pathName = handler.getLocalPathName();
+ EntryInfo ei = entries.get(pathName);
+ if(ei == null)
+ return 0;
+
+ if(ei.entry == null)
+ {
+ if(pathName.length() == 0)
+ return rootFile.length();
+ else
+ return 0;
+ }
+
+ return ei.entry.getSize();
+ }
+
+ public boolean exists(ZipEntryHandler handler)
+ {
+ checkIfModified();
+ EntryInfo ei = entries.get(handler.getLocalPathName());
+ if(ei == null)
+ return false;
+
+ return true;
+ }
+
+ public boolean isLeaf(ZipEntryHandler handler)
+ {
+ checkIfModified();
+ EntryInfo ei = entries.get(handler.getLocalPathName());
+ if(ei == null || ei.entry == null)
+ return false;
+
+ return !ei.entry.isDirectory();
+ }
+
+ public InputStream openStream(ZipEntryHandler handler) throws IOException
+ {
+ checkIfModified();
+ EntryInfo ei = entries.get(handler.getLocalPathName());
+
+ if (ei == null)
+ {
+ String uriStr = "";
+ try
+ {
+ uriStr = handler.toURI().toString();
+ }
+ catch(Exception ex)
+ {
+ throw new RuntimeException("ASSERTION ERROR - uri generation failed for ZipEntryHandler: " + handler);
+ }
+ throw new FileNotFoundException(uriStr);
+
+ }
+
+ if(ei.entry == null)
+ {
+ return new FileInputStream(rootFile);
+ }
+
+ return zipFile.openStream(ei.entry);
+ }
+
+ public void addChild(AbstractVirtualFileHandler parent, AbstractVirtualFileHandler child)
+ {
+ EntryInfo parentEntry = entries.get(parent.getLocalPathName());
+ if (parentEntry != null)
+ parentEntry.getChildren().add(child);
+ else throw new RuntimeException("Parent does not exist: " + parent);
+ }
+
+
+
+ protected void finalize()
+ {
+ try
+ {
+ zipFile.close();
+ if (autoClean)
+ rootFile.delete();
+ }
+ catch (Exception ex)
+ {
+ // ignore
+ }
+ }
+
+
+ /**
+ * Internal data structure, holding ZipEntries and child handlers for every handler in this context
+ */
+ static class EntryInfo
+ {
+ AbstractVirtualFileHandler handler;
+ ZipEntry entry;
+ List<AbstractVirtualFileHandler> children;
+
+ EntryInfo(AbstractVirtualFileHandler handler, ZipEntry entry)
+ {
+ this.handler = handler;
+ this.entry = entry;
+ }
+
+ public synchronized List<AbstractVirtualFileHandler> getChildren()
+ {
+ if (children == null)
+ children = new LinkedList<AbstractVirtualFileHandler>();
+
+ return children;
+ }
+ }
+
+
+ //
+ // Helper methods
+ //
+
+ private static URL fixUrl(URL rootURL) throws MalformedURLException
+ {
+ if (!"vfszip".equals(rootURL.getProtocol()))
+ {
+ String url = rootURL.toString();
+ int pos = url.indexOf(":/");
+ if (pos != -1)
+ url = url.substring(pos);
+
+ return new URL("vfszip" + url);
+ }
+ return rootURL;
+ }
+
+ public static String [] splitParentChild(String pathName)
+ {
+ if(pathName.length() == 0)
+ return new String [] {null, pathName};
+
+ int toPos = pathName.length();
+ if(pathName.charAt(pathName.length()-1) == '/')
+ toPos --;
+
+ int delimPos = pathName.lastIndexOf('/', toPos-1);
+
+ String [] ret;
+ if(delimPos == -1)
+ {
+ ret = new String []
+ {
+ "",
+ pathName.substring(delimPos+1, toPos)
+ };
+ }
+ else
+ {
+ ret = new String []
+ {
+ pathName.substring(0, delimPos),
+ pathName.substring(delimPos+1, toPos)
+ };
+ }
+ return ret;
+ }
+
+ private static void copyStreamAndClose(InputStream is, OutputStream os) throws IOException
+ {
+ try
+ {
+ byte [] buff = new byte[65536];
+ int count = is.read(buff);
+ while(count != -1)
+ {
+ os.write(buff, 0, count);
+ count = is.read(buff);
+ }
+ }
+ finally
+ {
+ if(is != null)
+ {
+ try {
+ is.close();
+ }
+ catch(Exception ex)
+ {
+ // ignore
+ }
+ }
+ os.close();
+ }
+ }
+
+
+ // TODO: the following two methods are a quick and dirty strategy for temp file name and path
+ private static String getTempFileName(String name)
+ {
+ int delim = name.lastIndexOf("/");
+ if (delim != -1)
+ name = name.substring(delim+1);
+ return UUID.randomUUID().toString() + "_" + name;
+ }
+
+ private static String getTempDir()
+ {
+ File dir = new File(System.getProperty("jboss.server.temp.dir"), "vfs");
+ //dir.mkdirs();
+ return dir.toString();
+ }
+
+ private static void deleteTmpDirContents()
+ {
+ try
+ {
+ File tmpDir = new File(getTempDir());
+ File [] files = tmpDir.listFiles();
+ for (File file: files)
+ {
+ if (!file.isDirectory() && !file.isHidden())
+ file.delete();
+ }
+ }
+ catch(Exception ex)
+ {
+ // ignore
+ }
+
+ }
+
+}
Added: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContextFactory.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContextFactory.java (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContextFactory.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -0,0 +1,97 @@
+package org.jboss.virtual.plugins.context.zip;
+
+import org.jboss.virtual.plugins.context.AbstractContextFactory;
+import org.jboss.virtual.spi.VFSContext;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * ContextFactory that keeps track of ZipEntryContexts
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+
+public class ZipEntryContextFactory extends AbstractContextFactory
+{
+
+ public static Map<String, ZipEntryContext> ctxCache = new ConcurrentHashMap<String, ZipEntryContext>();
+
+ private static ZipEntryContextFactory instance = new ZipEntryContextFactory();
+
+ public ZipEntryContextFactory()
+ {
+ super("jar", "vfsjar", "zip", "vfszip");
+ }
+
+ public VFSContext getVFS(URI rootURI) throws IOException
+ {
+ return getVFS(rootURI.toURL());
+ }
+
+ public VFSContext getVFS(URL rootURL) throws IOException
+ {
+ String key = rootURL.toString();
+ int cutPos = key.indexOf(":/");
+ key = key.substring(cutPos+1);
+
+ String longestMatchingKey = null;
+ ZipEntryContext longestMatchingCtx = null;
+
+ for(Map.Entry<String, ZipEntryContext> ent : ctxCache.entrySet())
+ {
+ if(key.startsWith(ent.getKey()))
+ {
+ if(longestMatchingCtx == null || ent.getKey().length() > longestMatchingKey.length())
+ {
+ longestMatchingKey = ent.getKey();
+ longestMatchingCtx = ent.getValue();
+ }
+ }
+ }
+
+ ZipEntryContext ctx = null;
+ if(longestMatchingCtx != null)
+ ctx = longestMatchingCtx;
+
+ if(ctx != null)
+ return ctx;
+
+ try
+ {
+ ctx = new ZipEntryContext(rootURL);
+ }
+ catch(URISyntaxException ex)
+ {
+ MalformedURLException e = new MalformedURLException("Failed to convert URL to URI: " + rootURL);
+ e.initCause(ex);
+ throw e;
+ }
+
+ // no need to put a newly created context into ctxCache
+ // it's constructor does that by calling registerContext
+
+ return ctx;
+ }
+
+ public static ZipEntryContextFactory getInstance()
+ {
+ return instance;
+ }
+
+ public static void registerContext(ZipEntryContext ctx)
+ {
+ String key = ctx.getRootURI().toString();
+ int cutPos = key.indexOf(":/");
+ key = key.substring(cutPos+1);
+ if("".equals(key))
+ throw new RuntimeException("Derived key for ZipEntryContext registration is empty: " + ctx.getRootURI());
+ ctxCache.put(key, ctx);
+ }
+}
Added: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -0,0 +1,122 @@
+package org.jboss.virtual.plugins.context.zip;
+
+import org.jboss.virtual.VFSUtils;
+import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler;
+import org.jboss.virtual.plugins.context.StructuredVirtualFileHandler;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
+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.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Handler representing an individual file (ZipEntry) within ZipEntryContext
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+
+public class ZipEntryHandler extends AbstractVirtualFileHandler implements StructuredVirtualFileHandler
+{
+
+ /** The url */
+ private final URL url;
+
+
+ /**
+ * Create a new ZipEntryHandler.
+ *
+ * @param context ZipEntryContext
+ * @param parent parent within the same context
+ * @param name name of this file within context
+ */
+ public ZipEntryHandler(ZipEntryContext context, AbstractVirtualFileHandler parent, String name) throws IOException
+ {
+ super(context, parent, name);
+
+ url = context.getChildURL(parent, name);
+
+ String vfsUrl = url.toString();
+ int pos = vfsUrl.indexOf(":/");
+ vfsUrl = "vfszip:" + vfsUrl.substring(pos+1);
+ try
+ {
+ setVfsUrl(new URL(vfsUrl));
+ }
+ catch(MalformedURLException ex)
+ {
+ throw new RuntimeException("ASSERTION ERROR - failed to set vfsUrl: " + vfsUrl, ex );
+ }
+
+ if(parent != null)
+ {
+ context.addChild(parent, this);
+ }
+ }
+
+ public URI toURI() throws URISyntaxException
+ {
+ return VFSUtils.toURI(url);
+ }
+
+ public long getLastModified() throws IOException
+ {
+ return getZipEntryContext().getLastModified(this);
+ }
+
+ public long getSize() throws IOException
+ {
+ return getZipEntryContext().getSize(this);
+ }
+
+ public boolean exists() throws IOException
+ {
+ return getZipEntryContext().exists(this);
+ }
+
+ public boolean isLeaf() throws IOException
+ {
+ return getZipEntryContext().isLeaf(this);
+ }
+
+ public boolean isHidden() throws IOException
+ {
+ return false;
+ }
+
+ public InputStream openStream() throws IOException
+ {
+ return getZipEntryContext().openStream(this);
+ }
+
+ public List<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
+ {
+ return getZipEntryContext().getChildren(this, ignoreErrors);
+
+ }
+
+ public VirtualFileHandler getChild(String path) throws IOException
+ {
+ return structuredFindChild(path);
+ }
+
+
+ public VirtualFileHandler createChildHandler(String name) throws IOException
+ {
+ return getZipEntryContext().getChild(this, name);
+ }
+
+ private ZipEntryContext getZipEntryContext()
+ {
+ return ((ZipEntryContext) getVFSContext());
+ }
+
+
+}
Added: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -0,0 +1,143 @@
+package org.jboss.virtual.plugins.context.zip;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+
+/**
+ * InputStream that wraps an InputStream retrieved from ZipFile.getInputStream(entry)
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+
+public class ZipEntryInputStream extends InputStream
+{
+ private InputStream delegate;
+
+ private ZipFileWrapper zipWrapper;
+
+ private boolean closed;
+
+ ZipEntryInputStream(ZipFileWrapper zipWrapper, InputStream is) throws IOException
+ {
+ this.zipWrapper = zipWrapper;
+ delegate = is;
+ }
+
+ private void streamClosed(boolean doClose)
+ {
+ if (closed == false && doClose)
+ {
+ closed = true;
+ zipWrapper.release();
+ }
+ }
+
+ public int read() throws IOException
+ {
+ int rc = -1;
+ try
+ {
+ rc = delegate.read();
+ return rc;
+ }
+ finally
+ {
+ streamClosed(rc < 0);
+ }
+ }
+
+ public int read(byte buf[]) throws IOException
+ {
+ int rc = -1;
+ try
+ {
+ rc = delegate.read(buf);
+ return rc;
+ }
+ finally
+ {
+ streamClosed(rc < 0);
+ }
+ }
+
+ public int read(byte buf[], int off, int len) throws IOException
+ {
+ int rc = -1;
+ try
+ {
+ rc = delegate.read(buf, off, len);
+ return rc;
+ }
+ finally
+ {
+ streamClosed(rc < 0);
+ }
+ }
+
+ public synchronized void reset() throws IOException
+ {
+ boolean ok = false;
+ try
+ {
+ delegate.reset();
+ ok = true;
+ }
+ finally
+ {
+ streamClosed(ok == false);
+ }
+ }
+
+ public synchronized void mark(int readlimit)
+ {
+ boolean ok = false;
+ try
+ {
+ delegate.mark(readlimit);
+ ok = true;
+ }
+ finally
+ {
+ streamClosed(ok == false);
+ }
+ }
+
+ public int available() throws IOException
+ {
+ boolean ok = false;
+ try
+ {
+ int ret = delegate.available();
+ ok = true;
+ return ret;
+ }
+ finally
+ {
+ streamClosed(ok == false);
+ }
+ }
+
+ public long skip(long n) throws IOException
+ {
+ boolean ok = false;
+ try
+ {
+ long ret = delegate.skip(n);
+ ok = true;
+ return ret;
+ }
+ finally
+ {
+ streamClosed(ok == false);
+ }
+ }
+
+ public void close() throws IOException
+ {
+ streamClosed(true);
+ super.close();
+ }
+
+}
Added: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -0,0 +1,125 @@
+package org.jboss.virtual.plugins.context.zip;
+
+import org.jboss.logging.Logger;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+/**
+ * ZipFileWrapper releases and reacquires an underlying ZipFile as necessary
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+
+public class ZipFileWrapper
+{
+ private static final Logger log = Logger.getLogger(ZipFileWrapper.class);
+
+ private File file;
+
+ private ZipFile zipFile;
+
+ private long lastUsed;
+
+ private long lastModified;
+
+ private long lastChecked;
+
+ private int refCount = 0;
+
+ public ZipFileWrapper(File archive)
+ {
+ file = archive;
+ lastModified = file.lastModified();
+ }
+
+ boolean hasBeenModified()
+ {
+ long now = System.currentTimeMillis();
+ if (now - lastChecked < 1000)
+ return false;
+
+ lastChecked = now;
+ long lm = file.lastModified();
+ if (lm != lastModified)
+ {
+ lastModified = lm;
+ return true;
+ }
+
+ return false;
+ }
+
+ boolean exists()
+ {
+ return file.isFile();
+ }
+
+ private ZipFile ensureZipFile() throws IOException
+ {
+ if (zipFile == null)
+ zipFile = new ZipFile(file);
+
+ return zipFile;
+ }
+
+ private void closeZipFile() throws IOException
+ {
+ if (zipFile != null)
+ {
+ ZipFile zf = zipFile;
+ zipFile = null;
+ zf.close();
+ }
+ }
+
+ synchronized ZipEntryInputStream openStream(ZipEntry ent) throws IOException
+ {
+ ensureZipFile();
+ InputStream is = zipFile.getInputStream(ent);
+ ZipEntryInputStream zis = new ZipEntryInputStream(this, is);
+ refCount++;
+ lastUsed = System.currentTimeMillis();
+ return zis;
+ }
+
+
+ synchronized void release()
+ {
+ refCount--;
+ if (refCount <= 0)
+ {
+ try
+ {
+ lastUsed = System.currentTimeMillis();
+ closeZipFile();
+ }
+ catch(Exception ex)
+ {
+ log.warn("Failed to release file: " + file);
+ }
+ }
+ }
+
+ synchronized ZipFile acquire() throws IOException
+ {
+ ZipFile ret = ensureZipFile();
+ refCount++;
+ return ret;
+ }
+
+ void close()
+ {
+ try
+ {
+ closeZipFile();
+ }
+ catch(Exception ex)
+ {
+ log.warn("Failed to release file: " + file);
+ }
+ }
+}
Added: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/protocol/vfszip/Handler.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/protocol/vfszip/Handler.java (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/protocol/vfszip/Handler.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -0,0 +1,37 @@
+package org.jboss.virtual.protocol.vfszip;
+
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.plugins.context.zip.ZipEntryContext;
+import org.jboss.virtual.plugins.context.zip.ZipEntryContextFactory;
+import org.jboss.virtual.plugins.vfs.VirtualFileURLConnection;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+/**
+ * URLStreamHandler for VFS
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+
+public class Handler extends URLStreamHandler
+{
+ protected URLConnection openConnection(URL u) throws IOException
+ {
+ String url = u.toString();
+ ZipEntryContext ctx = (ZipEntryContext) ZipEntryContextFactory.getInstance().getVFS(u);
+ if (ctx == null)
+ throw new IOException("vfs does not exist: " + url);
+
+ String rootPath = ctx.getRootURI().getPath();
+ String entryPath = u.getFile().substring(rootPath.length());
+ VirtualFile vf = ctx.getChild(ctx.getRoot(), entryPath).getVirtualFile();
+ if (vf == null)
+ throw new IOException("vfs does not exist: " + url);
+
+ return new VirtualFileURLConnection(u, vf);
+ }
+}
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/spi/VFSContext.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/spi/VFSContext.java 2008-04-29 22:26:48 UTC (rev 72877)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/spi/VFSContext.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -68,6 +68,14 @@
VirtualFileHandler getRoot() throws IOException;
/**
+ * Return the peer representing the root of this context within another context.
+ * Used when mounting contexts within other contexts
+ *
+ * @return the root peer
+ */
+ VirtualFileHandler getRootPeer();
+
+ /**
* Get the context option settings
*
* @return a map of the context options
Added: projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryHandlerUnitTestCase.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryHandlerUnitTestCase.java (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryHandlerUnitTestCase.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -0,0 +1,183 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.virtual.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.plugins.context.jar.JarUtils;
+import org.jboss.virtual.plugins.context.zip.ZipEntryContext;
+import org.jboss.virtual.spi.VFSContext;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.util.jar.*;
+
+/**
+ * JARVirtualFileHandlerUnitTestCase.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ZipEntryHandlerUnitTestCase extends AbstractVirtualFileHandlerTest
+{
+ public ZipEntryHandlerUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ return new TestSuite(ZipEntryHandlerUnitTestCase.class);
+ }
+
+
+
+ /*
+ public void testJarCache() throws Exception
+ {
+ // Create a test.jar with v1 in manifest
+ File testFile = new File("test.jar");
+ {
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1");
+ manifest.getMainAttributes().putValue("test", "v1");
+ JarOutputStream out = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(testFile)), manifest);
+ out.flush();
+ out.close();
+ }
+
+ // Verify it via VFS
+ File root = new File(".");
+ {
+ VirtualFile vf = VFS.getVirtualFile(root.toURL(), "test.jar");
+// System.err.println("lastModified = " + vf.getLastModified());
+ VirtualFile manifestFile = vf.findChild("META-INF/MANIFEST.MF");
+ Manifest manifest = new Manifest(manifestFile.openStream());
+ String actual = manifest.getMainAttributes().getValue("test");
+ assertEquals("v1", actual);
+ }
+
+ // If we don't delete, VFS will give ZIP errors (related issue?)
+ assertTrue("test file deleted: " + testFile, testFile.delete());
+
+ // Create a new test.jar with manifest v2
+ {
+ Manifest manifest = new Manifest();
+ manifest.getMainAttributes().putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1");
+ manifest.getMainAttributes().putValue("test", "v2");
+ JarOutputStream out = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(testFile)), manifest);
+ out.flush();
+ out.close();
+ }
+
+ // Verify the manifest the JDK way
+ {
+ JarFile jarFile = new JarFile(testFile);
+ String actual = jarFile.getManifest().getMainAttributes().getValue("test");
+ assertEquals("JDK found the wrong manifest", "v2", actual);
+ jarFile.close();
+ }
+
+ // Verify the manifest the VFS way
+ {
+ VirtualFile vf = VFS.getVirtualFile(root.toURL(), "test.jar");
+ // Note that the modification date has not changed according to VFS
+// System.err.println("lastModified = " + vf.getLastModified());
+// System.err.println("modified = " + vf.hasBeenModified());
+
+ VirtualFile manifestFile = vf.findChild("META-INF/MANIFEST.MF");
+ Manifest manifest = new Manifest(manifestFile.openStream());
+ String actual = manifest.getMainAttributes().getValue("test");
+ assertEquals("VFS found the wrong manifest", "v2", actual);
+ }
+ }
+ */
+
+
+ protected URL getRootResource(String name) throws Exception
+ {
+ if (name.endsWith(".jar"))
+ return getResource("/vfs/context/jar/" + name);
+ else
+ return getResource("/vfs/context/jar/" + name + ".jar");
+ }
+
+ protected File getRealJarFile(String name) throws Exception
+ {
+ URL url = getRootResource(name);
+ return new File(url.getPath());
+ }
+
+ protected JarEntry getRealJarEntry(String name, String path) throws Exception
+ {
+ URL url = getRootResource(name);
+ url = JarUtils.createJarURL(url);
+ JarURLConnection c = (JarURLConnection) url.openConnection();
+ JarFile jarFile = c.getJarFile();
+ return jarFile.getJarEntry(path);
+ }
+
+ protected VFSContext getVFSContext(String name) throws Exception
+ {
+ URL url = getRootResource(name);
+ url = JarUtils.createJarURL(url);
+ return new ZipEntryContext(url);
+ }
+
+ protected String getRootName(String name) throws Exception
+ {
+ return name + ".jar";
+ }
+
+ protected long getRealLastModified(String name, String path) throws Exception
+ {
+ if (path != null)
+ {
+ JarEntry entry = getRealJarEntry(name, path);
+ return entry.getTime();
+ }
+ else
+ {
+ File file = getRealJarFile(name);
+ return file.lastModified();
+ }
+ }
+
+ protected long getRealSize(String name, String path) throws Exception
+ {
+ if (path != null)
+ {
+ JarEntry entry = getRealJarEntry(name, path);
+ return entry.getSize();
+ }
+ else
+ {
+ File file = getRealJarFile(name);
+ return file.length();
+ }
+ }
+}
\ No newline at end of file
Added: projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java 2008-04-29 22:30:10 UTC (rev 72878)
@@ -0,0 +1,116 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.virtual.test;
+
+import junit.framework.Test;
+import 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.zip.ZipEntryContext;
+import org.jboss.virtual.spi.VFSContext;
+
+import java.net.URL;
+
+/**
+ * JARVFSContextUnitTestCase.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ZipEntryVFSContextUnitTestCase extends AbstractVFSContextTest
+{
+ public ZipEntryVFSContextUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ VFS.init();
+ System.out.println("java.protocol.handler.pkgs: " + System.getProperty("java.protocol.handler.pkgs"));
+ return new TestSuite(ZipEntryVFSContextUnitTestCase.class);
+ }
+
+ protected VFSContext getVFSContext(String name) throws Exception
+ {
+ URL url = getResource("/vfs/context/jar/" + name + ".jar");
+ url = JarUtils.createJarURL(url);
+ return new ZipEntryContext(url);
+ }
+
+ protected VFSContext getParentVFSContext() throws Exception
+ {
+ URL url = getResource("/vfs/context/jar/");
+ return new FileSystemContext(url);
+ }
+
+ protected String getSuffix()
+ {
+ return ".jar";
+ }
+
+ /**
+ * Was having problems with a jar entry as root of VFS.
+ *
+ * @throws Exception
+ */
+ public void testJarEntryAsRoot() throws Exception
+ {
+ URL url = getResource("/vfs/context/jar/simple.jar");
+ URL entry = new URL("jar:" + url.toString() + "!/child");
+ //entry.openStream().close();
+ ZipEntryContext context = new ZipEntryContext(entry);
+ assertEquals("child", context.getRoot().getName());
+
+ url = getResource("/vfs/test/outer.jar");
+ entry = new URL("jar:" + url.toString() + "!/jar2.jar ");
+ //entry.openStream().close();
+ context = new ZipEntryContext(entry);
+ assertEquals("jar2.jar", context.getRoot().getName());
+ }
+
+ /**
+ * Was having problems with a jar entry as root of VFS.
+ * A JarEntry that is the root of the VFS should have a VFS Path of ""
+ *
+ * @throws Exception
+ */
+ public void testPathIsEmptryForJarEntryAsRoot() throws Exception
+ {
+ URL url = getResource("/vfs/context/jar/simple.jar");
+ URL entry = new URL("jar:" + url.toString() + "!/child");
+ //entry.openStream().close();
+ ZipEntryContext context = new ZipEntryContext(entry);
+ assertEquals("child", context.getRoot().getName());
+ assertEquals("", context.getRoot().getPathName());
+
+ url = getResource("/vfs/test/outer.jar");
+ entry = new URL("jar:" + url.toString() + "!/jar2.jar ");
+ //entry.openStream().close();
+ context = new ZipEntryContext(entry);
+ assertEquals("jar2.jar", context.getRoot().getName());
+ assertEquals("", context.getRoot().getPathName());
+ }
+
+}
\ No newline at end of file
More information about the jboss-cvs-commits
mailing list