[jboss-cvs] JBossAS SVN: r91749 - in projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual: spi and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Jul 28 19:14:21 EDT 2009
Author: david.lloyd at jboss.com
Date: 2009-07-28 19:14:21 -0400 (Tue, 28 Jul 2009)
New Revision: 91749
Modified:
projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java
projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFSUtils.java
projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/RealFileSystem.java
Log:
Add friendly mount API
Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java 2009-07-28 22:50:03 UTC (rev 91748)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java 2009-07-28 23:14:21 UTC (rev 91749)
@@ -23,6 +23,9 @@
import java.io.Closeable;
import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileOutputStream;
import java.net.URI;
import java.net.URL;
import java.net.URISyntaxException;
@@ -35,11 +38,16 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Enumeration;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipEntry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.jboss.virtual.spi.FileSystem;
import org.jboss.virtual.spi.RealFileSystem;
+import org.jboss.virtual.spi.JavaZipFileSystem;
+import org.jboss.virtual.plugins.vfs.helpers.PathTokenizer;
/**
* Virtual File System
@@ -320,6 +328,270 @@
return new HashSet<String>(mountMap.keySet());
}
+ private static Closeable doMount(final FileSystem fileSystem, final VirtualFile mountPoint) throws IOException
+ {
+ boolean ok = false;
+ try {
+ final Closeable mountHandle = getInstance().mount(mountPoint, fileSystem);
+ final Closeable closeable = new Closeable()
+ {
+ public void close() throws IOException
+ {
+ VFSUtils.safeClose(mountHandle);
+ VFSUtils.safeClose(fileSystem);
+ }
+ };
+ return closeable;
+ } finally {
+ if (! ok) {
+ VFSUtils.safeClose(fileSystem);
+ }
+ }
+ }
+
+ /**
+ * Create and mount a zip file into the filesystem, returning a single handle which will unmount and close the file
+ * system when closed.
+ *
+ * @param zipFile the zip file to mount
+ * @param mountPoint the point at which the filesystem should be mounted
+ * @param tempFileProvider the temporary file provider
+ * @return a handle
+ * @throws IOException if an error occurs
+ */
+ public static Closeable mountZip(File zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+ {
+ boolean ok = false;
+ final TempDir tempDir = tempFileProvider.createTempDir(zipFile.getName());
+ try {
+ final Closeable closeable = doMount(new JavaZipFileSystem(zipFile, tempDir), mountPoint);
+ ok = true;
+ return closeable;
+ } finally {
+ if (! ok) {
+ VFSUtils.safeClose(tempDir);
+ }
+ }
+ }
+
+ /**
+ * Create and mount a zip file into the filesystem, returning a single handle which will unmount and close the file
+ * system when closed.
+ *
+ * @param zipData an input stream containing the zip data
+ * @param zipName the name of the archive
+ * @param mountPoint the point at which the filesystem should be mounted
+ * @param tempFileProvider the temporary file provider
+ * @return a handle
+ * @throws IOException if an error occurs
+ */
+ public static Closeable mountZip(InputStream zipData, String zipName, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+ {
+ boolean ok = false;
+ try {
+ final TempDir tempDir = tempFileProvider.createTempDir(zipName);
+ try {
+ final Closeable closeable = doMount(new JavaZipFileSystem(zipName, zipData, tempDir), mountPoint);
+ ok = true;
+ return closeable;
+ } finally {
+ if (! ok) {
+ VFSUtils.safeClose(tempDir);
+ }
+ }
+ } finally {
+ VFSUtils.safeClose(zipData);
+ }
+ }
+
+ /**
+ * Create and mount a real file system, returning a single handle which will unmount and close the filesystem when
+ * closed.
+ *
+ * @param realRoot the real filesystem root
+ * @param mountPoint the point at which the filesystem should be mounted
+ * @return a handle
+ * @throws IOException if an error occurs
+ */
+ public static Closeable mountReal(File realRoot, VirtualFile mountPoint) throws IOException
+ {
+ return doMount(new RealFileSystem(realRoot), mountPoint);
+ }
+
+ /**
+ * Create and mount a temporary file system, returning a single handle which will unmount and close the filesystem
+ * when closed.
+ *
+ * @param mountPoint the point at which the filesystem should be mounted
+ * @param tempFileProvider the temporary file provider
+ * @return a handle
+ * @throws IOException if an error occurs
+ */
+ public static Closeable mountTemp(VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+ {
+ boolean ok = false;
+ final TempDir tempDir = tempFileProvider.createTempDir("tmpfs");
+ try {
+ final Closeable closeable = doMount(new RealFileSystem(tempDir.getRoot()), mountPoint);
+ ok = true;
+ return new Closeable()
+ {
+ public void close() throws IOException
+ {
+ VFSUtils.safeClose(closeable);
+ VFSUtils.safeClose(tempDir);
+ }
+ };
+ } finally {
+ if (! ok) {
+ VFSUtils.safeClose(tempDir);
+ }
+ }
+ }
+
+ /**
+ * Create and mount an expanded zip file in a temporary file system, returning a single handle which will unmount and
+ * close the filesystem when closed.
+ *
+ * @param zipFile the zip file to mount
+ * @param mountPoint the point at which the filesystem should be mounted
+ * @param tempFileProvider the temporary file provider
+ * @return a handle
+ * @throws IOException if an error occurs
+ */
+ public static Closeable mountZipExpanded(File zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+ {
+ boolean ok = false;
+ final TempDir tempDir = tempFileProvider.createTempDir(zipFile.getName());
+ try {
+ final File rootFile = tempDir.getRoot();
+ unzip(zipFile, rootFile);
+ final Closeable closeable = doMount(new RealFileSystem(rootFile), mountPoint);
+ ok = true;
+ return new Closeable()
+ {
+ public void close() throws IOException
+ {
+ VFSUtils.safeClose(closeable);
+ VFSUtils.safeClose(tempDir);
+ }
+ };
+ } finally {
+ if (! ok) {
+ VFSUtils.safeClose(tempDir);
+ }
+ }
+ }
+
+ /**
+ * Create and mount an expanded zip file in a temporary file system, returning a single handle which will unmount and
+ * close the filesystem when closed. The given zip data stream is closed.
+ *
+ * @param zipData an input stream containing the zip data
+ * @param zipName the name of the archive
+ * @param mountPoint the point at which the filesystem should be mounted
+ * @param tempFileProvider the temporary file provider
+ * @return a handle
+ * @throws IOException if an error occurs
+ */
+ public static Closeable mountZipExpanded(InputStream zipData, String zipName, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+ {
+ try {
+ boolean ok = false;
+ final TempDir tempDir = tempFileProvider.createTempDir(zipName);
+ try {
+ final File zipFile = File.createTempFile(zipName + "-", ".tmp");
+ try {
+ final FileOutputStream os = new FileOutputStream(zipFile);
+ try {
+ // allow an error on close to terminate the unzip
+ VFSUtils.copyStream(zipData, os);
+ zipData.close();
+ os.close();
+ } finally {
+ VFSUtils.safeClose(zipData);
+ VFSUtils.safeClose(os);
+ }
+ final File rootFile = tempDir.getRoot();
+ unzip(zipFile, rootFile);
+ final Closeable closeable = doMount(new RealFileSystem(rootFile), mountPoint);
+ ok = true;
+ return new Closeable()
+ {
+ public void close() throws IOException
+ {
+ VFSUtils.safeClose(closeable);
+ VFSUtils.safeClose(tempDir);
+ }
+ };
+ } finally {
+ zipFile.delete();
+ }
+ } finally {
+ if (! ok) {
+ VFSUtils.safeClose(tempDir);
+ }
+ }
+ } finally {
+ VFSUtils.safeClose(zipData);
+ }
+ }
+
+ /**
+ * Expand a zip file to a destination directory. The directory must exist. If an error occurs, the destination
+ * directory may contain a partially-extracted archive, so cleanup is up to the caller.
+ *
+ * @param zipFile the zip file
+ * @param destDir the destination directory
+ * @throws IOException if an error occurs
+ */
+ public static void unzip(File zipFile, File destDir) throws IOException
+ {
+ final ZipFile zip = new ZipFile(zipFile);
+ try {
+ final Set<File> createdDirs = new HashSet<File>();
+ final Enumeration<? extends ZipEntry> entries = zip.entries();
+ FILES_LOOP: while (entries.hasMoreElements()) {
+ final ZipEntry zipEntry = entries.nextElement();
+ final String name = zipEntry.getName();
+ final List<String> tokens = PathTokenizer.getTokens(name);
+ File current = destDir;
+ for (Iterator<String> it = tokens.iterator(); it.hasNext();)
+ {
+ String token = it.next();
+ if (PathTokenizer.isCurrentToken(token) || PathTokenizer.isReverseToken(token))
+ {
+ // invalid file; skip it!
+ continue FILES_LOOP;
+ }
+ current = new File(current, token);
+ if ((it.hasNext() || zipEntry.isDirectory()) && createdDirs.add(current))
+ {
+ current.mkdir();
+ }
+ }
+ if (! zipEntry.isDirectory()) {
+ final InputStream is = zip.getInputStream(zipEntry);
+ try {
+ final FileOutputStream os = new FileOutputStream(current);
+ try {
+ VFSUtils.copyStream(is, os);
+ // allow an error on close to terminate the unzip
+ is.close();
+ os.close();
+ } finally {
+ VFSUtils.safeClose(os);
+ }
+ } finally {
+ VFSUtils.safeClose(is);
+ }
+ }
+ }
+ } finally {
+ VFSUtils.safeClose(zip);
+ }
+ }
+
@SuppressWarnings({ "unchecked" })
private static <E> Set<E> emptyRemovableSet() {
return EMPTY_REMOVABLE_SET;
Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFSUtils.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFSUtils.java 2009-07-28 22:50:03 UTC (rev 91748)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFSUtils.java 2009-07-28 23:14:21 UTC (rev 91749)
@@ -35,6 +35,7 @@
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
+import java.util.zip.ZipFile;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
@@ -479,4 +480,20 @@
safeClose(closeable);
}
}
+
+ /**
+ * Safely close some resource without throwing an exception. Any exception will be logged at TRACE level.
+ *
+ * @param zipFile the resource
+ */
+ public static void safeClose(final ZipFile zipFile)
+ {
+ if (zipFile != null) try {
+ zipFile.close();
+ }
+ catch (Exception e)
+ {
+ log.trace("Failed to close resource", e);
+ }
+ }
}
Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/RealFileSystem.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/RealFileSystem.java 2009-07-28 22:50:03 UTC (rev 91748)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/RealFileSystem.java 2009-07-28 23:14:21 UTC (rev 91749)
@@ -31,27 +31,42 @@
import java.util.List;
import java.util.Arrays;
+/**
+ * A real filesystem.
+ */
public final class RealFileSystem implements FileSystem
{
+
+ /**
+ * The root real filesystem (singleton instance).
+ */
public static final RealFileSystem ROOT_INSTANCE = new RealFileSystem(new File(""));
private final File realRoot;
- private RealFileSystem(File realRoot)
+ /**
+ * Construct a real filesystem with the given real root.
+ *
+ * @param realRoot the real root
+ */
+ public RealFileSystem(File realRoot)
{
this.realRoot = realRoot;
}
+ /** {@inheritDoc} */
public InputStream openInputStream(VirtualFile mountPoint, VirtualFile target) throws IOException
{
return new FileInputStream(getFile(mountPoint, target));
}
+ /** {@inheritDoc} */
public boolean isReadOnly()
{
return false;
}
+ /** {@inheritDoc} */
public File getFile(VirtualFile mountPoint, VirtualFile target) throws IOException
{
if (mountPoint == target) {
@@ -61,36 +76,43 @@
}
}
+ /** {@inheritDoc} */
public boolean delete(VirtualFile mountPoint, VirtualFile target) throws IOException
{
return getFile(mountPoint, target).delete();
}
+ /** {@inheritDoc} */
public long getSize(VirtualFile mountPoint, VirtualFile target) throws IOException
{
return getFile(mountPoint, target).length();
}
+ /** {@inheritDoc} */
public long getLastModified(VirtualFile mountPoint, VirtualFile target) throws IOException
{
return getFile(mountPoint, target).lastModified();
}
+ /** {@inheritDoc} */
public boolean exists(VirtualFile mountPoint, VirtualFile target) throws IOException
{
return getFile(mountPoint, target).exists();
}
+ /** {@inheritDoc} */
public boolean isDirectory(VirtualFile mountPoint, VirtualFile target) throws IOException
{
return getFile(mountPoint, target).isDirectory();
}
+ /** {@inheritDoc} */
public List<String> getDirectoryEntries(VirtualFile mountPoint, VirtualFile target) throws IOException
{
return Arrays.asList(getFile(mountPoint, target).list());
}
+ /** {@inheritDoc} */
public void close() throws IOException
{
// no operation - the real FS can't be closed
More information about the jboss-cvs-commits
mailing list