jaroslav@1584: /** jaroslav@1584: * Back 2 Browser Bytecode Translator jaroslav@1584: * Copyright (C) 2012 Jaroslav Tulach jaroslav@1584: * jaroslav@1584: * This program is free software: you can redistribute it and/or modify jaroslav@1584: * it under the terms of the GNU General Public License as published by jaroslav@1584: * the Free Software Foundation, version 2 of the License. jaroslav@1584: * jaroslav@1584: * This program is distributed in the hope that it will be useful, jaroslav@1584: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@1584: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@1584: * GNU General Public License for more details. jaroslav@1584: * jaroslav@1584: * You should have received a copy of the GNU General Public License jaroslav@1584: * along with this program. Look for COPYING file in the top folder. jaroslav@1584: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@1584: */ jaroslav@1584: jaroslav@1584: package org.apidesign.bck2brwsr.mojo; jaroslav@1584: jaroslav@1584: import java.io.File; jaroslav@1584: import java.io.FileWriter; jaroslav@1584: import java.io.IOException; jaroslav@1584: import java.io.InputStream; jaroslav@1584: import java.net.MalformedURLException; jaroslav@1584: import java.net.URL; jaroslav@1584: import java.net.URLClassLoader; jaroslav@1584: import java.util.ArrayList; jaroslav@1584: import java.util.Collection; jaroslav@1584: import java.util.List; jaroslav@1584: import org.apache.maven.artifact.Artifact; jaroslav@1584: import org.apache.maven.plugin.AbstractMojo; jaroslav@1584: import org.apache.maven.plugin.MojoExecutionException; jaroslav@1584: import org.apache.maven.plugin.MojoFailureException; jaroslav@1584: import org.apache.maven.plugins.annotations.LifecyclePhase; jaroslav@1584: import org.apache.maven.plugins.annotations.Mojo; jaroslav@1584: import org.apache.maven.plugins.annotations.Parameter; jaroslav@1584: import org.apache.maven.plugins.annotations.ResolutionScope; jaroslav@1584: import org.apache.maven.project.MavenProject; jaroslav@1599: import org.apidesign.bck2brwsr.aot.Bck2BrwsrJars; jaroslav@1584: import org.apidesign.vm4brwsr.Bck2Brwsr; jaroslav@1584: import org.apidesign.vm4brwsr.ObfuscationLevel; jaroslav@1584: jaroslav@1584: /** jaroslav@1584: * jaroslav@1584: * @author Jaroslav Tulach jaroslav@1584: * @since 0.9 jaroslav@1584: */ jaroslav@1584: @Mojo(name = "aot", jaroslav@1584: requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, jaroslav@1584: defaultPhase = LifecyclePhase.PACKAGE jaroslav@1584: ) jaroslav@1584: public class AheadOfTime extends AbstractMojo { jaroslav@1584: @Parameter(defaultValue = "${project}") jaroslav@1584: private MavenProject prj; jaroslav@1604: jaroslav@1604: @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.jar") jaroslav@1604: private File mainJar; jaroslav@1584: jaroslav@1604: @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.js") jaroslav@1604: private File mainJavaScript; jaroslav@1604: jaroslav@1604: @Parameter jaroslav@1604: private String[] exports; jaroslav@1604: jaroslav@1584: /** jaroslav@1584: * Directory where to generate ahead-of-time JavaScript files for jaroslav@1584: * required libraries. jaroslav@1584: */ jaroslav@1604: @Parameter(defaultValue = "lib") jaroslav@1604: private String classPathPrefix; jaroslav@1584: jaroslav@1584: /** Root JavaScript file to generate */ jaroslav@1584: @Parameter(defaultValue="${project.build.directory}/bck2brwsr.js") jaroslav@1584: private File vm; jaroslav@1584: jaroslav@1584: /** jaroslav@1584: * The obfuscation level for the generated JavaScript file. jaroslav@1584: * jaroslav@1584: * @since 0.5 jaroslav@1584: */ jaroslav@1584: @Parameter(defaultValue = "NONE") jaroslav@1584: private ObfuscationLevel obfuscation; jaroslav@1584: jaroslav@1584: @Override jaroslav@1584: public void execute() throws MojoExecutionException, MojoFailureException { jaroslav@1594: URLClassLoader loader; jaroslav@1584: try { jaroslav@1604: loader = buildClassLoader(mainJar, prj.getArtifacts()); jaroslav@1594: } catch (MalformedURLException ex) { jaroslav@1594: throw new MojoFailureException("Can't initialize classloader"); jaroslav@1594: } jaroslav@1594: for (Artifact a : prj.getArtifacts()) { jaroslav@1594: if (a.getFile() == null) { jaroslav@1594: continue; jaroslav@1594: } jaroslav@1594: String n = a.getFile().getName(); jaroslav@1594: if (!n.endsWith(".jar")) { jaroslav@1594: continue; jaroslav@1594: } jaroslav@1594: if ("provided".equals(a.getScope())) { jaroslav@1594: continue; jaroslav@1594: } jaroslav@1636: if ("system".equals(a.getScope())) { jaroslav@1636: continue; jaroslav@1636: } jaroslav@1604: File aot = new File(prj.getBuild().getDirectory(), classPathPrefix); jaroslav@1594: aot.mkdirs(); jaroslav@1594: File js = new File(aot, n.substring(0, n.length() - 4) + ".js"); jaroslav@1618: if (js.exists()) { jaroslav@1618: getLog().info("Skipping " + js + " as it already exists."); jaroslav@1618: continue; jaroslav@1618: } jaroslav@1594: try { jaroslav@1618: getLog().info("Generating " + js); jaroslav@1584: aotLibrary(a, js , loader); jaroslav@1594: } catch (IOException ex) { jaroslav@1594: throw new MojoFailureException("Can't compile" + a.getFile(), ex); jaroslav@1584: } jaroslav@1594: } jaroslav@1604: jaroslav@1604: try { jaroslav@1618: if (mainJavaScript.exists()) { jaroslav@1618: getLog().info("Skipping " + mainJavaScript + " as it already exists."); jaroslav@1618: } else { jaroslav@1618: getLog().info("Generating " + mainJavaScript); jaroslav@1618: Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar); jaroslav@1618: if (exports != null) { jaroslav@1618: for (String e : exports) { jaroslav@1618: c = c.addExported(e.replace('.', '/')); jaroslav@1618: } jaroslav@1604: } jaroslav@1618: FileWriter w = new FileWriter(mainJavaScript); jaroslav@1618: c. jaroslav@1618: obfuscation(obfuscation). jaroslav@1618: resources(loader). jaroslav@1618: generate(w); jaroslav@1618: w.close(); jaroslav@1604: } jaroslav@1604: } catch (IOException ex) { jaroslav@1604: throw new MojoFailureException("Cannot generate script for " + mainJar, ex); jaroslav@1604: } jaroslav@1584: jaroslav@1594: try { jaroslav@1584: FileWriter w = new FileWriter(vm); jaroslav@1584: Bck2Brwsr.newCompiler(). jaroslav@1584: obfuscation(obfuscation). jaroslav@1584: standalone(false). jaroslav@1584: resources(new Bck2Brwsr.Resources() { jaroslav@1584: jaroslav@1584: @Override jaroslav@1584: public InputStream get(String resource) throws IOException { jaroslav@1584: return null; jaroslav@1584: } jaroslav@1584: }). jaroslav@1584: generate(w); jaroslav@1584: w.close(); jaroslav@1584: jaroslav@1584: } catch (IOException ex) { jaroslav@1584: throw new MojoExecutionException("Can't compile", ex); jaroslav@1584: } jaroslav@1584: } jaroslav@1584: jaroslav@1584: private void aotLibrary(Artifact a, File js, URLClassLoader loader) throws IOException { jaroslav@1584: FileWriter w = new FileWriter(js); jaroslav@1599: Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, a.getFile()); jaroslav@1599: c. jaroslav@1599: obfuscation(obfuscation). jaroslav@1599: resources(loader). jaroslav@1599: generate(w); jaroslav@1584: w.close(); jaroslav@1584: } jaroslav@1584: private static URLClassLoader buildClassLoader(File root, Collection deps) throws MalformedURLException { jaroslav@1584: List arr = new ArrayList(); jaroslav@1584: if (root != null) { jaroslav@1584: arr.add(root.toURI().toURL()); jaroslav@1584: } jaroslav@1584: for (Artifact a : deps) { jaroslav@1584: if (a.getFile() != null) { jaroslav@1584: arr.add(a.getFile().toURI().toURL()); jaroslav@1584: } jaroslav@1584: } jaroslav@1584: return new URLClassLoader(arr.toArray(new URL[0]), Java2JavaScript.class.getClassLoader()); jaroslav@1584: } jaroslav@1584: }