1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java Mon Mar 25 13:28:33 2013 +0100
1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java Thu Apr 25 16:17:48 2013 +0200
1.3 @@ -18,9 +18,16 @@
1.4 package org.apidesign.vm4brwsr;
1.5
1.6 import java.io.BufferedWriter;
1.7 +import java.io.File;
1.8 import java.io.FileWriter;
1.9 import java.io.IOException;
1.10 import java.io.Writer;
1.11 +import java.net.URI;
1.12 +import java.net.URISyntaxException;
1.13 +import java.net.URL;
1.14 +import java.util.Enumeration;
1.15 +import java.util.jar.JarEntry;
1.16 +import java.util.jar.JarFile;
1.17
1.18 /** Generator of JavaScript from bytecode of classes on classpath of the VM
1.19 * with a Main method.
1.20 @@ -30,7 +37,7 @@
1.21 final class Main {
1.22 private Main() {}
1.23
1.24 - public static void main(String... args) throws IOException {
1.25 + public static void main(String... args) throws IOException, URISyntaxException {
1.26 final String obfuscate = "--obfuscatelevel";
1.27
1.28 if (args.length < 2) {
1.29 @@ -50,7 +57,9 @@
1.30 System.err.println("] <file_to_generate_js_code_to> java/lang/Class org/your/App ...");
1.31 System.exit(9);
1.32 }
1.33 -
1.34 +
1.35 + final ClassLoader mainClassLoader = Main.class.getClassLoader();
1.36 +
1.37 ObfuscationLevel obfLevel = ObfuscationLevel.NONE;
1.38 StringArray classes = new StringArray();
1.39 String generateTo = null;
1.40 @@ -78,15 +87,114 @@
1.41 if (generateTo == null) {
1.42 generateTo = args[i];
1.43 } else {
1.44 - classes = classes.addAndNew(args[i]);
1.45 + collectClasses(classes, mainClassLoader, args[i]);
1.46 }
1.47 }
1.48 try (Writer w = new BufferedWriter(new FileWriter(generateTo))) {
1.49 Bck2Brwsr.newCompiler().
1.50 obfuscation(obfLevel).
1.51 addRootClasses(classes.toArray()).
1.52 - resources(Main.class.getClassLoader()).
1.53 + resources(mainClassLoader).
1.54 generate(w);
1.55 }
1.56 }
1.57 +
1.58 + private static void collectClasses(
1.59 + final StringArray dest,
1.60 + final ClassLoader cl, final String relativePath)
1.61 + throws IOException, URISyntaxException {
1.62 + final Enumeration<URL> urls = cl.getResources(relativePath);
1.63 + if (!urls.hasMoreElements()) {
1.64 + dest.add(relativePath);
1.65 + return;
1.66 + }
1.67 + do {
1.68 + final URL url = urls.nextElement();
1.69 + switch (url.getProtocol()) {
1.70 + case "file":
1.71 + collectClasses(dest, relativePath,
1.72 + new File(new URI(url.toString())));
1.73 + continue;
1.74 + case "jar":
1.75 + final String fullPath = url.getPath();
1.76 + final int sepIndex = fullPath.indexOf('!');
1.77 + final String jarFilePath =
1.78 + (sepIndex != -1) ? fullPath.substring(0, sepIndex)
1.79 + : fullPath;
1.80 +
1.81 + final URI jarUri = new URI(jarFilePath);
1.82 + if (jarUri.getScheme().equals("file")) {
1.83 + try (JarFile jarFile = new JarFile(new File(jarUri))) {
1.84 + collectClasses(dest, relativePath, jarFile);
1.85 + continue;
1.86 + }
1.87 + }
1.88 + break;
1.89 + }
1.90 +
1.91 + dest.add(relativePath);
1.92 + } while (urls.hasMoreElements());
1.93 + }
1.94 +
1.95 + private static void collectClasses(final StringArray dest,
1.96 + final String relativePath,
1.97 + final File file) {
1.98 + if (file.isDirectory()) {
1.99 + final File[] subFiles = file.listFiles();
1.100 + for (final File subFile: subFiles) {
1.101 + collectClasses(dest,
1.102 + extendPath(relativePath, subFile.getName()),
1.103 + subFile);
1.104 + }
1.105 +
1.106 + return;
1.107 + }
1.108 +
1.109 + final String filePath = file.getPath();
1.110 + if (filePath.endsWith(".class")) {
1.111 + validateAndAddClass(dest, relativePath);
1.112 + }
1.113 + }
1.114 +
1.115 + private static void collectClasses(final StringArray dest,
1.116 + final String relativePath,
1.117 + final JarFile jarFile) {
1.118 + if (relativePath.endsWith(".class")) {
1.119 + if (jarFile.getJarEntry(relativePath) != null) {
1.120 + validateAndAddClass(dest, relativePath);
1.121 + }
1.122 +
1.123 + return;
1.124 + }
1.125 +
1.126 + final String expectedPrefix =
1.127 + relativePath.endsWith("/") ? relativePath
1.128 + : relativePath + '/';
1.129 + final Enumeration<JarEntry> entries = jarFile.entries();
1.130 + while (entries.hasMoreElements()) {
1.131 + final JarEntry entry = entries.nextElement();
1.132 + if (!entry.isDirectory()) {
1.133 + final String entryName = entry.getName();
1.134 + if (entryName.startsWith(expectedPrefix)
1.135 + && entryName.endsWith(".class")) {
1.136 + validateAndAddClass(dest, entryName);
1.137 + }
1.138 + }
1.139 + }
1.140 + }
1.141 +
1.142 + private static String extendPath(final String relativePath,
1.143 + final String fileName) {
1.144 + return relativePath.endsWith("/") ? relativePath + fileName
1.145 + : relativePath + '/' + fileName;
1.146 + }
1.147 +
1.148 + private static void validateAndAddClass(final StringArray dest,
1.149 + final String relativePath) {
1.150 + final String className =
1.151 + relativePath.substring(0, relativePath.length() - 6);
1.152 + if (!className.endsWith("package-info")) {
1.153 + dest.add(className);
1.154 + }
1.155 + }
1.156 }