[jboss-cvs] JBossAS SVN: r73900 - in projects/vfs/branches/jar-alter-work/src: main/java/org/jboss/virtual/plugins/context and 3 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Sun Jun 1 12:17:46 EDT 2008
Author: mstruk
Date: 2008-06-01 12:17:45 -0400 (Sun, 01 Jun 2008)
New Revision: 73900
Modified:
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/VFSUtils.java
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/file/FileSystemContext.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/SizeLimitedInputStream.java
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/ZipFileLockReaper.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/plugins/context/zip/ZipStreamWrapper.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipWrapper.java
projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java
Log:
Added noReaper URL query parameter, bug fixes, code cleanup, comments and javadoc
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/VFSUtils.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/VFSUtils.java 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/VFSUtils.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -87,6 +87,7 @@
* Key used to turn off reaper mode in vfszip - forcing synchronous (slower) handling of files
*/
public static final String FORCE_NO_REAPER_KEY = "jboss.vfs.forceNoReaper";
+ public static final String NO_REAPER_QUERY = "noReaper";
private static File tempDir;
@@ -99,7 +100,7 @@
}
}
- private synchronized static File getTempDirectory()
+ public synchronized static File getTempDirectory()
{
if (tempDir == null)
{
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-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/AbstractVFSContext.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -151,8 +151,11 @@
else
pPathName = parent.getPathName();
+ if (urlStr.charAt( urlStr.length()-1) != '/')
+ urlStr.append("/");
+
if(pPathName.length() != 0)
- urlStr.append("/").append(pPathName);
+ urlStr.append(pPathName);
if (urlStr.charAt( urlStr.length()-1) != '/')
urlStr.append("/");
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-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -45,6 +45,11 @@
/**
* FileSystemContext.
+ *
+ * Jar archives are processed through {@link org.jboss.virtual.plugins.context.zip.ZipEntryContext}.
+ *
+ * To switch back to {@link org.jboss.virtual.plugins.context.jar.JarHandler}
+ * set a system property <em>jboss.vfs.forceVfsJar=true</em>
*
* @author <a href="adrian at jboss.com">Adrian Brock</a>
* @author <a href="ales.justin at jboss.com">Ales Justin</a>
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/SizeLimitedInputStream.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/SizeLimitedInputStream.java 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/SizeLimitedInputStream.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,3 +1,24 @@
+/*
+* 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.zip;
import java.io.InputStream;
@@ -4,8 +25,11 @@
import java.io.IOException;
/**
- * SizeLimitedInputStream - signals EOF when the specified number of bytes have been read from the underlying stream
+ * SizeLimitedInputStream
*
+ * Signals EOF when the specified number of bytes
+ * have been read from the underlying stream
+ *
* @author <a href="strukelj at parsek.net">Marko Strukelj</a>
* @version $Revision: 1.0 $
*/
Modified: 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 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,3 +1,24 @@
+/*
+* 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.zip;
import org.jboss.logging.Logger;
@@ -33,8 +54,28 @@
import java.util.zip.ZipEntry;
/**
- * VFSContext exposing a zip archive file as a virtual file system
+ * <tt>ZipEntryContext</tt> implements a {@link org.jboss.virtual.spi.VFSContext}
+ * that exposes a zip archive as a virtual file system.
*
+ * Zip archive can be in a form of a file or a stream.
+ *
+ * Nested archives are processed through this same class.
+ * By default nested archives are cached in memory and mounted as new
+ * instances of <tt>ZipEntryContext</tt> with <tt>ZipStremWrapper</tt> as a source.
+ * If system property <em>jboss.vfs.forceCopy=true</em> is specified,
+ * or URL query parameter <em>forceCopy=true</em> is present,
+ * nested archives are extracted into a temp directory before being
+ * mounted as new instances of <tt>ZipEntryContext</tt>.
+ *
+ * This context implementation has two modes of releasing file locks.
+ * <em>Asynchronous</em> mode is the default one since it is better performant.
+ * To switch this to <em>synchronous</em> mode a system property
+ * <em>jboss.vfs.forceNoReaper=true</em> can be specified or URL query parameter
+ * <em>noReaper=true</em> can be included in context URL.
+ *
+ * This context implementation is a replacement for
+ * {@link org.jboss.virtual.plugins.context.jar.JarContext}.
+ *
* @author <a href="strukelj at parsek.net">Marko Strukelj</a>
* @version $Revision: 1.0 $
*/
@@ -44,6 +85,7 @@
private static final Logger log = Logger.getLogger(ZipEntryContext.class);
+ /** Global setting for nested archive processing mode: copy or no-copy (default) */
private static boolean forceCopy;
static
@@ -57,18 +99,19 @@
}
- /** ZipFile opened around rootFile */
- private ZipWrapper zipFile;
+ /** Abstracted access to zip archive - either ZipFileWrapper or ZipStreamWrapper */
+ private ZipWrapper zipSource;
- /** Entry path representing a context root */
+ /** Entry path representing a context root - archive root is not necessarily a context root */
private String rootEntryPath = "";
- /** Auto clean signals if rootFile should be deleted after closing the context */
+ /** AutoClean signals if zip archive should be deleted after closing the context - true for nested archives */
private boolean autoClean = false;
- /** Entries in a hierarchy */
+ /** Registry of everything that zipSource contains */
private ConcurrentHashMap<String, EntryInfo> entries = new ConcurrentHashMap<String, EntryInfo>();
+
/**
* Create a new ZipEntryContext
*
@@ -97,7 +140,7 @@
}
/**
- * Create a new ZipEntryContext being mounted into another context
+ * Create a new ZipEntryContext to be 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
@@ -111,7 +154,7 @@
}
/**
- * Create a new ZipEntryContext being mounted into another context
+ * Create a new ZipEntryContext to be 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
@@ -128,11 +171,11 @@
}
/**
- * Create a new ZipEntryContext being mounted into another context
+ * Create a new ZipEntryContext to be 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 zipWrapper - zip archive as abstracted wrapper
+ * @param zipWrapper - abstracted zip archive source
* @param autoClean - true if file represented by localRootURL should be deleted after this context is closed
* @throws URISyntaxException
* @throws IOException
@@ -144,7 +187,15 @@
init(null, peer, zipWrapper);
}
-
+ /**
+ * Extra initialization that couldn't fit inside constructors
+ *
+ * @param localRootURL
+ * @param peer
+ * @param zipWrapper
+ * @throws IOException
+ * @throws URISyntaxException
+ */
private void init(URL localRootURL, VirtualFileHandler peer, ZipWrapper zipWrapper) throws IOException, URISyntaxException
{
@@ -152,45 +203,64 @@
{
if (localRootURL == null)
throw new IllegalArgumentException("No ZipWrapper specified and localRootURL is null");
+
+ // initialize rootEntryPath and get archive file path
String rootPath = initRootAndPath(localRootURL);
- zipFile = new ZipFileWrapper(VFSUtils.toURI(new URL(rootPath)), autoClean);
+
+ String noReaper = getOptions().get(VFSUtils.NO_REAPER_QUERY);
+ zipSource = new ZipFileWrapper(VFSUtils.toURI(new URL(rootPath)), autoClean, Boolean.valueOf(noReaper));
}
else
{
- zipFile = zipWrapper;
+ zipSource = zipWrapper;
}
setRootPeer(peer);
- String name = getRootURI().toString(); // rootFile.getName()
+ String name = getRootURI().toString();
int toPos = name.length();
+
+ // cut off any ending slash
if(name.length() != 0 && name.charAt(name.length()-1) == '/')
toPos --;
+ // name is last path component
int namePos = name.lastIndexOf("/", toPos-1);
name = name.substring(namePos+1, toPos);
+ // cut off any ending exclamation
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
- // root represents the zip file itself so we treat it as leaf as far as
- // URL not ending with / for non-directories goes
+ // init initial root EntryInfo that will be overwritten
+ // if zip entry exists for rootEntryPath
entries.put("", new EntryInfo(new ZipEntryHandler(this, null, name, true), null));
initEntries();
ZipEntryContextFactory.registerContext(this);
}
+ /**
+ * Returns archive file name - if this is a top-level ZipEntryContext.
+ * Otherwise it returns the last component of URL.
+ *
+ * @return name
+ */
public String getName()
{
VirtualFileHandler peer = getRootPeer();
if (peer != null)
return peer.getName();
else
- return zipFile.getName();
+ return zipSource.getName();
}
+ /**
+ * Iterate through zip archive entries, compose a tree structure of archive's content
+ *
+ * @throws IOException
+ * @throws URISyntaxException
+ */
private synchronized void initEntries() throws IOException, URISyntaxException
{
@@ -199,10 +269,12 @@
// this way we ensure that parent entries are processed before child entries
HashMap<String, ZipEntry> relevant = new HashMap<String, ZipEntry>();
- zipFile.acquire();
+ zipSource.acquire();
try
{
- Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
+ Enumeration<? extends ZipEntry> zipEntries = zipSource.entries();
+
+ // zoom-in on entries under rootEntryPath - ignoring the rest
while(zipEntries.hasMoreElements())
{
ZipEntry ent = zipEntries.nextElement();
@@ -238,28 +310,32 @@
useCopyMode = Boolean.valueOf(flag);
}
+ DelegatingHandler delegator;
+
if (useCopyMode)
{
// extract it to temp dir
File dest = new File(getTempDir() + "/" + getTempFileName(ent.getName()));
- dest.getParentFile().mkdirs(); // ensure parent exists
- InputStream is = zipFile.openStream(ent);
+ dest.deleteOnExit();
+
+ // ensure parent exists
+ dest.getParentFile().mkdirs();
+
+ InputStream is = zipSource.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);
+ // mount another instance of ZipEntryContext
+ delegator = mountZipFile(parent, name, dest);
}
else
{
- DelegatingHandler delegator = mountZipStreamFS(parent, name, zipFile.openStream(ent));
+ // mount another instance of ZipEntryContext
+ delegator = mountZipStream(parent, name, zipSource.openStream(ent));
+ }
- entries.put(delegator.getLocalPathName(), new EntryInfo(delegator, ent));
- addChild(parent, delegator);
- }
+ entries.put(delegator.getLocalPathName(), new EntryInfo(delegator, ent));
+ addChild(parent, delegator);
}
else
{
@@ -271,12 +347,22 @@
}
finally
{
- zipFile.release();
+ zipSource.release();
}
}
- protected DelegatingHandler mountZipFS(VirtualFileHandler parent, String name, File file) throws IOException, URISyntaxException
+ /**
+ * Mount ZipEntryContext created around extracted nested archive
+ *
+ * @param parent
+ * @param name
+ * @param file
+ * @return
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ protected DelegatingHandler mountZipFile(VirtualFileHandler parent, String name, File file) throws IOException, URISyntaxException
{
DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
URL fileUrl = file.toURL();
@@ -284,18 +370,25 @@
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;
}
- protected DelegatingHandler mountZipStreamFS(VirtualFileHandler parent, String name, InputStream zipStream) throws IOException, URISyntaxException
+ /**
+ * Mount ZipEntryContext created around ZipStreamWrapper
+ *
+ * @param parent
+ * @param name
+ * @param zipStream
+ * @return
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ protected DelegatingHandler mountZipStream(VirtualFileHandler parent, String name, InputStream zipStream) throws IOException, URISyntaxException
{
DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
ZipStreamWrapper wrapper = new ZipStreamWrapper(zipStream, name, parent.getLastModified());
@@ -306,14 +399,19 @@
delegatorUrl = getChildURL(parent, name);
ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, wrapper, false);
-
VirtualFileHandler handler = ctx.getRoot();
delegator.setDelegate(handler);
return delegator;
}
-
+ /**
+ * Zip archives sometimes don't contain directory entries - only leaf entries
+ *
+ * @param parentPath
+ * @return
+ * @throws IOException
+ */
private EntryInfo makeDummyParent(String parentPath) throws IOException
{
// get grand parent first
@@ -330,6 +428,12 @@
return ei;
}
+ /**
+ * Initialize rootEntryPath and return archive file path
+ *
+ * @param localRootUrl
+ * @return
+ */
private String initRootAndPath(URL localRootUrl)
{
String filePath = localRootUrl.toString();
@@ -344,45 +448,54 @@
rootEntryPath += "/";
}
- // find where schema ends - all schemas when you have wrapping - i.e. jar:file:/ ...
+ // find where url protocol ends - i.e. jar:file:/ ...
pos= zipPath.indexOf(":/");
- filePath = "file:" + zipPath.substring(pos+1);
+ filePath = zipPath.substring(pos+1);
- return filePath;
+ // cut out url query part if present
+ int queryStart = filePath.indexOf("?");
+ if (queryStart != -1)
+ filePath = filePath.substring(0, queryStart);
+
+ return "file:" + filePath;
}
- public VirtualFileHandler getRoot() throws IOException
- {
- return entries.get("").handler;
- }
-
+ /**
+ * If archive has been modified, clear <em>entries</em> and re-initialize
+ */
private synchronized void checkIfModified()
{
- // TODO: our rootFile may be a derivative - the extracted insides of another archive
- // In that case we should delegate lastModified to its parent
- // otherwise work on the file directly
- if (zipFile.hasBeenModified())
+ // TODO: if zipSource represents a nested archive we should maybe delegate lastModified to its parent
+ if (zipSource.hasBeenModified())
{
EntryInfo rootInfo = entries.get("");
entries = new ConcurrentHashMap<String, EntryInfo>();
entries.put("", rootInfo);
- if (zipFile.exists())
+ if (zipSource.exists())
{
try
{
initEntries();
}
- catch(Exception ex)
+ catch(Exception ignored)
{
- log.warn("IGNORING: Failed to reinitialize context: " + getRootURI(), ex);
+ log.warn("IGNORING: Failed to reinitialize context: " + getRootURI(), ignored);
}
}
}
}
+ public VirtualFileHandler getRoot() throws IOException
+ {
+ return entries.get("").handler;
+ }
+
public VirtualFileHandler getChild(ZipEntryHandler parent, String name)
{
+ if (parent == null)
+ throw new IllegalArgumentException("Null parent");
+
checkIfModified();
String pathName = parent.getLocalPathName();
if("".equals(pathName))
@@ -421,13 +534,16 @@
public long getLastModified(ZipEntryHandler handler)
{
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
checkIfModified();
EntryInfo ei = entries.get(handler.getLocalPathName());
if(ei == null)
return 0;
if(ei.entry == null) {
- return zipFile.getLastModified();
+ return zipSource.getLastModified();
}
return ei.entry.getTime();
@@ -435,6 +551,9 @@
public long getSize(ZipEntryHandler handler)
{
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
checkIfModified();
String pathName = handler.getLocalPathName();
EntryInfo ei = entries.get(pathName);
@@ -444,7 +563,7 @@
if(ei.entry == null)
{
if(pathName.length() == 0)
- return zipFile.getSize();
+ return zipSource.getSize();
else
return 0;
}
@@ -454,16 +573,26 @@
public boolean exists(ZipEntryHandler handler)
{
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
checkIfModified();
- EntryInfo ei = entries.get(handler.getLocalPathName());
+ String pathName = handler.getLocalPathName();
+ EntryInfo ei = entries.get(pathName);
if(ei == null)
return false;
+ if (ei.entry == null && pathName.length() == 0)
+ return zipSource.exists();
+
return true;
}
public boolean isLeaf(ZipEntryHandler handler)
{
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
checkIfModified();
EntryInfo ei = entries.get(handler.getLocalPathName());
if(ei == null || ei.entry == null)
@@ -474,6 +603,9 @@
public InputStream openStream(ZipEntryHandler handler) throws IOException
{
+ if (handler == null)
+ throw new IllegalArgumentException("Null handler");
+
checkIfModified();
EntryInfo ei = entries.get(handler.getLocalPathName());
@@ -494,14 +626,20 @@
if(ei.entry == null)
{
- return zipFile.getRootAsStream();
+ return zipSource.getRootAsStream();
}
- return zipFile.openStream(ei.entry);
+ return zipSource.openStream(ei.entry);
}
public void addChild(AbstractVirtualFileHandler parent, AbstractVirtualFileHandler child)
{
+ if (parent == null)
+ throw new IllegalArgumentException("Null parent");
+
+ if (child == null)
+ throw new IllegalArgumentException("Null child");
+
EntryInfo parentEntry = entries.get(parent.getLocalPathName());
if (parentEntry != null)
parentEntry.add(child);
@@ -515,11 +653,12 @@
{
try
{
- zipFile.close();
+ super.finalize();
+ zipSource.close();
}
- catch (Exception ex)
+ catch (Throwable ignored)
{
- // ignore
+ log.debug("IGNORING: Failed to close zip source: " + zipSource, ignored);
}
}
@@ -559,7 +698,7 @@
/**
- * Internal data structure, holding ZipEntries and child handlers for every handler in this context
+ * Internal data structure holding meta information of a virtual file in this context
*/
static class EntryInfo
{
@@ -609,13 +748,30 @@
public synchronized void add(AbstractVirtualFileHandler child)
{
if (children == null)
+ {
children = new LinkedList<AbstractVirtualFileHandler>();
+ }
+ else
+ {
+ // if a child exists with this name already, remove it
+ Iterator<AbstractVirtualFileHandler> it = children.iterator();
+ while (it.hasNext())
+ {
+ AbstractVirtualFileHandler handler = it.next();
+ if (handler.getName().equals(child.getName()))
+ {
+ it.remove();
+ break;
+ }
+ }
+ }
children.add(child);
}
}
+
//
// Helper methods
//
@@ -624,6 +780,7 @@
/**
* Copy input stream to output stream and close them both
+ *
* @param is
* @param os
* @throws IOException
@@ -647,19 +804,24 @@
try {
is.close();
}
- catch(Exception ex)
+ catch(Exception ignored)
{
- // ignore
}
}
os.close();
}
}
-
+ /**
+ * Make sure url protocol is <em>vfszip</em>
+ *
+ * @param rootURL
+ * @return
+ * @throws MalformedURLException
+ */
private static URL fixUrl(URL rootURL) throws MalformedURLException
{
- if (!"vfszip".equals(rootURL.getProtocol()))
+ if ("vfszip".equals(rootURL.getProtocol()) == false)
{
String url = rootURL.toString();
int pos = url.indexOf(":/");
@@ -671,6 +833,12 @@
return rootURL;
}
+ /**
+ * Break to path + name
+ *
+ * @param pathName
+ * @return
+ */
public static String [] splitParentChild(String pathName)
{
if(pathName.length() == 0)
@@ -703,23 +871,34 @@
}
-
- // TODO: the following two methods are a quick and dirty strategy for temp file name and path
+ /**
+ * Temporary files naming scheme
+ *
+ * @param name
+ * @return
+ */
private static String getTempFileName(String name)
{
int delim = name.lastIndexOf("/");
if (delim != -1)
name = name.substring(delim+1);
- return UUID.randomUUID().toString() + "_" + name;
+ return UUID.randomUUID().toString().substring(0, 18) + "_" + name;
}
+ /**
+ * Use VFS's temp directory and make 'vfs-nested' sub-directory inside it for our purposes
+ *
+ * @return
+ */
private static String getTempDir()
{
- File dir = new File(System.getProperty("jboss.server.temp.dir"), "vfs.tmp");
- //dir.mkdirs();
+ File dir = new File(VFSUtils.getTempDirectory(), "vfs-nested.tmp");
return dir.toString();
}
+ /**
+ * Delete first-level files only, don't drill down
+ */
private static void deleteTmpDirContents()
{
try
@@ -732,9 +911,8 @@
file.delete();
}
}
- catch(Exception ex)
+ catch(Exception ignored)
{
- // ignore
}
}
Modified: 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 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContextFactory.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,3 +1,24 @@
+/*
+* 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.zip;
import org.jboss.virtual.plugins.context.AbstractContextFactory;
@@ -20,11 +41,15 @@
public class ZipEntryContextFactory extends AbstractContextFactory
{
+ /** registry of all ZipEntryContext instances */
+ private static Map<String, ZipEntryContext> ctxCache = new ConcurrentHashMap<String, ZipEntryContext>();
- public static Map<String, ZipEntryContext> ctxCache = new ConcurrentHashMap<String, ZipEntryContext>();
-
+ /** singleton */
private static ZipEntryContextFactory instance = new ZipEntryContextFactory();
+ /**
+ * ZipEntryContextFactory registers two url protocols: <em>zip</em> and <em>vfszip</em>
+ */
public ZipEntryContextFactory()
{
super("zip", "vfszip"); // "jar", "vfsjar",
@@ -35,6 +60,13 @@
return getVFS(rootURI.toURL());
}
+ /**
+ * Find a best matching existing ZipEntryContext, or create a new one if none matches.
+ *
+ * @param rootURL
+ * @return
+ * @throws IOException
+ */
public VFSContext getVFS(URL rootURL) throws IOException
{
String key = rootURL.toString();
@@ -74,8 +106,8 @@
throw e;
}
- // no need to put a newly created context into ctxCache
- // it's constructor does that by calling registerContext
+ // ZipEntryContext registers newly created context with this factory
+ // by calling registerContext() which puts a newly created context into ctxCache
return ctx;
}
Modified: 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 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryHandler.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,3 +1,24 @@
+/*
+* 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.zip;
import org.jboss.virtual.VFSUtils;
Modified: 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 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryInputStream.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,3 +1,24 @@
+/*
+* 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.zip;
import java.io.IOException;
@@ -2,7 +23,9 @@
import java.io.InputStream;
-import java.util.zip.ZipEntry;
/**
- * InputStream that wraps an InputStream retrieved from ZipFile.getInputStream(entry)
+ * ZipEntryInputStream is part of ZipFileWrapper implementation.
*
+ * It wraps the stream retrieved from ZipFile.getInputStream(entry)
+ * and releases the underlying ZipFileWrapper when detecting end of use.
+ *
* @author <a href="strukelj at parsek.net">Marko Strukelj</a>
@@ -21,6 +44,9 @@
ZipEntryInputStream(ZipFileWrapper zipWrapper, InputStream is) throws IOException
{
+ if (is == null)
+ throw new IllegalArgumentException("Input stream is null");
+
this.zipWrapper = zipWrapper;
delegate = is;
}
@@ -146,9 +172,8 @@
{
close();
}
- catch(IOException ex)
+ catch(IOException ignored)
{
- // ignore
}
}
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileLockReaper.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileLockReaper.java 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileLockReaper.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,3 +1,24 @@
+/*
+* 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.zip;
import org.jboss.logging.Logger;
@@ -8,7 +29,7 @@
import java.util.concurrent.ConcurrentLinkedQueue;
/**
- * Monitoring object that closes ZipFiles when they haven't been used for a while
+ * A monitoring object that closes ZipFiles when they haven't been used for a while
*
* @author <a href="strukelj at parsek.net">Marko Strukelj</a>
* @version $Revision: 1.0 $
@@ -16,7 +37,6 @@
public class ZipFileLockReaper
{
- /** Logger */
private static final Logger log = Logger.getLogger(ZipFileLockReaper.class);
/**
@@ -28,7 +48,7 @@
/** Timer thread period */
private static final int TIMER_PERIOD = 1000;
- /** If timer finds out there are no open ZipFiles for a while it shuts down until some are (re)opened */
+ /** If timer finds out there haven't been any ZipFiles open for a while it shuts down until some are (re)opened */
private static final int TIMER_UNUSED_PERIOD = 30000;
/** There is only one instance that serves all ZipFileWrappers */
@@ -136,10 +156,9 @@
w.closeZipFile();
log.debug("Asynchronously closed an unused ZipFile: " + w);
}
- catch(Exception ex)
+ catch(Exception ignored)
{
- // ignore the exception
- log.debug("IGNORING: Failed to close ZipFile: ", ex);
+ log.debug("IGNORING: Failed to close ZipFile: " + w, ignored);
}
}
}
Modified: 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 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,3 +1,24 @@
+/*
+* 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.zip;
import org.jboss.logging.Logger;
@@ -17,8 +38,10 @@
/**
- * ZipFileWrapper releases and reacquires an underlying ZipFile as necessary
+ * ZipFileWrapper - for abstracted access to zip files on disk
*
+ * It releases and reacquires the underlying ZipFile as necessary
+ *
* @author <a href="strukelj at parsek.net">Marko Strukelj</a>
* @version $Revision: 1.0 $
*/
@@ -39,25 +62,31 @@
}
-
private File file;
+ /** zip inflater wrapped around file */
private ZipFile zipFile;
+ /** true for extracted nested jars that we want removed when this wrapper is closed */
private boolean autoClean;
+ /** true if noReaper mode is forced on a per-instance basis */
+ private boolean noReaperOverride;
+
// used for debugging stream leaks
//ConcurrentLinkedQueue<ZipEntryInputStream> streams = new ConcurrentLinkedQueue<ZipEntryInputStream>();
- ZipFileWrapper(File archive, boolean autoClean)
+ ZipFileWrapper(File archive, boolean autoClean, boolean noReaperOverride)
{
+ this.noReaperOverride = noReaperOverride;
init(archive, autoClean);
}
- ZipFileWrapper(URI rootPathURI, boolean autoClean)
+ ZipFileWrapper(URI rootPathURI, boolean autoClean, boolean noReaperOverride)
{
+ this.noReaperOverride = noReaperOverride;
File rootFile = new File(rootPathURI);
if(!rootFile.isFile())
throw new RuntimeException("File not found: " + rootFile);
@@ -65,6 +94,12 @@
init(rootFile, autoClean);
}
+ /**
+ * Extra initialization that didn't fit in constructors
+ *
+ * @param archive
+ * @param autoClean
+ */
private void init(File archive, boolean autoClean)
{
file = archive;
@@ -99,7 +134,7 @@
if (zipFile == null)
{
zipFile = new ZipFile(file);
- if (forceNoReaper == false)
+ if (forceNoReaper == false && noReaperOverride == false)
ZipFileLockReaper.getInstance().register(this);
}
@@ -113,7 +148,7 @@
ZipFile zf = zipFile;
zipFile = null;
zf.close();
- if (forceNoReaper == false)
+ if (forceNoReaper == false && noReaperOverride == false)
ZipFileLockReaper.getInstance().unregister(this);
}
}
@@ -122,6 +157,9 @@
{
ensureZipFile();
InputStream is = zipFile.getInputStream(ent);
+ if (is == null)
+ throw new IOException("Entry no longer available: " + ent.getName() + " in file " + file);
+
ZipEntryInputStream zis = new ZipEntryInputStream(this, is);
// debugging code
@@ -146,7 +184,7 @@
synchronized void release() {
super.release();
- if (forceNoReaper)
+ if (forceNoReaper || noReaperOverride)
try
{
closeZipFile();
@@ -168,9 +206,9 @@
{
closeZipFile();
}
- catch(Exception ex)
+ catch(Exception ignored)
{
- log.warn("IGNORING: Failed to release file: " + file, ex);
+ log.warn("IGNORING: Failed to release file: " + file, ignored);
}
if (autoClean)
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipStreamWrapper.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipStreamWrapper.java 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipStreamWrapper.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,14 +1,33 @@
+/*
+* 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.zip;
-import org.jboss.virtual.plugins.context.zip.SizeLimitedInputStream;
-
import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
- * ZipStreamWrapper - abstracted access to in-memory zip file
+ * ZipStreamWrapper - for abstracted access to in-memory zip file
*
* @author <a href="strukelj at parsek.net">Marko Strukelj</a>
* @version $Revision: 1.0 $
@@ -18,12 +37,15 @@
/** Raw zip archive loaded in memory */
private byte [] zipBytes;
- /** Name of an underlying file */
+ /** Name */
private String name;
/**
+ * ZipStreamWrapper is not aware of actual zip source so it can not detect
+ * if it's been modified, like ZipFileWrapper does.
+ *
* @param zipStream
- * @param lastModified passed by zip stream provider. We're not aware of zip source so we can not detect it was changed
+ * @param lastModified passed by zip stream provider - constant value
* @throws IOException
*/
ZipStreamWrapper(InputStream zipStream, String name, long lastModified) throws IOException
@@ -74,7 +96,7 @@
throw new IOException("Failed to find nested jar entry: " + ent.getName() + " in zip stream: " + this.name);
- // now read it
+ // then read it
return new SizeLimitedInputStream(zis, (int) entry.getSize());
}
@@ -93,7 +115,6 @@
}
-
void close()
{
zipBytes = null;
Modified: projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipWrapper.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipWrapper.java 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipWrapper.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -1,3 +1,24 @@
+/*
+* 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.zip;
import java.io.IOException;
@@ -7,7 +28,7 @@
import java.util.Enumeration;
/**
- * ZipWrapper represents abstracted access to zip resource
+ * ZipWrapper represents abstracted access to zip archive
*
* @author <a href="strukelj at parsek.net">Marko Strukelj</a>
* @version $Revision: 1.0 $
@@ -16,17 +37,24 @@
abstract class ZipWrapper
{
+ /** last known modifyTime of the zip source */
protected long lastModified;
- protected long lastChecked;
+ /** timestamp of last call to getLastModified()
+ * it's an expensive call - we don't do it more then once every second */
+ private long lastChecked;
+ /** last known activity */
private long lastUsed;
+ /** number of streams currently open on this wrapper */
private int refCount = 0;
-
+ /**
+ * Returns true if underlying source's lastModified time has changed since previous call
+ */
boolean hasBeenModified()
{
long now = System.currentTimeMillis();
@@ -49,7 +77,11 @@
return lastUsed;
}
-
+ /**
+ * Returns the number of streams currently open
+ *
+ * @return
+ */
int getReferenceCount()
{
return refCount;
@@ -62,8 +94,6 @@
}
- abstract void acquire() throws IOException;
-
synchronized void release()
{
refCount--;
@@ -73,6 +103,7 @@
}
}
+ abstract void acquire() throws IOException;
abstract long getLastModified();
Modified: 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 2008-06-01 09:13:34 UTC (rev 73899)
+++ projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/ZipEntryVFSContextUnitTestCase.java 2008-06-01 16:17:45 UTC (rev 73900)
@@ -24,12 +24,14 @@
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.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.net.URL;
/**
@@ -103,4 +105,37 @@
assertEquals("", context.getRoot().getPathName());
}
+ /**
+ * Test detection of underlying jar file removal through exists()
+ *
+ * @throws Exception
+ */
+ public void testRootExists() throws Exception
+ {
+ URL url = getResource("/vfs/test/outer.jar");
+ File tmpJar = File.createTempFile("vfstest", ".jar");
+
+ InputStream is = url.openStream();
+ OutputStream os = new FileOutputStream(tmpJar);
+
+ byte [] buff = new byte[65536];
+ int count = is.read(buff);
+ while(count != -1)
+ {
+ os.write(buff, 0, count);
+ count = is.read(buff);
+ }
+ os.close();
+
+ // use noReaper so that the underlying file is not locked
+ // when we try to delete it
+ String jarUrl = tmpJar.toURL().toString() + "?noReaper=true";
+ ZipEntryContext context = new ZipEntryContext(new URL(jarUrl));
+ assertTrue("context.getRoot().exists()", context.getRoot().exists());
+
+ boolean isDeleted = tmpJar.delete();
+ assertTrue("delete tmp file: " + tmpJar, isDeleted);
+
+ assertFalse("context.getRoot().exists()", context.getRoot().exists());
+ }
}
\ No newline at end of file
More information about the jboss-cvs-commits
mailing list