--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java Wed Dec 14 20:23:24 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,443 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.module;
-
-import java.io.File;
-import java.io.IOError;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.function.Supplier;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import java.util.zip.ZipFile;
-
-import jdk.internal.jmod.JmodFile;
-import jdk.internal.misc.JavaLangAccess;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.module.ModuleBootstrap;
-import jdk.internal.module.ModuleHashes;
-import jdk.internal.module.ModuleHashes.HashSupplier;
-import jdk.internal.module.ModulePatcher;
-import jdk.internal.util.jar.VersionedStream;
-import sun.net.www.ParseUtil;
-
-
-/**
- * A factory for creating ModuleReference implementations where the modules are
- * packaged as modular JAR file, JMOD files or where the modules are exploded
- * on the file system.
- */
-
-class ModuleReferences {
-
- private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
-
- private ModuleReferences() { }
-
- /**
- * Creates a ModuleReference to a module or to patched module when
- * creating modules for the boot Layer and --patch-module is specified.
- */
- private static ModuleReference newModule(ModuleDescriptor md,
- URI uri,
- Supplier<ModuleReader> supplier,
- HashSupplier hasher) {
-
- ModuleReference mref = new ModuleReference(md, uri, supplier, hasher);
- if (JLA.getBootLayer() == null)
- mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
-
- return mref;
- }
-
- /**
- * Creates a ModuleReference to a module packaged as a modular JAR.
- */
- static ModuleReference newJarModule(ModuleDescriptor md, Path file) {
- URI uri = file.toUri();
- Supplier<ModuleReader> supplier = () -> new JarModuleReader(file, uri);
- HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
- return newModule(md, uri, supplier, hasher);
- }
-
- /**
- * Creates a ModuleReference to a module packaged as a JMOD.
- */
- static ModuleReference newJModModule(ModuleDescriptor md, Path file) {
- URI uri = file.toUri();
- Supplier<ModuleReader> supplier = () -> new JModModuleReader(file, uri);
- HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
- return newModule(md, file.toUri(), supplier, hasher);
- }
-
- /**
- * Creates a ModuleReference to an exploded module.
- */
- static ModuleReference newExplodedModule(ModuleDescriptor md, Path dir) {
- Supplier<ModuleReader> supplier = () -> new ExplodedModuleReader(dir);
- return newModule(md, dir.toUri(), supplier, null);
- }
-
-
- /**
- * A base module reader that encapsulates machinery required to close the
- * module reader safely.
- */
- static abstract class SafeCloseModuleReader implements ModuleReader {
-
- // RW lock to support safe close
- private final ReadWriteLock lock = new ReentrantReadWriteLock();
- private final Lock readLock = lock.readLock();
- private final Lock writeLock = lock.writeLock();
- private boolean closed;
-
- SafeCloseModuleReader() { }
-
- /**
- * Returns a URL to resource. This method is invoked by the find
- * method to do the actual work of finding the resource.
- */
- abstract Optional<URI> implFind(String name) throws IOException;
-
- /**
- * Returns an input stream for reading a resource. This method is
- * invoked by the open method to do the actual work of opening
- * an input stream to the resource.
- */
- abstract Optional<InputStream> implOpen(String name) throws IOException;
-
- /**
- * Returns a stream of the names of resources in the module. This
- * method is invoked by the list method to do the actual work of
- * creating the stream.
- */
- abstract Stream<String> implList() throws IOException;
-
- /**
- * Closes the module reader. This method is invoked by close to do the
- * actual work of closing the module reader.
- */
- abstract void implClose() throws IOException;
-
- @Override
- public final Optional<URI> find(String name) throws IOException {
- readLock.lock();
- try {
- if (!closed) {
- return implFind(name);
- } else {
- throw new IOException("ModuleReader is closed");
- }
- } finally {
- readLock.unlock();
- }
- }
-
-
- @Override
- public final Optional<InputStream> open(String name) throws IOException {
- readLock.lock();
- try {
- if (!closed) {
- return implOpen(name);
- } else {
- throw new IOException("ModuleReader is closed");
- }
- } finally {
- readLock.unlock();
- }
- }
-
- @Override
- public final Stream<String> list() throws IOException {
- readLock.lock();
- try {
- if (!closed) {
- return implList();
- } else {
- throw new IOException("ModuleReader is closed");
- }
- } finally {
- readLock.unlock();
- }
- }
-
- @Override
- public final void close() throws IOException {
- writeLock.lock();
- try {
- if (!closed) {
- closed = true;
- implClose();
- }
- } finally {
- writeLock.unlock();
- }
- }
- }
-
-
- /**
- * A ModuleReader for a modular JAR file.
- */
- static class JarModuleReader extends SafeCloseModuleReader {
- private final JarFile jf;
- private final URI uri;
-
- static JarFile newJarFile(Path path) {
- try {
- return new JarFile(path.toFile(),
- true, // verify
- ZipFile.OPEN_READ,
- JarFile.runtimeVersion());
- } catch (IOException ioe) {
- throw new UncheckedIOException(ioe);
- }
- }
-
- JarModuleReader(Path path, URI uri) {
- this.jf = newJarFile(path);
- this.uri = uri;
- }
-
- private JarEntry getEntry(String name) {
- return jf.getJarEntry(Objects.requireNonNull(name));
- }
-
- @Override
- Optional<URI> implFind(String name) throws IOException {
- JarEntry je = getEntry(name);
- if (je != null) {
- if (jf.isMultiRelease())
- name = SharedSecrets.javaUtilJarAccess().getRealName(jf, je);
- String encodedPath = ParseUtil.encodePath(name, false);
- String uris = "jar:" + uri + "!/" + encodedPath;
- return Optional.of(URI.create(uris));
- } else {
- return Optional.empty();
- }
- }
-
- @Override
- Optional<InputStream> implOpen(String name) throws IOException {
- JarEntry je = getEntry(name);
- if (je != null) {
- return Optional.of(jf.getInputStream(je));
- } else {
- return Optional.empty();
- }
- }
-
- @Override
- Stream<String> implList() throws IOException {
- // take snapshot to avoid async close
- List<String> names = VersionedStream.stream(jf)
- .filter(e -> !e.isDirectory())
- .map(JarEntry::getName)
- .collect(Collectors.toList());
- return names.stream();
- }
-
- @Override
- void implClose() throws IOException {
- jf.close();
- }
- }
-
-
- /**
- * A ModuleReader for a JMOD file.
- */
- static class JModModuleReader extends SafeCloseModuleReader {
- private final JmodFile jf;
- private final URI uri;
-
- static JmodFile newJmodFile(Path path) {
- try {
- return new JmodFile(path);
- } catch (IOException ioe) {
- throw new UncheckedIOException(ioe);
- }
- }
-
- JModModuleReader(Path path, URI uri) {
- this.jf = newJmodFile(path);
- this.uri = uri;
- }
-
- private JmodFile.Entry getEntry(String name) {
- Objects.requireNonNull(name);
- return jf.getEntry(JmodFile.Section.CLASSES, name);
- }
-
- @Override
- Optional<URI> implFind(String name) {
- JmodFile.Entry je = getEntry(name);
- if (je != null) {
- String encodedPath = ParseUtil.encodePath(name, false);
- String uris = "jmod:" + uri + "!/" + encodedPath;
- return Optional.of(URI.create(uris));
- } else {
- return Optional.empty();
- }
- }
-
- @Override
- Optional<InputStream> implOpen(String name) throws IOException {
- JmodFile.Entry je = getEntry(name);
- if (je != null) {
- return Optional.of(jf.getInputStream(je));
- } else {
- return Optional.empty();
- }
- }
-
- @Override
- Stream<String> implList() throws IOException {
- // take snapshot to avoid async close
- List<String> names = jf.stream()
- .filter(e -> e.section() == JmodFile.Section.CLASSES)
- .map(JmodFile.Entry::name)
- .collect(Collectors.toList());
- return names.stream();
- }
-
- @Override
- void implClose() throws IOException {
- jf.close();
- }
- }
-
-
- /**
- * A ModuleReader for an exploded module.
- */
- static class ExplodedModuleReader implements ModuleReader {
- private final Path dir;
- private volatile boolean closed;
-
- ExplodedModuleReader(Path dir) {
- this.dir = dir;
-
- // when running with a security manager then check that the caller
- // has access to the directory.
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- boolean unused = Files.isDirectory(dir);
- }
- }
-
- /**
- * Returns a Path to access to the given resource.
- */
- private Path toPath(String name) {
- Path path = Paths.get(name.replace('/', File.separatorChar));
- if (path.getRoot() == null) {
- return dir.resolve(path);
- } else {
- // drop the root component so that the resource is
- // located relative to the module directory
- int n = path.getNameCount();
- return (n > 0) ? dir.resolve(path.subpath(0, n)) : null;
- }
- }
-
- /**
- * Throws IOException if the module reader is closed;
- */
- private void ensureOpen() throws IOException {
- if (closed) throw new IOException("ModuleReader is closed");
- }
-
- @Override
- public Optional<URI> find(String name) throws IOException {
- ensureOpen();
- Path path = toPath(name);
- if (path != null && Files.isRegularFile(path)) {
- try {
- return Optional.of(path.toUri());
- } catch (IOError e) {
- throw (IOException) e.getCause();
- }
- } else {
- return Optional.empty();
- }
- }
-
- @Override
- public Optional<InputStream> open(String name) throws IOException {
- ensureOpen();
- Path path = toPath(name);
- if (path != null && Files.isRegularFile(path)) {
- return Optional.of(Files.newInputStream(path));
- } else {
- return Optional.empty();
- }
- }
-
- @Override
- public Optional<ByteBuffer> read(String name) throws IOException {
- ensureOpen();
- Path path = toPath(name);
- if (path != null && Files.isRegularFile(path)) {
- return Optional.of(ByteBuffer.wrap(Files.readAllBytes(path)));
- } else {
- return Optional.empty();
- }
- }
-
- @Override
- public Stream<String> list() throws IOException {
- ensureOpen();
- // sym links not followed
- return Files.find(dir, Integer.MAX_VALUE,
- (path, attrs) -> attrs.isRegularFile())
- .map(f -> dir.relativize(f)
- .toString()
- .replace(File.separatorChar, '/'));
- }
-
- @Override
- public void close() {
- closed = true;
- }
- }
-
-}