diff -r c16121d8020b -r 35daab73e225 rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java --- a/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java Mon Jun 09 21:27:49 2014 +0200 +++ b/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java Sat Sep 13 13:44:01 2014 +0200 @@ -25,8 +25,10 @@ import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -65,23 +67,26 @@ */ public static Bck2Brwsr configureFrom(Bck2Brwsr c, File jar) throws IOException { final JarFile jf = new JarFile(jar); - List classes = new ArrayList<>(); + final List classes = new ArrayList<>(); List resources = new ArrayList<>(); Set exported = new HashSet<>(); - - listJAR(jf, classes, resources, exported); - - String cp = jf.getManifest().getMainAttributes().getValue("Class-Path"); // NOI18N - String[] classpath = cp == null ? new String[0] : cp.split(" "); - class JarRes extends EmulationResources implements Bck2Brwsr.Resources { - + JarRes() { + super(classes); + } @Override public InputStream get(String resource) throws IOException { InputStream is = jf.getInputStream(new ZipEntry(resource)); return is == null ? super.get(resource) : is; } } + JarRes jarRes = new JarRes(); + + listJAR(jf, jarRes, resources, exported); + + String cp = jf.getManifest().getMainAttributes().getValue("Class-Path"); // NOI18N + String[] classpath = cp == null ? new String[0] : cp.split(" "); + if (c == null) { c = Bck2Brwsr.newCompiler(); } @@ -91,11 +96,11 @@ .addClasses(classes.toArray(new String[classes.size()])) .addExported(exported.toArray(new String[exported.size()])) .addResources(resources.toArray(new String[resources.size()])) - .resources(new JarRes()); + .resources(jarRes); } private static void listJAR( - JarFile j, List classes, + JarFile j, EmulationResources classes, List resources, Set keep ) throws IOException { Enumeration en = j.entries(); @@ -114,7 +119,7 @@ keep.add(pkg); } if (n.endsWith(".class")) { - classes.add(n.substring(0, n.length() - 6)); + classes.addClassResource(n); } else { resources.add(n); if (n.startsWith("META-INF/services/") && keep != null) { @@ -142,8 +147,51 @@ } } } + + static byte[] readFrom(InputStream is) throws IOException { + int expLen = is.available(); + if (expLen < 1) { + expLen = 1; + } + byte[] arr = new byte[expLen]; + int pos = 0; + for (;;) { + int read = is.read(arr, pos, arr.length - pos); + if (read == -1) { + break; + } + pos += read; + if (pos == arr.length) { + byte[] tmp = new byte[arr.length * 2]; + System.arraycopy(arr, 0, tmp, 0, arr.length); + arr = tmp; + } + } + if (pos != arr.length) { + byte[] tmp = new byte[pos]; + System.arraycopy(arr, 0, tmp, 0, pos); + arr = tmp; + } + return arr; + } + static class EmulationResources implements Bck2Brwsr.Resources { + private final List classes; + private final Map converted = new HashMap<>(); + private final BytecodeProcessor proc; + + protected EmulationResources(List classes) { + this.classes = classes; + BytecodeProcessor p; + try { + Class bpClass = Class.forName("org.apidesign.bck2brwsr.aot.RetroLambda"); + p = (BytecodeProcessor) bpClass.newInstance(); + } catch (Throwable t) { + p = null; + } + this.proc = p; + } @Override public InputStream get(String name) throws IOException { @@ -162,6 +210,23 @@ } return u.openStream(); } + + private void addClassResource(String n) throws IOException { + if (proc != null) { + try (InputStream is = this.get(n)) { + Map conv = proc.process(n, readFrom(is), this); + if (conv != null) { + if (!conv.containsKey(n)) { + throw new IOException("Cannot find " + n + " among " + conv); + } + converted.putAll(conv); + return; + } + } + } + classes.add(n.substring(0, n.length() - 6)); + } } + }