jaroslav@1489: /** jaroslav@1489: * Back 2 Browser Bytecode Translator jaroslav@1489: * Copyright (C) 2012 Jaroslav Tulach jaroslav@1489: * jaroslav@1489: * This program is free software: you can redistribute it and/or modify jaroslav@1489: * it under the terms of the GNU General Public License as published by jaroslav@1489: * the Free Software Foundation, version 2 of the License. jaroslav@1489: * jaroslav@1489: * This program is distributed in the hope that it will be useful, jaroslav@1489: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@1489: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@1489: * GNU General Public License for more details. jaroslav@1489: * jaroslav@1489: * You should have received a copy of the GNU General Public License jaroslav@1489: * along with this program. Look for COPYING file in the top folder. jaroslav@1489: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@1489: */ jaroslav@1489: package org.apidesign.bck2brwsr.launcher; jaroslav@1489: jaroslav@1489: import java.io.File; jaroslav@1489: import java.io.IOException; jaroslav@1489: import java.io.InputStream; jaroslav@1489: import java.io.StringWriter; jaroslav@1489: import java.net.URISyntaxException; jaroslav@1489: import java.net.URL; jaroslav@1489: import java.util.ArrayList; jaroslav@1489: import java.util.Enumeration; jaroslav@1489: import java.util.List; jaroslav@1489: import java.util.jar.JarEntry; jaroslav@1489: import java.util.jar.JarFile; jaroslav@1489: import java.util.zip.ZipEntry; jaroslav@1489: import org.apidesign.vm4brwsr.Bck2Brwsr; jaroslav@1489: jaroslav@1489: /** jaroslav@1489: * jaroslav@1489: * @author Jaroslav Tulach jaroslav@1489: */ jaroslav@1489: class CompileCP { jaroslav@1489: static String compileJAR(final JarFile jar) throws IOException { jaroslav@1489: List arr = new ArrayList<>(); jaroslav@1489: List classes = new ArrayList<>(); jaroslav@1489: listJAR(jar, classes, arr); jaroslav@1489: StringWriter w = new StringWriter(); jaroslav@1489: try { jaroslav@1489: class JarRes extends EmulationResources implements Bck2Brwsr.Resources { jaroslav@1489: @Override jaroslav@1489: public InputStream get(String resource) throws IOException { jaroslav@1489: InputStream is = jar.getInputStream(new ZipEntry(resource)); jaroslav@1489: return is == null ? super.get(resource) : is; jaroslav@1489: } jaroslav@1489: } jaroslav@1489: jaroslav@1489: Bck2Brwsr.newCompiler() jaroslav@1491: .addClasses(classes.toArray(new String[0])) jaroslav@1491: .library(true) jaroslav@1489: .resources(new JarRes()) jaroslav@1489: .generate(w); jaroslav@1489: w.flush(); jaroslav@1489: return w.toString(); jaroslav@1489: } catch (Throwable ex) { jaroslav@1489: throw new IOException("Cannot compile: ", ex); jaroslav@1489: } finally { jaroslav@1489: w.close(); jaroslav@1489: } jaroslav@1489: } jaroslav@1489: jaroslav@1489: static String compileFromClassPath(URL u) throws IOException, URISyntaxException { jaroslav@1489: File f = new File(u.toURI()); jaroslav@1489: for (String s : System.getProperty("java.class.path").split(File.pathSeparator)) { jaroslav@1489: if (!f.getPath().startsWith(s)) { jaroslav@1489: continue; jaroslav@1489: } jaroslav@1489: File root = new File(s); jaroslav@1489: List arr = new ArrayList<>(); jaroslav@1489: List classes = new ArrayList<>(); jaroslav@1489: listDir(root, null, classes, arr); jaroslav@1489: StringWriter w = new StringWriter(); jaroslav@1489: try { jaroslav@1489: Bck2Brwsr.newCompiler() jaroslav@1489: .addRootClasses(classes.toArray(new String[0])) jaroslav@1491: .library(true) jaroslav@1489: .resources(new EmulationResources()) jaroslav@1489: .generate(w); jaroslav@1489: w.flush(); jaroslav@1489: return w.toString(); jaroslav@1489: } catch (ClassFormatError ex) { jaroslav@1489: throw new IOException(ex); jaroslav@1489: } finally { jaroslav@1489: w.close(); jaroslav@1489: } jaroslav@1489: } jaroslav@1489: return null; jaroslav@1489: } jaroslav@1489: jaroslav@1489: private static void listJAR(JarFile j, List classes, List resources) throws IOException { jaroslav@1489: Enumeration en = j.entries(); jaroslav@1489: while (en.hasMoreElements()) { jaroslav@1489: JarEntry e = en.nextElement(); jaroslav@1489: final String n = e.getName(); jaroslav@1489: if (n.endsWith("/")) { jaroslav@1489: continue; jaroslav@1489: } jaroslav@1489: int last = n.lastIndexOf('/'); jaroslav@1489: String pkg = n.substring(0, last + 1); jaroslav@1489: if (skipPkg(pkg)) { jaroslav@1489: continue; jaroslav@1489: } jaroslav@1489: if (n.endsWith(".class")) { jaroslav@1489: classes.add(n.substring(0, n.length() - 6)); jaroslav@1489: } else { jaroslav@1489: resources.add(n); jaroslav@1489: } jaroslav@1489: } jaroslav@1489: } jaroslav@1489: jaroslav@1489: private static boolean skipPkg(String pkg) { jaroslav@1489: return pkg.equals("org/apidesign/bck2brwsr/launcher/"); jaroslav@1489: } jaroslav@1489: jaroslav@1489: private static void listDir(File f, String pref, List classes, List resources) throws IOException { jaroslav@1489: File[] arr = f.listFiles(); jaroslav@1489: if (arr == null) { jaroslav@1489: if (f.getName().endsWith(".class")) { jaroslav@1489: classes.add(pref + f.getName().substring(0, f.getName().length() - 6)); jaroslav@1489: } else { jaroslav@1489: resources.add(pref + f.getName()); jaroslav@1489: } jaroslav@1489: } else { jaroslav@1489: for (File ch : arr) { jaroslav@1489: jaroslav@1489: listDir(ch, pref == null ? "" : pref + f.getName() + "/", classes, resources); jaroslav@1489: } jaroslav@1489: } jaroslav@1489: } jaroslav@1489: jaroslav@1489: static class EmulationResources implements Bck2Brwsr.Resources { jaroslav@1489: jaroslav@1489: @Override jaroslav@1489: public InputStream get(String name) throws IOException { jaroslav@1489: Enumeration en = CompileCP.class.getClassLoader().getResources(name); jaroslav@1489: URL u = null; jaroslav@1489: while (en.hasMoreElements()) { jaroslav@1489: u = en.nextElement(); jaroslav@1489: } jaroslav@1489: if (u == null) { jaroslav@1489: throw new IOException("Can't find " + name); jaroslav@1489: } jaroslav@1489: if (u.toExternalForm().contains("rt.jar!")) { jaroslav@1489: throw new IOException("No emulation for " + u); jaroslav@1489: } jaroslav@1489: return u.openStream(); jaroslav@1489: } jaroslav@1489: } jaroslav@1489: }