< prev index next >

make/src/classes/build/tools/module/ModuleArchive.java

Print this page

        

*** 24,42 **** */ package build.tools.module; import jdk.internal.jimage.Archive; - import jdk.internal.jimage.Resource; import java.io.IOException; import java.io.InputStream; - import java.io.OutputStream; import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; ! import java.util.function.Consumer; /** * An Archive backed by an exploded representation on disk. */ public class ModuleArchive implements Archive { --- 24,44 ---- */ package build.tools.module; import jdk.internal.jimage.Archive; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; ! import java.util.ArrayList; ! import java.util.List; ! import java.util.stream.Collectors; ! import java.util.stream.Stream; ! import jdk.internal.jimage.Archive.Entry.EntryType; /** * An Archive backed by an exploded representation on disk. */ public class ModuleArchive implements Archive {
*** 44,53 **** --- 46,57 ---- private final Path cmds; private final Path libs; private final Path configs; private final String moduleName; + private final List<InputStream> opened = new ArrayList<>(); + public ModuleArchive(String moduleName, Path classes, Path cmds, Path libs, Path configs) { this.moduleName = moduleName; this.classes = classes; this.cmds = cmds;
*** 59,242 **** public String moduleName() { return moduleName; } @Override ! public void visitResources(Consumer<Resource> consumer) { ! if (classes == null) ! return; ! try{ ! Files.walk(classes) ! .sorted() ! .filter(p -> !Files.isDirectory(p) ! && !classes.relativize(p).toString().startsWith("_the.") ! && !classes.relativize(p).toString().equals("javac_state")) ! .map(this::toResource) ! .forEach(consumer::accept); ! } catch (IOException ioe) { ! throw new UncheckedIOException(ioe); ! } } ! private Resource toResource(Path path) { try { ! return new Resource(classes.relativize(path).toString().replace('\\','/'), ! Files.size(path), ! 0 /* no compression support yet */); ! } catch (IOException ioe) { ! throw new UncheckedIOException(ioe); } } ! ! private enum Section { ! CLASSES, ! CMDS, ! LIBS, ! CONFIGS } @Override ! public void visitEntries(Consumer<Entry> consumer) { ! try{ ! if (classes != null) ! Files.walk(classes) ! .sorted() .filter(p -> !Files.isDirectory(p) && !classes.relativize(p).toString().startsWith("_the.") && !classes.relativize(p).toString().equals("javac_state")) ! .map(p -> toEntry(p, classes, Section.CLASSES)) ! .forEach(consumer::accept); ! if (cmds != null) ! Files.walk(cmds) .filter(p -> !Files.isDirectory(p)) ! .map(p -> toEntry(p, cmds, Section.CMDS)) ! .forEach(consumer::accept); ! if (libs != null) ! Files.walk(libs) .filter(p -> !Files.isDirectory(p)) ! .map(p -> toEntry(p, libs, Section.LIBS)) ! .forEach(consumer::accept); ! if (configs != null) ! Files.walk(configs) .filter(p -> !Files.isDirectory(p)) ! .map(p -> toEntry(p, configs, Section.CONFIGS)) ! .forEach(consumer::accept); } catch (IOException ioe) { throw new UncheckedIOException(ioe); } } ! private static class FileEntry implements Entry { ! private final String name; ! private final InputStream is; private final boolean isDirectory; ! private final Section section; ! FileEntry(String name, InputStream is, ! boolean isDirectory, Section section) { ! this.name = name; ! this.is = is; this.isDirectory = isDirectory; ! this.section = section; ! } ! public String getName() { ! return name; ! } ! public Section getSection() { ! return section; ! } ! public InputStream getInputStream() { ! return is; } public boolean isDirectory() { return isDirectory; } - } - - private Entry toEntry(Path entryPath, Path basePath, Section section) { - try { - return new FileEntry(basePath.relativize(entryPath).toString().replace('\\', '/'), - Files.newInputStream(entryPath), false, - section); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } @Override ! public Consumer<Entry> defaultImageWriter(Path path, OutputStream out) { ! return new DefaultEntryWriter(path, out); ! } ! ! private static class DefaultEntryWriter implements Consumer<Archive.Entry> { ! private final Path root; ! private final OutputStream out; ! ! DefaultEntryWriter(Path root, OutputStream out) { ! this.root = root; ! this.out = out; } @Override ! public void accept(Archive.Entry entry) { ! try { ! FileEntry e = (FileEntry)entry; ! Section section = e.getSection(); ! String filename = e.getName(); ! ! try (InputStream in = entry.getInputStream()) { ! switch (section) { ! case CLASSES: ! if (!filename.startsWith("_the.") && !filename.equals("javac_state")) ! writeEntry(in); ! break; ! case LIBS: ! writeEntry(in, destFile(nativeDir(filename), filename)); ! break; ! case CMDS: ! Path path = destFile("bin", filename); ! writeEntry(in, path); ! path.toFile().setExecutable(true, false); ! break; ! case CONFIGS: ! writeEntry(in, destFile("conf", filename)); ! break; ! default: ! throw new InternalError("unexpected entry: " + filename); ! } ! } ! } catch (IOException x) { ! throw new UncheckedIOException(x); } } ! private Path destFile(String dir, String filename) { ! return root.resolve(dir).resolve(filename); ! } ! ! private static void writeEntry(InputStream in, Path dstFile) throws IOException { ! if (Files.notExists(dstFile.getParent())) ! Files.createDirectories(dstFile.getParent()); ! Files.copy(in, dstFile); ! } ! ! private void writeEntry(InputStream in) throws IOException { ! byte[] buf = new byte[8192]; ! int n; ! while ((n = in.read(buf)) > 0) ! out.write(buf, 0, n); ! } ! ! private static String nativeDir(String filename) { ! if (System.getProperty("os.name").startsWith("Windows")) { ! if (filename.endsWith(".dll") || filename.endsWith(".diz") ! || filename.endsWith(".pdb") || filename.endsWith(".map")) { ! return "bin"; ! } else { ! return "lib"; ! } ! } else { ! return "lib"; ! } } } } --- 63,183 ---- public String moduleName() { return moduleName; } @Override ! public void open() throws IOException { ! // NOOP } ! @Override ! public void close() throws IOException { ! IOException e = null; ! for (InputStream stream : opened) { try { ! stream.close(); ! } catch (IOException ex) { ! if (e == null) { ! e = ex; ! } else { ! e.addSuppressed(ex); } } ! } ! if (e != null) { ! throw e; ! } } @Override ! public Stream<Entry> entries() { ! List<Entry> entries = new ArrayList<>(); ! try { ! /* ! * This code should be revisited to avoid buffering of the entries. ! * 1) Do we really need sorting classes? This force buffering of entries. ! * libs, cmds and configs are not sorted. ! * 2) I/O streams should be concatenated instead of buffering into ! * entries list. ! * 3) Close I/O streams in a close handler. ! */ ! if (classes != null) { ! try (Stream<Path> stream = Files.walk(classes)) { ! entries.addAll(stream .filter(p -> !Files.isDirectory(p) && !classes.relativize(p).toString().startsWith("_the.") && !classes.relativize(p).toString().equals("javac_state")) ! .sorted() ! .map(p -> toEntry(p, classes, EntryType.CLASS_OR_RESOURCE)) ! .collect(Collectors.toList())); ! } ! } ! if (cmds != null) { ! try (Stream<Path> stream = Files.walk(cmds)) { ! entries.addAll(stream .filter(p -> !Files.isDirectory(p)) ! .map(p -> toEntry(p, cmds, EntryType.NATIVE_CMD)) ! .collect(Collectors.toList())); ! } ! } ! if (libs != null) { ! try (Stream<Path> stream = Files.walk(libs)) { ! entries.addAll(stream .filter(p -> !Files.isDirectory(p)) ! .map(p -> toEntry(p, libs, EntryType.NATIVE_LIB)) ! .collect(Collectors.toList())); ! } ! } ! if (configs != null) { ! try (Stream<Path> stream = Files.walk(configs)) { ! entries.addAll(stream .filter(p -> !Files.isDirectory(p)) ! .map(p -> toEntry(p, configs, EntryType.CONFIG)) ! .collect(Collectors.toList())); ! } ! } } catch (IOException ioe) { throw new UncheckedIOException(ioe); } + return entries.stream(); } ! private class FileEntry extends Entry { private final boolean isDirectory; ! private final long size; ! private final Path entryPath; ! FileEntry(Path entryPath, String path, EntryType type, ! boolean isDirectory, long size) { ! super(ModuleArchive.this, path, path, type); ! this.entryPath = entryPath; this.isDirectory = isDirectory; ! this.size = size; } + public boolean isDirectory() { return isDirectory; } @Override ! public long size() { ! return size; } @Override ! public InputStream stream() throws IOException { ! InputStream stream = Files.newInputStream(entryPath); ! opened.add(stream); ! return stream; } } ! private Entry toEntry(Path entryPath, Path basePath, EntryType section) { ! try { ! String path = basePath.relativize(entryPath).toString().replace('\\', '/'); ! return new FileEntry(entryPath, path, section, ! false, Files.size(entryPath)); ! } catch (IOException e) { ! throw new UncheckedIOException(e); } } }
< prev index next >