# HG changeset patch # User Jaroslav Tulach # Date 1417843697 -3600 # Node ID 82fd3830167d60f25af3998fcd33913ca49562b6 # Parent 2ca94af8496afdaccd7f7c427386da5100c5490c Ability to extract precompiled bck2brwsr JavaScript files from Maven artifacts named bck2brwsr diff -r 2ca94af8496a -r 82fd3830167d javaquery/demo-calculator/pom.xml --- a/javaquery/demo-calculator/pom.xml Thu Dec 04 19:07:00 2014 +0100 +++ b/javaquery/demo-calculator/pom.xml Sat Dec 06 06:28:17 2014 +0100 @@ -37,6 +37,7 @@ org/apidesign/bck2brwsr/demo/calc/staticcompilation/ + false diff -r 2ca94af8496a -r 82fd3830167d rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AOTLibrary.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AOTLibrary.java Sat Dec 06 06:28:17 2014 +0100 @@ -0,0 +1,155 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ + +package org.apidesign.bck2brwsr.mojo; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectHelper; +import org.apidesign.bck2brwsr.aot.Bck2BrwsrJars; +import org.apidesign.vm4brwsr.Bck2Brwsr; +import org.apidesign.vm4brwsr.ObfuscationLevel; + +/** + * + * @author Jaroslav Tulach + * @since 0.12 + */ +@Mojo(name = "library", + requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, + defaultPhase = LifecyclePhase.PACKAGE +) +public class AOTLibrary extends AbstractMojo { + @Parameter(defaultValue = "${project}") + private MavenProject prj; + + @Component + private MavenProjectHelper projectHelper; + @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.jar") + private File mainJar; + @Parameter(defaultValue = "${project.build.finalName}-min.js") + private String minified; + @Parameter(defaultValue = "${project.build.finalName}-debug.js") + private String debug; + + @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}-bck2brwsr.jar") + private File aotJar; + + @Parameter + private String[] exports; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + URLClassLoader loader; + try { + loader = buildClassLoader(mainJar, prj.getArtifacts()); + } catch (MalformedURLException ex) { + throw new MojoFailureException("Can't initialize classloader"); + } + + try { + Manifest m = new Manifest(); + { + Attributes attr = new Attributes(); + attr.putValue("Bck2BrwsrArtifactId", prj.getArtifactId()); + attr.putValue("Bck2BrwsrGroupId", prj.getGroupId()); + attr.putValue("Bck2BrwsrVersion", prj.getVersion()); + attr.putValue("Bck2BrwsrMinified", "true"); + m.getEntries().put(minified, attr); + } + { + Attributes attr = new Attributes(); + attr.putValue("Bck2BrwsrArtifactId", prj.getArtifactId()); + attr.putValue("Bck2BrwsrGroupId", prj.getGroupId()); + attr.putValue("Bck2BrwsrVersion", prj.getVersion()); + attr.putValue("Bck2BrwsrDebug", "true"); + m.getEntries().put(debug, attr); + } + + FileOutputStream fos = new FileOutputStream(this.aotJar); + JarOutputStream os = new JarOutputStream(fos, m); + + Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar, loader); + if (exports != null) { + for (String e : exports) { + c = c.addExported(e.replace('.', '/')); + } + } + { + os.putNextEntry(new JarEntry(debug)); + Writer w = new OutputStreamWriter(os); + c. + obfuscation(ObfuscationLevel.NONE). + generate(w); + w.flush(); + os.closeEntry(); + } + { + os.putNextEntry(new JarEntry(minified)); + + Writer w = new OutputStreamWriter(os); + c. + obfuscation(ObfuscationLevel.FULL). + generate(w); + w.flush(); + os.closeEntry(); + } + os.close(); + + projectHelper.attachArtifact(prj, "jar", "bck2brwsr", aotJar); + } catch (IOException ex) { + throw new MojoFailureException("Cannot generate script for " + mainJar, ex); + } + } + + private static URLClassLoader buildClassLoader(File root, Collection deps) throws MalformedURLException { + List arr = new ArrayList(); + if (root != null) { + arr.add(root.toURI().toURL()); + } + for (Artifact a : deps) { + if (a.getFile() != null) { + arr.add(a.getFile().toURI().toURL()); + } + } + return new URLClassLoader(arr.toArray(new URL[0]), Java2JavaScript.class.getClassLoader()); + } +} diff -r 2ca94af8496a -r 82fd3830167d rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java Thu Dec 04 19:07:00 2014 +0100 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java Sat Dec 06 06:28:17 2014 +0100 @@ -25,9 +25,15 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -74,6 +80,9 @@ @Parameter(defaultValue="${project.build.directory}/bck2brwsr.js") private File vm; + @Parameter(defaultValue = "true") + private boolean generateAotLibraries; + /** * The obfuscation level for the generated JavaScript file. * @@ -109,10 +118,9 @@ continue; } try { - getLog().info("Generating " + js); aotLibrary(a, js , loader); } catch (IOException ex) { - throw new MojoFailureException("Can't compile" + a.getFile(), ex); + throw new MojoFailureException("Can't compile " + a.getFile(), ex); } } @@ -157,7 +165,39 @@ } } - private void aotLibrary(Artifact a, File js, URLClassLoader loader) throws IOException { + private void aotLibrary(Artifact a, File js, URLClassLoader loader) throws IOException, MojoExecutionException { + for (Artifact b : prj.getArtifacts()) { + if ("bck2brwsr".equals(b.getClassifier())) { // NOI18N + getLog().debug("Inspecting " + b.getFile()); + JarFile jf = new JarFile(b.getFile()); + Manifest man = jf.getManifest(); + for (Map.Entry entrySet : man.getEntries().entrySet()) { + String entryName = entrySet.getKey(); + Attributes attr = entrySet.getValue(); + + if ( + a.getArtifactId().equals(attr.getValue("Bck2BrwsrArtifactId")) && + a.getGroupId().equals(attr.getValue("Bck2BrwsrGroupId")) && + a.getVersion().equals(attr.getValue("Bck2BrwsrVersion")) && + ( + obfuscation == ObfuscationLevel.FULL && "true".equals(attr.getValue("Bck2BrwsrMinified")) + || + obfuscation != ObfuscationLevel.FULL && "true".equals(attr.getValue("Bck2BrwsrDebug")) + ) + ) { + getLog().info("Extracting " + js + " from " + b.getFile()); + InputStream is = jf.getInputStream(new ZipEntry(entryName)); + Files.copy(is, js.toPath()); + is.close(); + return; + } + } + } + } + if (!generateAotLibraries) { + throw new MojoExecutionException("Not generating " + js + " and no precompiled version found!"); + } + getLog().info("Generating " + js); FileWriter w = new FileWriter(js); Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, a.getFile(), loader); c.