/* * Capsule * Copyright (c) 2014-2015, Parallel Universe Software Co. All rights reserved. * * This program and the accompanying materials are licensed under the terms * of the Eclipse Public License v1.0, available at * http://www.eclipse.org/legal/epl-v10.html */ package co.paralleluniverse.common; import static co.paralleluniverse.common.Exceptions.rethrow; import com.sun.nio.zipfs.ZipFileSystem; import com.sun.nio.zipfs.ZipFileSystemProvider; import java.io.IOException; import java.lang.reflect.Constructor; import java.nio.file.FileSystem; import java.nio.file.Path; import java.nio.file.spi.FileSystemProvider; import java.util.Collections; import java.util.Map; /** * Bypasses the check in ZipFileSystemProvider.newFileSystem that verifies that the given path is in the default FileSystem. * This is a JDK bug, fixed in JDK 8. See https://bugs.openjdk.java.net/browse/JDK-8004789 */ public final class ZipFS { private static final ZipFileSystemProvider ZIP_FILE_SYSTEM_PROVIDER = getZipFileSystemProvider(); private static final Constructor<ZipFileSystem> ZIP_FILE_SYSTEM_CONSTRUCTOR; static { try { Constructor<ZipFileSystem> c = ZipFileSystem.class.getDeclaredConstructor(ZipFileSystemProvider.class, Path.class, Map.class); c.setAccessible(true); ZIP_FILE_SYSTEM_CONSTRUCTOR = c; } catch (NoSuchMethodException e) { throw new AssertionError(e); } } private static ZipFileSystemProvider getZipFileSystemProvider() { for (FileSystemProvider fsr : FileSystemProvider.installedProviders()) { if (fsr instanceof ZipFileSystemProvider) return (ZipFileSystemProvider) fsr; } throw new AssertionError("Zip file system not installed!"); } public static FileSystem newZipFileSystem(Path path) throws IOException { // return FileSystems.newFileSystem(path, null); if (path.getFileSystem() instanceof ZipFileSystem) throw new IllegalArgumentException("Can't create a ZIP file system nested in a ZIP file system. (" + path + " is nested in " + path.getFileSystem() + ")"); try { return (ZipFileSystem) ZIP_FILE_SYSTEM_CONSTRUCTOR.newInstance(ZIP_FILE_SYSTEM_PROVIDER, path, Collections.emptyMap()); } catch (ReflectiveOperationException e) { throw new AssertionError(e); } catch(Exception e) { throw rethrow(e); } } private ZipFS() { } }