diff --git a/.classpath b/.classpath
index 33e838fb..f45ae07a 100644
--- a/.classpath
+++ b/.classpath
@@ -27,5 +27,8 @@
+
+
+
diff --git a/build.xml b/build.xml
index cf864bcf..014e473c 100644
--- a/build.xml
+++ b/build.xml
@@ -168,6 +168,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ivy.xml b/ivy.xml
index 40f866b3..51c9d80c 100644
--- a/ivy.xml
+++ b/ivy.xml
@@ -19,6 +19,7 @@
+
diff --git a/source/META-INF/vfs-providers.xml b/source/META-INF/vfs-providers.xml
new file mode 100644
index 00000000..f7ccad42
--- /dev/null
+++ b/source/META-INF/vfs-providers.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/net/filebot/Main.java b/source/net/filebot/Main.java
index 3335daf7..8f67a602 100644
--- a/source/net/filebot/Main.java
+++ b/source/net/filebot/Main.java
@@ -145,6 +145,7 @@ public class Main {
System.setProperty("http.agent", String.format("%s %s", getApplicationName(), getApplicationVersion()));
System.setProperty("swing.crossplatformlaf", "javax.swing.plaf.nimbus.NimbusLookAndFeel");
System.setProperty("grape.root", new File(getApplicationFolder(), "grape").getAbsolutePath());
+ System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");
if (args.unixfs) {
System.setProperty("unixfs", "true");
diff --git a/source/net/filebot/archive/ApacheVFS.java b/source/net/filebot/archive/ApacheVFS.java
new file mode 100644
index 00000000..2d8b1cf6
--- /dev/null
+++ b/source/net/filebot/archive/ApacheVFS.java
@@ -0,0 +1,83 @@
+package net.filebot.archive;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.filebot.vfs.FileInfo;
+import net.filebot.vfs.SimpleFileInfo;
+
+import org.apache.commons.vfs2.AllFileSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSelector;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileType;
+import org.apache.commons.vfs2.VFS;
+
+public class ApacheVFS implements ArchiveExtractor, Closeable {
+
+ private static final FileSelector ALL_FILES = new AllFileSelector();
+
+ private final FileSystemManager fsm;
+ private final FileObject archive;
+
+ public ApacheVFS(File file) throws Exception {
+ if (!file.exists()) {
+ throw new FileNotFoundException(file.getAbsolutePath());
+ }
+
+ this.fsm = VFS.getManager();
+ this.archive = fsm.createFileSystem(fsm.toFileObject(file));
+ }
+
+ public List listFiles() throws Exception {
+ List paths = new ArrayList();
+ for (FileObject it : archive.findFiles(ALL_FILES)) {
+ if (it.getType() == FileType.FILE) {
+ // ignore leading / slash
+ paths.add(new SimpleFileInfo(it.getName().getPathDecoded().substring(1), it.getContent().getSize()));
+ }
+ }
+ return paths;
+ }
+
+ public void extract(File outputDir) throws Exception {
+ extract(outputDir, null);
+ }
+
+ public void extract(File outputDir, FileFilter filter) throws Exception {
+ fsm.toFileObject(outputDir).copyFrom(archive, filter == null ? ALL_FILES : new FileFilterSelector(filter));
+ }
+
+ @Override
+ public void close() throws IOException {
+ archive.close();
+ }
+
+ private static class FileFilterSelector implements FileSelector {
+
+ private final FileFilter filter;
+
+ public FileFilterSelector(FileFilter filter) {
+ this.filter = filter;
+ }
+
+ @Override
+ public boolean traverseDescendents(FileSelectInfo it) throws Exception {
+ return true;
+ }
+
+ @Override
+ public boolean includeFile(FileSelectInfo it) throws Exception {
+ // ignore leading / slash
+ return filter.accept(new File(it.getFile().getName().getPathDecoded().substring(1)));
+ }
+
+ }
+
+}
diff --git a/source/net/filebot/archive/Archive.java b/source/net/filebot/archive/Archive.java
index 64872e98..d27d358c 100644
--- a/source/net/filebot/archive/Archive.java
+++ b/source/net/filebot/archive/Archive.java
@@ -19,7 +19,7 @@ import net.filebot.vfs.FileInfo;
public class Archive implements Closeable {
public static enum Extractor {
- SevenZipNativeBindings, SevenZipExecutable;
+ SevenZipNativeBindings, SevenZipExecutable, ApacheVFS;
public ArchiveExtractor newInstance(File archive) throws Exception {
switch (this) {
@@ -27,6 +27,8 @@ public class Archive implements Closeable {
return new SevenZipNativeBindings(archive);
case SevenZipExecutable:
return new SevenZipExecutable(archive);
+ case ApacheVFS:
+ return new ApacheVFS(archive);
}
return null;
}