jdk/make/src/classes/build/tools/module/ModuleArchive.java
changeset 36511 9d0388c6b336
parent 36510 043f1af70518
child 36512 1b1dea65af3e
equal deleted inserted replaced
36510:043f1af70518 36511:9d0388c6b336
     1 /*
       
     2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package build.tools.module;
       
    27 
       
    28 import jdk.internal.jimage.Archive;
       
    29 
       
    30 import java.io.IOException;
       
    31 import java.io.InputStream;
       
    32 import java.io.UncheckedIOException;
       
    33 import java.nio.file.Files;
       
    34 import java.nio.file.Path;
       
    35 import java.util.ArrayList;
       
    36 import java.util.List;
       
    37 import java.util.stream.Collectors;
       
    38 import java.util.stream.Stream;
       
    39 import jdk.internal.jimage.Archive.Entry.EntryType;
       
    40 
       
    41 /**
       
    42  * An Archive backed by an exploded representation on disk.
       
    43  */
       
    44 public class ModuleArchive implements Archive {
       
    45     private final Path classes;
       
    46     private final Path cmds;
       
    47     private final Path libs;
       
    48     private final Path configs;
       
    49     private final String moduleName;
       
    50 
       
    51     private final List<InputStream> opened = new ArrayList<>();
       
    52 
       
    53     public ModuleArchive(String moduleName, Path classes, Path cmds,
       
    54                          Path libs, Path configs) {
       
    55         this.moduleName = moduleName;
       
    56         this.classes = classes;
       
    57         this.cmds = cmds;
       
    58         this.libs = libs;
       
    59         this.configs = configs;
       
    60     }
       
    61 
       
    62     @Override
       
    63     public String moduleName() {
       
    64         return moduleName;
       
    65     }
       
    66 
       
    67     @Override
       
    68     public void open() throws IOException {
       
    69         // NOOP
       
    70     }
       
    71 
       
    72     @Override
       
    73     public void close() throws IOException {
       
    74         IOException e = null;
       
    75         for (InputStream stream : opened) {
       
    76             try {
       
    77                 stream.close();
       
    78             } catch (IOException ex) {
       
    79                 if (e == null) {
       
    80                     e = ex;
       
    81                 } else {
       
    82                     e.addSuppressed(ex);
       
    83                 }
       
    84             }
       
    85         }
       
    86         if (e != null) {
       
    87             throw e;
       
    88         }
       
    89     }
       
    90 
       
    91     @Override
       
    92     public Stream<Entry> entries() {
       
    93         List<Entry> entries = new ArrayList<>();
       
    94         try {
       
    95             /*
       
    96              * This code should be revisited to avoid buffering of the entries.
       
    97              * 1) Do we really need sorting classes? This force buffering of entries.
       
    98              *    libs, cmds and configs are not sorted.
       
    99              * 2) I/O streams should be concatenated instead of buffering into
       
   100              *    entries list.
       
   101              * 3) Close I/O streams in a close handler.
       
   102              */
       
   103             if (classes != null) {
       
   104                 try (Stream<Path> stream = Files.walk(classes)) {
       
   105                     entries.addAll(stream
       
   106                             .filter(p -> !Files.isDirectory(p)
       
   107                                     && !classes.relativize(p).toString().startsWith("_the.")
       
   108                                     && !classes.relativize(p).toString().endsWith(".bc")
       
   109                                     && !classes.relativize(p).toString().equals("javac_state"))
       
   110                             .sorted()
       
   111                             .map(p -> toEntry(p, classes, EntryType.CLASS_OR_RESOURCE))
       
   112                             .collect(Collectors.toList()));
       
   113                 }
       
   114             }
       
   115             if (cmds != null) {
       
   116                 try (Stream<Path> stream = Files.walk(cmds)) {
       
   117                     entries.addAll(stream
       
   118                             .filter(p -> !Files.isDirectory(p))
       
   119                             .map(p -> toEntry(p, cmds, EntryType.NATIVE_CMD))
       
   120                             .collect(Collectors.toList()));
       
   121                 }
       
   122             }
       
   123             if (libs != null) {
       
   124                 try (Stream<Path> stream = Files.walk(libs)) {
       
   125                     entries.addAll(stream
       
   126                             .filter(p -> !Files.isDirectory(p))
       
   127                             .map(p -> toEntry(p, libs, EntryType.NATIVE_LIB))
       
   128                             .collect(Collectors.toList()));
       
   129                 }
       
   130             }
       
   131             if (configs != null) {
       
   132                 try (Stream<Path> stream = Files.walk(configs)) {
       
   133                 entries.addAll(stream
       
   134                         .filter(p -> !Files.isDirectory(p))
       
   135                         .map(p -> toEntry(p, configs, EntryType.CONFIG))
       
   136                         .collect(Collectors.toList()));
       
   137                 }
       
   138             }
       
   139         } catch (IOException ioe) {
       
   140             throw new UncheckedIOException(ioe);
       
   141         }
       
   142         return entries.stream();
       
   143     }
       
   144 
       
   145     private class FileEntry extends Entry {
       
   146         private final boolean isDirectory;
       
   147         private final long size;
       
   148         private final Path entryPath;
       
   149         FileEntry(Path entryPath, String path, EntryType type,
       
   150                   boolean isDirectory, long size) {
       
   151             super(ModuleArchive.this, path, path, type);
       
   152             this.entryPath = entryPath;
       
   153             this.isDirectory = isDirectory;
       
   154             this.size = size;
       
   155         }
       
   156 
       
   157         public boolean isDirectory() {
       
   158             return isDirectory;
       
   159         }
       
   160 
       
   161         @Override
       
   162         public long size() {
       
   163             return size;
       
   164         }
       
   165 
       
   166         @Override
       
   167         public InputStream stream() throws IOException {
       
   168             InputStream stream = Files.newInputStream(entryPath);
       
   169             opened.add(stream);
       
   170             return stream;
       
   171         }
       
   172     }
       
   173 
       
   174     private Entry toEntry(Path entryPath, Path basePath, EntryType section) {
       
   175         try {
       
   176             String path = basePath.relativize(entryPath).toString().replace('\\', '/');
       
   177             return new FileEntry(entryPath, path, section,
       
   178                     false, Files.size(entryPath));
       
   179         } catch (IOException e) {
       
   180             throw new UncheckedIOException(e);
       
   181         }
       
   182     }
       
   183 }
       
   184