jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java
changeset 41817 b90ad1de93ea
parent 41555 8a2a5a88376a
child 42338 a60f280f803c
equal deleted inserted replaced
41816:07e906f1a20b 41817:b90ad1de93ea
    30 import java.io.InputStream;
    30 import java.io.InputStream;
    31 import java.io.UncheckedIOException;
    31 import java.io.UncheckedIOException;
    32 import java.net.URI;
    32 import java.net.URI;
    33 import java.net.URLConnection;
    33 import java.net.URLConnection;
    34 import java.nio.ByteBuffer;
    34 import java.nio.ByteBuffer;
       
    35 import java.util.ArrayDeque;
    35 import java.util.Collections;
    36 import java.util.Collections;
       
    37 import java.util.Deque;
    36 import java.util.HashMap;
    38 import java.util.HashMap;
    37 import java.util.HashSet;
    39 import java.util.HashSet;
       
    40 import java.util.Iterator;
    38 import java.util.Map;
    41 import java.util.Map;
    39 import java.util.Objects;
    42 import java.util.Objects;
    40 import java.util.Optional;
    43 import java.util.Optional;
    41 import java.util.Set;
    44 import java.util.Set;
       
    45 import java.util.Spliterator;
       
    46 import java.util.function.Consumer;
    42 import java.util.function.Supplier;
    47 import java.util.function.Supplier;
       
    48 import java.util.stream.Stream;
       
    49 import java.util.stream.StreamSupport;
    43 
    50 
    44 import jdk.internal.jimage.ImageLocation;
    51 import jdk.internal.jimage.ImageLocation;
    45 import jdk.internal.jimage.ImageReader;
    52 import jdk.internal.jimage.ImageReader;
    46 import jdk.internal.jimage.ImageReaderFactory;
    53 import jdk.internal.jimage.ImageReaderFactory;
    47 import jdk.internal.misc.JavaNetUriAccess;
    54 import jdk.internal.misc.JavaNetUriAccess;
    60  * ConcealedPackages attribute.
    67  * ConcealedPackages attribute.
    61  */
    68  */
    62 
    69 
    63 class SystemModuleFinder implements ModuleFinder {
    70 class SystemModuleFinder implements ModuleFinder {
    64 
    71 
       
    72     private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
       
    73 
    65     private static final PerfCounter initTime
    74     private static final PerfCounter initTime
    66         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.initTime");
    75         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.initTime");
    67     private static final PerfCounter moduleCount
    76     private static final PerfCounter moduleCount
    68         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.modules");
    77         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.modules");
    69     private static final PerfCounter packageCount
    78     private static final PerfCounter packageCount
    70         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.packages");
    79         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.packages");
    71     private static final PerfCounter exportsCount
    80     private static final PerfCounter exportsCount
    72         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");
    81         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");
    73     // ImageReader used to access all modules in the image
    82     // ImageReader used to access all modules in the image
    74     private static final ImageReader imageReader;
    83     private static final ImageReader imageReader;
    75 
       
    76     private static final JavaNetUriAccess jnua = SharedSecrets.getJavaNetUriAccess();
       
    77 
    84 
    78     // the set of modules in the run-time image
    85     // the set of modules in the run-time image
    79     private static final Set<ModuleReference> modules;
    86     private static final Set<ModuleReference> modules;
    80 
    87 
    81     // maps module name to module reference
    88     // maps module name to module reference
   168 
   175 
   169     private static ModuleReference toModuleReference(ModuleDescriptor md,
   176     private static ModuleReference toModuleReference(ModuleDescriptor md,
   170                                                      HashSupplier hash)
   177                                                      HashSupplier hash)
   171     {
   178     {
   172         String mn = md.name();
   179         String mn = md.name();
   173 
   180         URI uri = JNUA.create("jrt", "/".concat(mn));
   174         URI uri = jnua.create("jrt", "/".concat(mn));
       
   175 
   181 
   176         Supplier<ModuleReader> readerSupplier = new Supplier<>() {
   182         Supplier<ModuleReader> readerSupplier = new Supplier<>() {
   177             @Override
   183             @Override
   178             public ModuleReader get() {
   184             public ModuleReader get() {
   179                 return new ImageModuleReader(mn, uri);
   185                 return new ImageModuleReader(mn, uri);
   330             Objects.requireNonNull(bb);
   336             Objects.requireNonNull(bb);
   331             ImageReader.releaseByteBuffer(bb);
   337             ImageReader.releaseByteBuffer(bb);
   332         }
   338         }
   333 
   339 
   334         @Override
   340         @Override
       
   341         public Stream<String> list() throws IOException {
       
   342             if (closed)
       
   343                 throw new IOException("ModuleReader is closed");
       
   344 
       
   345             Spliterator<String> s = new ModuleContentSpliterator(module);
       
   346             return StreamSupport.stream(s, false);
       
   347         }
       
   348 
       
   349         @Override
   335         public void close() {
   350         public void close() {
   336             // nothing else to do
   351             // nothing else to do
   337             closed = true;
   352             closed = true;
   338         }
   353         }
   339     }
   354     }
   340 
   355 
       
   356     /**
       
   357      * A Spliterator for traversing the resources of a module linked into the
       
   358      * run-time image.
       
   359      */
       
   360     static class ModuleContentSpliterator implements Spliterator<String> {
       
   361         final String moduleRoot;
       
   362         final Deque<ImageReader.Node> stack;
       
   363         Iterator<ImageReader.Node> iterator;
       
   364 
       
   365         ModuleContentSpliterator(String module) throws IOException {
       
   366             moduleRoot = "/modules/" + module;
       
   367             stack = new ArrayDeque<>();
       
   368 
       
   369             // push the root node to the stack to get started
       
   370             ImageReader.Node dir = imageReader.findNode(moduleRoot);
       
   371             if (dir == null || !dir.isDirectory())
       
   372                 throw new IOException(moduleRoot + " not a directory");
       
   373             stack.push(dir);
       
   374             iterator = Collections.emptyIterator();
       
   375         }
       
   376 
       
   377         /**
       
   378          * Returns the name of the next non-directory node or {@code null} if
       
   379          * there are no remaining nodes to visit.
       
   380          */
       
   381         private String next() throws IOException {
       
   382             for (;;) {
       
   383                 while (iterator.hasNext()) {
       
   384                     ImageReader.Node node = iterator.next();
       
   385                     String name = node.getName();
       
   386                     if (node.isDirectory()) {
       
   387                         // build node
       
   388                         ImageReader.Node dir = imageReader.findNode(name);
       
   389                         assert dir.isDirectory();
       
   390                         stack.push(dir);
       
   391                     } else {
       
   392                         // strip /modules/$MODULE/ prefix
       
   393                         return name.substring(moduleRoot.length() + 1);
       
   394                     }
       
   395                 }
       
   396 
       
   397                 if (stack.isEmpty()) {
       
   398                     return null;
       
   399                 } else {
       
   400                     ImageReader.Node dir = stack.poll();
       
   401                     assert dir.isDirectory();
       
   402                     iterator = dir.getChildren().iterator();
       
   403                 }
       
   404             }
       
   405         }
       
   406 
       
   407         @Override
       
   408         public boolean tryAdvance(Consumer<? super String> action) {
       
   409             String next;
       
   410             try {
       
   411                 next = next();
       
   412             } catch (IOException ioe) {
       
   413                 throw new UncheckedIOException(ioe);
       
   414             }
       
   415             if (next != null) {
       
   416                 action.accept(next);
       
   417                 return true;
       
   418             } else {
       
   419                 return false;
       
   420             }
       
   421         }
       
   422 
       
   423         @Override
       
   424         public Spliterator<String> trySplit() {
       
   425             return null;
       
   426         }
       
   427 
       
   428         @Override
       
   429         public int characteristics() {
       
   430             return Spliterator.DISTINCT + Spliterator.NONNULL + Spliterator.IMMUTABLE;
       
   431         }
       
   432 
       
   433         @Override
       
   434         public long estimateSize() {
       
   435             return Long.MAX_VALUE;
       
   436         }
       
   437     }
   341 }
   438 }