< prev index next >

src/java.base/share/classes/jdk/internal/module/ModuleReferences.java

Print this page




  34 import java.lang.module.ModuleReference;
  35 import java.net.URI;
  36 import java.nio.ByteBuffer;
  37 import java.nio.file.Files;
  38 import java.nio.file.Path;
  39 import java.nio.file.Paths;
  40 import java.util.List;
  41 import java.util.Objects;
  42 import java.util.Optional;
  43 import java.util.concurrent.locks.Lock;
  44 import java.util.concurrent.locks.ReadWriteLock;
  45 import java.util.concurrent.locks.ReentrantReadWriteLock;
  46 import java.util.function.Supplier;
  47 import java.util.jar.JarEntry;
  48 import java.util.jar.JarFile;
  49 import java.util.stream.Collectors;
  50 import java.util.stream.Stream;
  51 import java.util.zip.ZipFile;
  52 
  53 import jdk.internal.jmod.JmodFile;

  54 import jdk.internal.misc.JavaLangAccess;
  55 import jdk.internal.misc.SharedSecrets;
  56 import jdk.internal.module.ModuleHashes.HashSupplier;
  57 import jdk.internal.util.jar.VersionedStream;
  58 import sun.net.www.ParseUtil;
  59 
  60 
  61 /**
  62  * A factory for creating ModuleReference implementations where the modules are
  63  * packaged as modular JAR file, JMOD files or where the modules are exploded
  64  * on the file system.
  65  */
  66 
  67 class ModuleReferences {
  68 
  69     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
  70 
  71     private ModuleReferences() { }
  72 
  73     /**


 226         private final JarFile jf;
 227         private final URI uri;
 228 
 229         static JarFile newJarFile(Path path) {
 230             try {
 231                 return new JarFile(path.toFile(),
 232                                    true,               // verify
 233                                    ZipFile.OPEN_READ,
 234                                    JarFile.runtimeVersion());
 235             } catch (IOException ioe) {
 236                 throw new UncheckedIOException(ioe);
 237             }
 238         }
 239 
 240         JarModuleReader(Path path, URI uri) {
 241             this.jf = newJarFile(path);
 242             this.uri = uri;
 243         }
 244 
 245         private JarEntry getEntry(String name) {
 246             return jf.getJarEntry(Objects.requireNonNull(name));

 247         }
 248 
 249         @Override
 250         Optional<URI> implFind(String name) throws IOException {
 251             JarEntry je = getEntry(name);
 252             if (je != null) {
 253                 if (jf.isMultiRelease())
 254                     name = SharedSecrets.javaUtilJarAccess().getRealName(jf, je);
 255                 String encodedPath = ParseUtil.encodePath(name, false);
 256                 String uris = "jar:" + uri + "!/" + encodedPath;
 257                 return Optional.of(URI.create(uris));
 258             } else {
 259                 return Optional.empty();
 260             }
 261         }
 262 
 263         @Override
 264         Optional<InputStream> implOpen(String name) throws IOException {
 265             JarEntry je = getEntry(name);
 266             if (je != null) {


 353 
 354     /**
 355      * A ModuleReader for an exploded module.
 356      */
 357     static class ExplodedModuleReader implements ModuleReader {
 358         private final Path dir;
 359         private volatile boolean closed;
 360 
 361         ExplodedModuleReader(Path dir) {
 362             this.dir = dir;
 363 
 364             // when running with a security manager then check that the caller
 365             // has access to the directory.
 366             SecurityManager sm = System.getSecurityManager();
 367             if (sm != null) {
 368                 boolean unused = Files.isDirectory(dir);
 369             }
 370         }
 371 
 372         /**
 373          * Returns a Path to access to the given resource.
 374          */
 375         private Path toPath(String name) {
 376             Path path = Paths.get(name.replace('/', File.separatorChar));
 377             if (path.getRoot() == null) {
 378                 return dir.resolve(path);
 379             } else {
 380                 // drop the root component so that the resource is
 381                 // located relative to the module directory
 382                 int n = path.getNameCount();
 383                 return (n > 0) ? dir.resolve(path.subpath(0, n)) : null;
 384             }
 385         }
 386 
 387         /**
 388          * Throws IOException if the module reader is closed;
 389          */
 390         private void ensureOpen() throws IOException {
 391             if (closed) throw new IOException("ModuleReader is closed");
 392         }
 393 
















 394         @Override
 395         public Optional<URI> find(String name) throws IOException {
 396             ensureOpen();
 397             Path path = toPath(name);
 398             if (path != null && Files.isRegularFile(path)) {
 399                 try {
 400                     return Optional.of(path.toUri());
 401                 } catch (IOError e) {
 402                     throw (IOException) e.getCause();
 403                 }
 404             } else {
 405                 return Optional.empty();
 406             }
 407         }
 408 
 409         @Override
 410         public Optional<InputStream> open(String name) throws IOException {
 411             ensureOpen();
 412             Path path = toPath(name);
 413             if (path != null && Files.isRegularFile(path)) {
 414                 return Optional.of(Files.newInputStream(path));
 415             } else {
 416                 return Optional.empty();
 417             }
 418         }
 419 
 420         @Override
 421         public Optional<ByteBuffer> read(String name) throws IOException {
 422             ensureOpen();
 423             Path path = toPath(name);
 424             if (path != null && Files.isRegularFile(path)) {
 425                 return Optional.of(ByteBuffer.wrap(Files.readAllBytes(path)));
 426             } else {
 427                 return Optional.empty();
 428             }
 429         }
 430 
 431         @Override
 432         public Stream<String> list() throws IOException {
 433             ensureOpen();
 434             // sym links not followed
 435             return Files.find(dir, Integer.MAX_VALUE,
 436                               (path, attrs) -> attrs.isRegularFile())
 437                     .map(f -> dir.relativize(f)
 438                                  .toString()
 439                                  .replace(File.separatorChar, '/'));
 440         }
 441 
 442         @Override
 443         public void close() {
 444             closed = true;


  34 import java.lang.module.ModuleReference;
  35 import java.net.URI;
  36 import java.nio.ByteBuffer;
  37 import java.nio.file.Files;
  38 import java.nio.file.Path;
  39 import java.nio.file.Paths;
  40 import java.util.List;
  41 import java.util.Objects;
  42 import java.util.Optional;
  43 import java.util.concurrent.locks.Lock;
  44 import java.util.concurrent.locks.ReadWriteLock;
  45 import java.util.concurrent.locks.ReentrantReadWriteLock;
  46 import java.util.function.Supplier;
  47 import java.util.jar.JarEntry;
  48 import java.util.jar.JarFile;
  49 import java.util.stream.Collectors;
  50 import java.util.stream.Stream;
  51 import java.util.zip.ZipFile;
  52 
  53 import jdk.internal.jmod.JmodFile;
  54 import jdk.internal.loader.ResourceHelper;
  55 import jdk.internal.misc.JavaLangAccess;
  56 import jdk.internal.misc.SharedSecrets;
  57 import jdk.internal.module.ModuleHashes.HashSupplier;
  58 import jdk.internal.util.jar.VersionedStream;
  59 import sun.net.www.ParseUtil;
  60 
  61 
  62 /**
  63  * A factory for creating ModuleReference implementations where the modules are
  64  * packaged as modular JAR file, JMOD files or where the modules are exploded
  65  * on the file system.
  66  */
  67 
  68 class ModuleReferences {
  69 
  70     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
  71 
  72     private ModuleReferences() { }
  73 
  74     /**


 227         private final JarFile jf;
 228         private final URI uri;
 229 
 230         static JarFile newJarFile(Path path) {
 231             try {
 232                 return new JarFile(path.toFile(),
 233                                    true,               // verify
 234                                    ZipFile.OPEN_READ,
 235                                    JarFile.runtimeVersion());
 236             } catch (IOException ioe) {
 237                 throw new UncheckedIOException(ioe);
 238             }
 239         }
 240 
 241         JarModuleReader(Path path, URI uri) {
 242             this.jf = newJarFile(path);
 243             this.uri = uri;
 244         }
 245 
 246         private JarEntry getEntry(String name) {
 247             JarEntry entry = jf.getJarEntry(Objects.requireNonNull(name));
 248             return (entry == null || entry.isDirectory()) ? null : entry;
 249         }
 250 
 251         @Override
 252         Optional<URI> implFind(String name) throws IOException {
 253             JarEntry je = getEntry(name);
 254             if (je != null) {
 255                 if (jf.isMultiRelease())
 256                     name = SharedSecrets.javaUtilJarAccess().getRealName(jf, je);
 257                 String encodedPath = ParseUtil.encodePath(name, false);
 258                 String uris = "jar:" + uri + "!/" + encodedPath;
 259                 return Optional.of(URI.create(uris));
 260             } else {
 261                 return Optional.empty();
 262             }
 263         }
 264 
 265         @Override
 266         Optional<InputStream> implOpen(String name) throws IOException {
 267             JarEntry je = getEntry(name);
 268             if (je != null) {


 355 
 356     /**
 357      * A ModuleReader for an exploded module.
 358      */
 359     static class ExplodedModuleReader implements ModuleReader {
 360         private final Path dir;
 361         private volatile boolean closed;
 362 
 363         ExplodedModuleReader(Path dir) {
 364             this.dir = dir;
 365 
 366             // when running with a security manager then check that the caller
 367             // has access to the directory.
 368             SecurityManager sm = System.getSecurityManager();
 369             if (sm != null) {
 370                 boolean unused = Files.isDirectory(dir);
 371             }
 372         }
 373 
 374         /**















 375          * Throws IOException if the module reader is closed;
 376          */
 377         private void ensureOpen() throws IOException {
 378             if (closed) throw new IOException("ModuleReader is closed");
 379         }
 380 
 381         /**
 382          * Returns a Path to access the given resource. Returns null if the
 383          * resource name does not convert to a file path that locates a regular
 384          * file in the module.
 385          */
 386         private Path toFilePath(String name) {
 387             Path path = ResourceHelper.toFilePath(name);
 388             if (path != null) {
 389                 Path file = dir.resolve(path);
 390                 if (Files.isRegularFile(file)) {
 391                     return file;
 392                 }
 393             }
 394             return null;
 395         }
 396 
 397         @Override
 398         public Optional<URI> find(String name) throws IOException {
 399             ensureOpen();
 400             Path path = toFilePath(name);
 401             if (path != null) {
 402                 try {
 403                     return Optional.of(path.toUri());
 404                 } catch (IOError e) {
 405                     throw (IOException) e.getCause();
 406                 }
 407             } else {
 408                 return Optional.empty();
 409             }
 410         }
 411 
 412         @Override
 413         public Optional<InputStream> open(String name) throws IOException {
 414             ensureOpen();
 415             Path path = toFilePath(name);
 416             if (path != null) {
 417                 return Optional.of(Files.newInputStream(path));
 418             } else {
 419                 return Optional.empty();
 420             }
 421         }
 422 
 423         @Override
 424         public Optional<ByteBuffer> read(String name) throws IOException {
 425             ensureOpen();
 426             Path path = toFilePath(name);
 427             if (path != null) {
 428                 return Optional.of(ByteBuffer.wrap(Files.readAllBytes(path)));
 429             } else {
 430                 return Optional.empty();
 431             }
 432         }
 433 
 434         @Override
 435         public Stream<String> list() throws IOException {
 436             ensureOpen();
 437             // sym links not followed
 438             return Files.find(dir, Integer.MAX_VALUE,
 439                               (path, attrs) -> attrs.isRegularFile())
 440                     .map(f -> dir.relativize(f)
 441                                  .toString()
 442                                  .replace(File.separatorChar, '/'));
 443         }
 444 
 445         @Override
 446         public void close() {
 447             closed = true;
< prev index next >