/* * Copyright 2015-2017 the original author or authors. * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html */ package org.junit.platform.commons.util; import static java.util.Collections.emptyMap; import java.io.Closeable; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; import java.util.function.Function; final class CloseablePath implements Closeable { private static final String FILE_URI_SCHEME = "file"; private static final String JAR_URI_SCHEME = "jar"; private static final String JAR_FILE_EXTENSION = ".jar"; private static final String JAR_URI_SEPARATOR = "!"; private static final Closeable NULL_CLOSEABLE = () -> { }; private final Path path; private final Closeable delegate; static CloseablePath create(URI uri) throws IOException, URISyntaxException { if (JAR_URI_SCHEME.equals(uri.getScheme())) { String[] parts = uri.toString().split(JAR_URI_SEPARATOR); String jarUri = parts[0]; String jarEntry = parts[1]; return createForJarFileSystem(new URI(jarUri), fileSystem -> fileSystem.getPath(jarEntry)); } if (uri.getScheme().equals(FILE_URI_SCHEME) && uri.getPath().endsWith(JAR_FILE_EXTENSION)) { return createForJarFileSystem(new URI(JAR_URI_SCHEME + ':' + uri), fileSystem -> fileSystem.getRootDirectories().iterator().next()); } return new CloseablePath(Paths.get(uri), NULL_CLOSEABLE); } private static CloseablePath createForJarFileSystem(URI jarUri, Function<FileSystem, Path> pathProvider) throws IOException { FileSystem fileSystem = FileSystems.newFileSystem(jarUri, emptyMap()); Path path = pathProvider.apply(fileSystem); return new CloseablePath(path, fileSystem); } private CloseablePath(Path path, Closeable delegate) { this.path = path; this.delegate = delegate; } public Path getPath() { return path; } @Override public void close() throws IOException { delegate.close(); } }