private static Map<FileLike, String> traverse(Collection<File> files) throws IOException { Collection<Path> paths = FluentIterable.from(files) .transform( new Function<File, Path>() { @Override public Path apply(File file) { return file.toPath(); } }) .toList(); final ImmutableMap.Builder<FileLike, String> completeList = ImmutableMap.builder(); ClasspathTraverser traverser = new DefaultClasspathTraverser(); ProjectFilesystem filesystem = new ProjectFilesystem(Paths.get(".").toAbsolutePath()); traverser.traverse( new ClasspathTraversal(paths, filesystem) { @Override public void visit(FileLike fileLike) { String contents; try { contents = new FileLikeCharSource(fileLike).read(); } catch (IOException e) { throw Throwables.propagate(e); } completeList.put(fileLike, contents); } }); return completeList.build(); }
// Not safe to execute multiple times. @Override public Collection<File> execute() throws IOException { ClasspathTraverser classpathTraverser = new DefaultClasspathTraverser(); // Compute the total size of the inputs so that we can figure out whether its safe // to begin putting non-essential entries into the primary zip. // TODO(devjasta): There's a more compact way of doing this by writing the primary zip during // this first-pass step then assigning it as the "currentSecondaryOut" to complete the second // pass. We're already tracking unique entries so we would not end up adding those primary // entries twice. classpathTraverser.traverse( new ClasspathTraversal(inFiles) { @Override public void visit(FileLike entry) { long entrySize = entry.getSize(); if (entrySize > 0) { remainingSize += entrySize; } } }); primaryOut = newZipOutput(outPrimary); secondaryDexWriter.reset(); try { for (File inFile : inFiles) { classpathTraverser.traverse( new ClasspathTraversal(ImmutableSet.of(inFile)) { @Override public void visit(FileLike entry) throws IOException { processEntry(entry); } }); // The soft limit was tripped (and not the hard limit). Flag that the next non-zero length // entry should create a new zip. DefaultZipOutputStreamHelper currentSecondaryOut = secondaryDexWriter.getCurrentOutput(); if (currentSecondaryOut != null && currentSecondaryOut.getCurrentSize() >= zipSizeSoftLimit) { secondaryDexWriter.finishCurrentZipFile(); } } } finally { primaryOut.close(); secondaryDexWriter.close(); } return secondaryDexWriter.getFiles(); }