[jboss-cvs] JBossAS SVN: r73826 - in projects/vfs/branches/jar-alter-work/src: main/java/org/jboss/virtual/plugins/context/file and 2 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu May 29 20:08:06 EDT 2008
Author: mstruk
Date: 2008-05-29 20:08:06 -0400 (Thu, 29 May 2008)
New Revision: 73826
Added:
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/ZipStreamWrapper.java
projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipWrapper.java
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/file/FileSystemContext.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/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/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
Log:
Added noCopy support, fixed some bugs, added system prop switches: jboss.vfs.forceVfsJar and jboss.vfs.forceNoReaper
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-05-29 23:28:29 UTC (rev 73825)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/VFSUtils.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -78,6 +78,16 @@
public static final String FORCE_COPY_KEY = "jboss.vfs.forceCopy";
public static final String USE_COPY_QUERY = "useCopyJarHandler";
+ /**
+ * Key used to force fallback from vfszip (default) to vfsjar
+ */
+ public static final String FORCE_VFS_JAR_KEY = "jboss.vfs.forceVfsJar";
+
+ /**
+ * 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";
+
private static File tempDir;
private static class GetTempDir implements PrivilegedAction<File>
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-05-29 23:28:29 UTC (rev 73825)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/file/FileSystemContext.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -27,6 +27,8 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.List;
import java.util.Properties;
@@ -35,19 +37,36 @@
import org.jboss.virtual.plugins.context.AbstractVFSContext;
import org.jboss.virtual.plugins.context.DelegatingHandler;
import org.jboss.virtual.plugins.context.zip.ZipEntryContext;
+import org.jboss.virtual.plugins.context.jar.JarHandler;
import org.jboss.virtual.plugins.context.jar.JarUtils;
import org.jboss.virtual.spi.LinkInfo;
import org.jboss.virtual.spi.VirtualFileHandler;
+import org.jboss.logging.Logger;
/**
* FileSystemContext.
*
* @author <a href="adrian at jboss.com">Adrian Brock</a>
* @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
* @version $Revision: 1.1 $
*/
public class FileSystemContext extends AbstractVFSContext
{
+
+ private static final Logger log = Logger.getLogger(ZipEntryContext.class);
+
+ /** true if forcing fallback to vfsjar from default vfszip */
+ private static boolean forceVfsJar;
+
+ static
+ {
+ forceVfsJar = AccessController.doPrivileged(new CheckForceVfsJar());
+
+ if (forceVfsJar)
+ log.warn("VFS forced fallback to vfsjar is enabled.");
+ }
+
/** The root file */
private final VirtualFileHandler root;
@@ -189,15 +208,23 @@
String name = file.getName();
if (file.isFile() && JarUtils.isArchive(name))
{
- try
+ if (forceVfsJar)
{
- //return new JarHandler(this, parent, file, file.toURL(), name);
- DelegatingHandler delegator = mountZipFS(parent, name, file);
- return delegator;
+ return new JarHandler(this, parent, file, file.toURL(), name);
}
- catch (Exception e)
+ else
{
- log.debug("Exception while trying to handle file (" + name + ") as a jar: " + e.getMessage());
+ try
+ {
+ DelegatingHandler delegator = mountZipFS(parent, name, file);
+ return delegator;
+ }
+ catch (Exception e)
+ {
+ IOException ex = new IOException("Exception while trying to handle file (" + name + ") through ZipEntryContext: ");
+ ex.initCause(e);
+ throw ex;
+ }
}
}
return createVirtualFileHandler(parent, file, getFileURI(file));
@@ -294,4 +321,14 @@
rootFile.close();
super.finalize();
}
+
+ private static class CheckForceVfsJar implements PrivilegedAction<Boolean>
+ {
+ public Boolean run()
+ {
+ String forceString = System.getProperty(VFSUtils.FORCE_VFS_JAR_KEY, "false");
+ return Boolean.valueOf(forceString);
+ }
+ }
+
}
Added: 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 (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/SizeLimitedInputStream.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -0,0 +1,62 @@
+package org.jboss.virtual.plugins.context.zip;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * 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 $
+ */
+
+public class SizeLimitedInputStream extends InputStream
+{
+
+ private InputStream in;
+
+ private int togo;
+
+ public SizeLimitedInputStream(InputStream ins, int size)
+ {
+ this.in = ins;
+ this.togo = size;
+ }
+
+ public int read() throws IOException
+ {
+ int b = -1;
+ if (togo > 0)
+ {
+ b = in.read();
+ if (b != -1)
+ togo--;
+ }
+ return b;
+ }
+
+ public int read(byte [] buf) throws IOException
+ {
+ return read(buf, 0, buf.length);
+ }
+
+ public int read(byte [] buf, int offs, int len) throws IOException
+ {
+ int rc = -1;
+
+ if (togo > 0)
+ {
+ rc = togo < len ? togo : len;
+ rc = in.read(buf, offs, rc);
+ if (rc != -1)
+ togo -= rc;
+ }
+
+ return rc;
+ }
+
+ public void close() throws IOException
+ {
+ in.close();
+ }
+}
\ No newline at end of file
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-05-29 23:28:29 UTC (rev 73825)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipEntryContext.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -1,20 +1,36 @@
package org.jboss.virtual.plugins.context.zip;
+import org.jboss.logging.Logger;
+import org.jboss.virtual.VFSUtils;
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.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.net.MalformedURLException;
-import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
-import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
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
@@ -25,16 +41,24 @@
public class ZipEntryContext extends AbstractVFSContext
{
+
+ private static final Logger log = Logger.getLogger(ZipEntryContext.class);
+
+ private static boolean forceCopy;
+
static
{
deleteTmpDirContents();
+
+ forceCopy = AccessController.doPrivileged(new CheckForceCopy());
+
+ if (forceCopy)
+ log.info("VFS force nested jars copy-mode is enabled.");
}
- /** File representing a zip archive that is virtualized with this context */
- private File rootFile;
/** ZipFile opened around rootFile */
- private ZipFileWrapper zipFile;
+ private ZipWrapper zipFile;
/** Entry path representing a context root */
private String rootEntryPath = "";
@@ -63,13 +87,13 @@
* @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
+ * @throws java.io.IOException
*/
public ZipEntryContext(URL rootURL, boolean autoClean) throws URISyntaxException, IOException
{
- super(fixUrl(rootURL));
+ super(VFSUtils.toURI(fixUrl(rootURL)));
this.autoClean = autoClean;
- init(rootURL, null);
+ init(rootURL, null, null);
}
/**
@@ -79,7 +103,7 @@
* @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
+ * @throws java.io.IOException
*/
public ZipEntryContext(URL rootURL, VirtualFileHandler peer, URL localRootUrl) throws URISyntaxException, IOException
{
@@ -98,19 +122,44 @@
*/
public ZipEntryContext(URL rootURL, VirtualFileHandler peer, URL localRootUrl, boolean autoClean) throws URISyntaxException, IOException
{
- super(fixUrl(rootURL));
+ super(VFSUtils.toURI(fixUrl(rootURL)));
this.autoClean = autoClean;
- init(localRootUrl, peer);
+ init(localRootUrl, peer, null);
}
- private void init(URL localRootURL, VirtualFileHandler peer) throws IOException, URISyntaxException
+ /**
+ * 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 zipWrapper - zip archive as abstracted wrapper
+ * @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, ZipWrapper zipWrapper, boolean autoClean) throws URISyntaxException, IOException
{
- initFileAndPath(localRootURL);
+ super(VFSUtils.toURI(fixUrl(rootURL)));
+ this.autoClean = autoClean;
+ init(null, peer, zipWrapper);
+ }
- if(!rootFile.isFile())
- throw new RuntimeException("File not found: " + rootFile);
- zipFile = new ZipFileWrapper(rootFile);
+ private void init(URL localRootURL, VirtualFileHandler peer, ZipWrapper zipWrapper) throws IOException, URISyntaxException
+ {
+
+ if (zipWrapper == null)
+ {
+ if (localRootURL == null)
+ throw new IllegalArgumentException("No ZipWrapper specified and localRootURL is null");
+ String rootPath = initRootAndPath(localRootURL);
+ zipFile = new ZipFileWrapper(VFSUtils.toURI(new URL(rootPath)), autoClean);
+ }
+ else
+ {
+ zipFile = zipWrapper;
+ }
+
setRootPeer(peer);
String name = getRootURI().toString(); // rootFile.getName()
@@ -139,7 +188,7 @@
if (peer != null)
return peer.getName();
else
- return rootFile.getName();
+ return zipFile.getName();
}
private synchronized void initEntries() throws IOException, URISyntaxException
@@ -150,10 +199,10 @@
// this way we ensure that parent entries are processed before child entries
HashMap<String, ZipEntry> relevant = new HashMap<String, ZipEntry>();
- ZipFile zFile = zipFile.acquire();
+ zipFile.acquire();
try
{
- Enumeration<? extends ZipEntry> zipEntries = zFile.entries();
+ Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
while(zipEntries.hasMoreElements())
{
ZipEntry ent = zipEntries.nextElement();
@@ -182,18 +231,35 @@
if(ent.isDirectory() == false && 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);
+ boolean useCopyMode = forceCopy;
+ if (useCopyMode == false)
+ {
+ String flag = getOptions().get(VFSUtils.USE_COPY_QUERY);
+ useCopyMode = Boolean.valueOf(flag);
+ }
- // mount FS
- DelegatingHandler delegator = mountZipFS(parent, name, dest);
+ 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);
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
+ copyStreamAndClose(is, os);
- entries.put(delegator.getLocalPathName(), new EntryInfo(delegator, ent));
- addChild(parent, delegator);
+ // mount FS
+ DelegatingHandler delegator = mountZipFS(parent, name, dest);
+
+ entries.put(delegator.getLocalPathName(), new EntryInfo(delegator, ent));
+ addChild(parent, delegator);
+ }
+ else
+ {
+ DelegatingHandler delegator = mountZipStreamFS(parent, name, zipFile.openStream(ent));
+
+ entries.put(delegator.getLocalPathName(), new EntryInfo(delegator, ent));
+ addChild(parent, delegator);
+ }
}
else
{
@@ -229,6 +295,25 @@
return delegator;
}
+ protected DelegatingHandler mountZipStreamFS(VirtualFileHandler parent, String name, InputStream zipStream) throws IOException, URISyntaxException
+ {
+ DelegatingHandler delegator = new DelegatingHandler(this, parent, name);
+ ZipStreamWrapper wrapper = new ZipStreamWrapper(zipStream, name, parent.getLastModified());
+
+ URL delegatorUrl = null;
+
+ if (parent != null)
+ delegatorUrl = getChildURL(parent, name);
+
+ ZipEntryContext ctx = new ZipEntryContext(delegatorUrl, delegator, wrapper, false);
+
+ VirtualFileHandler handler = ctx.getRoot();
+ delegator.setDelegate(handler);
+
+ return delegator;
+ }
+
+
private EntryInfo makeDummyParent(String parentPath) throws IOException
{
// get grand parent first
@@ -245,7 +330,7 @@
return ei;
}
- private void initFileAndPath(URL localRootUrl)
+ private String initRootAndPath(URL localRootUrl)
{
String filePath = localRootUrl.toString();
String zipPath = filePath;
@@ -259,19 +344,11 @@
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);
- }
+ // find where schema ends - all schemas when you have wrapping - i.e. jar:file:/ ...
+ pos= zipPath.indexOf(":/");
+ filePath = "file:" + zipPath.substring(pos+1);
+
+ return filePath;
}
public VirtualFileHandler getRoot() throws IOException
@@ -281,8 +358,8 @@
private synchronized void checkIfModified()
{
- // our rootFile may be a derivative - the extracted insides of another archive
- // if RootContextInfo is available - delegate to it
+ // 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())
{
@@ -298,11 +375,10 @@
}
catch(Exception ex)
{
- log.warn("Failed to reinitialize context: " + getRootURI());
+ log.warn("IGNORING: Failed to reinitialize context: " + getRootURI(), ex);
}
}
}
-
}
public VirtualFileHandler getChild(ZipEntryHandler parent, String name)
@@ -322,7 +398,6 @@
return null;
}
-
public List<VirtualFileHandler> getChildren(VirtualFileHandler parent, boolean ignoreErrors) throws IOException
{
if (parent == null)
@@ -344,7 +419,6 @@
return Collections.emptyList();
}
-
public long getLastModified(ZipEntryHandler handler)
{
checkIfModified();
@@ -353,7 +427,7 @@
return 0;
if(ei.entry == null) {
- return rootFile.lastModified();
+ return zipFile.getLastModified();
}
return ei.entry.getTime();
@@ -370,7 +444,7 @@
if(ei.entry == null)
{
if(pathName.length() == 0)
- return rootFile.length();
+ return zipFile.getSize();
else
return 0;
}
@@ -412,7 +486,7 @@
}
catch(Exception ex)
{
- throw new RuntimeException("ASSERTION ERROR - uri generation failed for ZipEntryHandler: " + handler);
+ throw new RuntimeException("ASSERTION ERROR - uri generation failed for ZipEntryHandler: " + handler, ex);
}
throw new FileNotFoundException(uriStr);
@@ -420,7 +494,7 @@
if(ei.entry == null)
{
- return new FileInputStream(rootFile);
+ return zipFile.getRootAsStream();
}
return zipFile.openStream(ei.entry);
@@ -442,8 +516,6 @@
try
{
zipFile.close();
- if (autoClean)
- rootFile.delete();
}
catch (Exception ex)
{
@@ -548,6 +620,43 @@
// Helper methods
//
+
+
+ /**
+ * Copy input stream to output stream and close them both
+ * @param is
+ * @param os
+ * @throws IOException
+ */
+ 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();
+ }
+ }
+
+
private static URL fixUrl(URL rootURL) throws MalformedURLException
{
if (!"vfszip".equals(rootURL.getProtocol()))
@@ -593,33 +702,6 @@
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
@@ -657,4 +739,13 @@
}
+
+ private static class CheckForceCopy implements PrivilegedAction<Boolean>
+ {
+ public Boolean run()
+ {
+ String forceString = System.getProperty(VFSUtils.FORCE_COPY_KEY, "false");
+ return Boolean.valueOf(forceString);
+ }
+ }
}
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-05-29 23:28:29 UTC (rev 73825)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileLockReaper.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -139,7 +139,7 @@
catch(Exception ex)
{
// ignore the exception
- log.debug("Failed to close ZipFile: ", ex);
+ log.debug("IGNORING: Failed to close ZipFile: ", ex);
}
}
}
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-05-29 23:28:29 UTC (rev 73825)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipFileWrapper.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -1,12 +1,21 @@
package org.jboss.virtual.plugins.context.zip;
import org.jboss.logging.Logger;
+import org.jboss.virtual.VFSUtils;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+
+
/**
* ZipFileWrapper releases and reacquires an underlying ZipFile as necessary
*
@@ -14,47 +23,55 @@
* @version $Revision: 1.0 $
*/
-public class ZipFileWrapper
+class ZipFileWrapper extends ZipWrapper
{
private static final Logger log = Logger.getLogger(ZipFileWrapper.class);
- private File file;
- private ZipFile zipFile;
+ private static boolean forceNoReaper;
- private long lastUsed;
+ static
+ {
+ forceNoReaper = AccessController.doPrivileged(new CheckNoReaper());
- private long lastModified;
+ if (forceNoReaper)
+ log.info("VFS forced no-reaper-mode is enabled.");
- private long lastChecked;
+ }
- private int refCount = 0;
+ private File file;
+
+ private ZipFile zipFile;
+
+ private boolean autoClean;
+
// used for debugging stream leaks
//ConcurrentLinkedQueue<ZipEntryInputStream> streams = new ConcurrentLinkedQueue<ZipEntryInputStream>();
- public ZipFileWrapper(File archive)
+ ZipFileWrapper(File archive, boolean autoClean)
{
- file = archive;
- lastModified = file.lastModified();
+ init(archive, autoClean);
}
- boolean hasBeenModified()
+
+ ZipFileWrapper(URI rootPathURI, boolean autoClean)
{
- long now = System.currentTimeMillis();
- if (now - lastChecked < 1000)
- return false;
+ File rootFile = new File(rootPathURI);
+ if(!rootFile.isFile())
+ throw new RuntimeException("File not found: " + rootFile);
- lastChecked = now;
- long lm = file.lastModified();
- if (lm != lastModified)
- {
- lastModified = lm;
- return true;
- }
+ init(rootFile, autoClean);
+ }
- return false;
+ private void init(File archive, boolean autoClean)
+ {
+ file = archive;
+ lastModified = file.lastModified();
+ this.autoClean = autoClean;
+ if (autoClean)
+ file.deleteOnExit();
}
boolean exists()
@@ -62,22 +79,28 @@
return file.isFile();
}
- long getLastUsed()
+ long getLastModified()
{
- return lastUsed;
+ return file.lastModified();
}
- int getReferenceCount()
+ String getName()
{
- return refCount;
+ return file.getName();
}
+ long getSize()
+ {
+ return file.length();
+ }
+
private ZipFile ensureZipFile() throws IOException
{
if (zipFile == null)
{
zipFile = new ZipFile(file);
- ZipFileLockReaper.getInstance().register(this);
+ if (forceNoReaper == false)
+ ZipFileLockReaper.getInstance().register(this);
}
return zipFile;
@@ -85,16 +108,17 @@
synchronized void closeZipFile() throws IOException
{
- if (zipFile != null && refCount <= 0)
+ if (zipFile != null && getReferenceCount() <= 0)
{
ZipFile zf = zipFile;
zipFile = null;
zf.close();
- ZipFileLockReaper.getInstance().unregister(this);
+ if (forceNoReaper == false)
+ ZipFileLockReaper.getInstance().unregister(this);
}
}
- synchronized ZipEntryInputStream openStream(ZipEntry ent) throws IOException
+ synchronized InputStream openStream(ZipEntry ent) throws IOException
{
ensureZipFile();
InputStream is = zipFile.getInputStream(ent);
@@ -103,35 +127,39 @@
// debugging code
//streams.add(zis);
- refCount++;
- lastUsed = System.currentTimeMillis();
+ incrementRef();
return zis;
}
- synchronized void release()
+ InputStream getRootAsStream() throws FileNotFoundException
{
- refCount--;
- if (refCount <= 0)
- {
+ return new FileInputStream(file);
+ }
+
+
+ synchronized void acquire() throws IOException
+ {
+ ensureZipFile();
+ incrementRef();
+ }
+
+ synchronized void release() {
+ super.release();
+ if (forceNoReaper)
try
{
- lastUsed = System.currentTimeMillis();
- // let the reaper do its job
- //closeZipFile();
+ closeZipFile();
}
catch(Exception ex)
{
log.warn("Failed to release file: " + file);
}
- }
}
- synchronized ZipFile acquire() throws IOException
+ synchronized Enumeration<? extends ZipEntry> entries() throws IOException
{
- ZipFile ret = ensureZipFile();
- refCount++;
- return ret;
+ return ensureZipFile().entries();
}
void close()
@@ -142,12 +170,25 @@
}
catch(Exception ex)
{
- log.warn("Failed to release file: " + file);
+ log.warn("IGNORING: Failed to release file: " + file, ex);
}
+
+ if (autoClean)
+ file.delete();
}
public String toString()
{
return super.toString() + " - " + file.getAbsolutePath();
}
+
+
+ private static class CheckNoReaper implements PrivilegedAction<Boolean>
+ {
+ public Boolean run()
+ {
+ String forceString = System.getProperty(VFSUtils.FORCE_NO_REAPER_KEY, "false");
+ return Boolean.valueOf(forceString);
+ }
+ }
}
Added: 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 (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipStreamWrapper.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -0,0 +1,142 @@
+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
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+class ZipStreamWrapper extends ZipWrapper
+{
+ /** Raw zip archive loaded in memory */
+ private byte [] zipBytes;
+
+ /** Name of an underlying file */
+ private String name;
+
+ /**
+ * @param zipStream
+ * @param lastModified passed by zip stream provider. We're not aware of zip source so we can not detect it was changed
+ * @throws IOException
+ */
+ ZipStreamWrapper(InputStream zipStream, String name, long lastModified) throws IOException
+ {
+ // read the contents into memory buffer
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ZipEntryContext.copyStreamAndClose(zipStream, bout);
+ zipBytes = bout.toByteArray();
+
+ // TODO - delegate file meta info operations to parent?
+ this.name = name;
+ this.lastModified = lastModified;
+ }
+
+ boolean exists()
+ {
+ return true;
+ }
+
+ long getLastModified()
+ {
+ return lastModified;
+ }
+
+ String getName()
+ {
+ return name;
+ }
+
+ long getSize()
+ {
+ return zipBytes.length;
+ }
+
+ InputStream openStream(ZipEntry ent) throws IOException
+ {
+ ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipBytes));
+
+ // first find the entry
+ ZipEntry entry = zis.getNextEntry();
+ while(entry != null)
+ {
+ if(entry.getName().equals(ent.getName()))
+ break;
+ entry = zis.getNextEntry();
+ }
+ if(entry == null)
+ throw new IOException("Failed to find nested jar entry: " + ent.getName() + " in zip stream: " + this.name);
+
+
+ // now read it
+ return new SizeLimitedInputStream(zis, (int) entry.getSize());
+ }
+
+ InputStream getRootAsStream() throws FileNotFoundException
+ {
+ return new ByteArrayInputStream(zipBytes);
+ }
+
+ void acquire() throws IOException
+ {
+ }
+
+ Enumeration<? extends ZipEntry> entries() throws IOException
+ {
+ return new ZipStreamEnumeration(new ZipInputStream(new ByteArrayInputStream(zipBytes)));
+ }
+
+
+
+ void close()
+ {
+ zipBytes = null;
+ }
+
+ public String toString()
+ {
+ return super.toString() + " - " + name;
+ }
+
+
+
+ class ZipStreamEnumeration implements Enumeration
+ {
+ private ZipInputStream zis;
+
+ private ZipEntry entry;
+
+ ZipStreamEnumeration(ZipInputStream zis) throws IOException
+ {
+ this.zis = zis;
+ entry = zis.getNextEntry();
+ }
+
+ public boolean hasMoreElements()
+ {
+ return entry != null;
+ }
+
+ public Object nextElement()
+ {
+ Object ret = entry;
+ try
+ {
+ entry = zis.getNextEntry();
+ }
+ catch (IOException ex)
+ {
+ throw new RuntimeException("Failed to retrieve next entry from zip stream", ex);
+ }
+
+ return ret;
+ }
+ }
+
+}
Added: 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 (rev 0)
+++ projects/vfs/branches/jar-alter-work/src/main/java/org/jboss/virtual/plugins/context/zip/ZipWrapper.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -0,0 +1,92 @@
+package org.jboss.virtual.plugins.context.zip;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.FileNotFoundException;
+import java.util.zip.ZipEntry;
+import java.util.Enumeration;
+
+/**
+ * ZipWrapper represents abstracted access to zip resource
+ *
+ * @author <a href="strukelj at parsek.net">Marko Strukelj</a>
+ * @version $Revision: 1.0 $
+ */
+
+abstract class ZipWrapper
+{
+
+ protected long lastModified;
+
+ protected long lastChecked;
+
+ private long lastUsed;
+
+ private int refCount = 0;
+
+
+
+
+ boolean hasBeenModified()
+ {
+ long now = System.currentTimeMillis();
+ if (now - lastChecked < 1000)
+ return false;
+
+ lastChecked = now;
+ long lm = getLastModified();
+ if (lm != lastModified)
+ {
+ lastModified = lm;
+ return true;
+ }
+
+ return false;
+ }
+
+ long getLastUsed()
+ {
+ return lastUsed;
+ }
+
+
+ int getReferenceCount()
+ {
+ return refCount;
+ }
+
+ void incrementRef()
+ {
+ refCount++;
+ lastUsed = System.currentTimeMillis();
+ }
+
+
+ abstract void acquire() throws IOException;
+
+ synchronized void release()
+ {
+ refCount--;
+ if (refCount <= 0)
+ {
+ lastUsed = System.currentTimeMillis();
+ }
+ }
+
+
+ abstract long getLastModified();
+
+ abstract String getName();
+
+ abstract boolean exists();
+
+ abstract long getSize();
+
+ abstract Enumeration<? extends ZipEntry> entries() throws IOException;
+
+ abstract InputStream openStream(ZipEntry ent) throws IOException;
+
+ abstract InputStream getRootAsStream() throws FileNotFoundException;
+
+ abstract void close();
+}
Modified: projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
===================================================================
--- projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java 2008-05-29 23:28:29 UTC (rev 73825)
+++ projects/vfs/branches/jar-alter-work/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java 2008-05-30 00:08:06 UTC (rev 73826)
@@ -1244,7 +1244,7 @@
assertNotNull("tstjar != null", tstjar);
URI uri = tstjar.toURI();
URI expectedURI = new URI("vfs"+rootURL.toString()+"/path%20with%20spaces/tst.jar");
- assertEquals(uri, expectedURI);
+ assertEquals(uri.getPath(), expectedURI.getPath());
}
public static void main(String[] args) throws Exception
More information about the jboss-cvs-commits
mailing list