Ability to extract precompiled bck2brwsr JavaScript files from Maven artifacts named bck2brwsr
1.1 --- a/javaquery/demo-calculator/pom.xml Thu Dec 04 19:07:00 2014 +0100
1.2 +++ b/javaquery/demo-calculator/pom.xml Sat Dec 06 06:28:17 2014 +0100
1.3 @@ -37,6 +37,7 @@
1.4 <exports>
1.5 <param>org/apidesign/bck2brwsr/demo/calc/staticcompilation/</param>
1.6 </exports>
1.7 + <generateAotLibraries>false</generateAotLibraries>
1.8 </configuration>
1.9 </plugin>
1.10 <plugin>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AOTLibrary.java Sat Dec 06 06:28:17 2014 +0100
2.3 @@ -0,0 +1,155 @@
2.4 +/**
2.5 + * Back 2 Browser Bytecode Translator
2.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.7 + *
2.8 + * This program is free software: you can redistribute it and/or modify
2.9 + * it under the terms of the GNU General Public License as published by
2.10 + * the Free Software Foundation, version 2 of the License.
2.11 + *
2.12 + * This program is distributed in the hope that it will be useful,
2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.15 + * GNU General Public License for more details.
2.16 + *
2.17 + * You should have received a copy of the GNU General Public License
2.18 + * along with this program. Look for COPYING file in the top folder.
2.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
2.20 + */
2.21 +
2.22 +package org.apidesign.bck2brwsr.mojo;
2.23 +
2.24 +import java.io.File;
2.25 +import java.io.FileOutputStream;
2.26 +import java.io.IOException;
2.27 +import java.io.OutputStreamWriter;
2.28 +import java.io.Writer;
2.29 +import java.net.MalformedURLException;
2.30 +import java.net.URL;
2.31 +import java.net.URLClassLoader;
2.32 +import java.util.ArrayList;
2.33 +import java.util.Collection;
2.34 +import java.util.List;
2.35 +import java.util.jar.Attributes;
2.36 +import java.util.jar.JarEntry;
2.37 +import java.util.jar.JarOutputStream;
2.38 +import java.util.jar.Manifest;
2.39 +import org.apache.maven.artifact.Artifact;
2.40 +import org.apache.maven.plugin.AbstractMojo;
2.41 +import org.apache.maven.plugin.MojoExecutionException;
2.42 +import org.apache.maven.plugin.MojoFailureException;
2.43 +import org.apache.maven.plugins.annotations.Component;
2.44 +import org.apache.maven.plugins.annotations.LifecyclePhase;
2.45 +import org.apache.maven.plugins.annotations.Mojo;
2.46 +import org.apache.maven.plugins.annotations.Parameter;
2.47 +import org.apache.maven.plugins.annotations.ResolutionScope;
2.48 +import org.apache.maven.project.MavenProject;
2.49 +import org.apache.maven.project.MavenProjectHelper;
2.50 +import org.apidesign.bck2brwsr.aot.Bck2BrwsrJars;
2.51 +import org.apidesign.vm4brwsr.Bck2Brwsr;
2.52 +import org.apidesign.vm4brwsr.ObfuscationLevel;
2.53 +
2.54 +/**
2.55 + *
2.56 + * @author Jaroslav Tulach
2.57 + * @since 0.12
2.58 + */
2.59 +@Mojo(name = "library",
2.60 + requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
2.61 + defaultPhase = LifecyclePhase.PACKAGE
2.62 +)
2.63 +public class AOTLibrary extends AbstractMojo {
2.64 + @Parameter(defaultValue = "${project}")
2.65 + private MavenProject prj;
2.66 +
2.67 + @Component
2.68 + private MavenProjectHelper projectHelper;
2.69 + @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.jar")
2.70 + private File mainJar;
2.71 + @Parameter(defaultValue = "${project.build.finalName}-min.js")
2.72 + private String minified;
2.73 + @Parameter(defaultValue = "${project.build.finalName}-debug.js")
2.74 + private String debug;
2.75 +
2.76 + @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}-bck2brwsr.jar")
2.77 + private File aotJar;
2.78 +
2.79 + @Parameter
2.80 + private String[] exports;
2.81 +
2.82 + @Override
2.83 + public void execute() throws MojoExecutionException, MojoFailureException {
2.84 + URLClassLoader loader;
2.85 + try {
2.86 + loader = buildClassLoader(mainJar, prj.getArtifacts());
2.87 + } catch (MalformedURLException ex) {
2.88 + throw new MojoFailureException("Can't initialize classloader");
2.89 + }
2.90 +
2.91 + try {
2.92 + Manifest m = new Manifest();
2.93 + {
2.94 + Attributes attr = new Attributes();
2.95 + attr.putValue("Bck2BrwsrArtifactId", prj.getArtifactId());
2.96 + attr.putValue("Bck2BrwsrGroupId", prj.getGroupId());
2.97 + attr.putValue("Bck2BrwsrVersion", prj.getVersion());
2.98 + attr.putValue("Bck2BrwsrMinified", "true");
2.99 + m.getEntries().put(minified, attr);
2.100 + }
2.101 + {
2.102 + Attributes attr = new Attributes();
2.103 + attr.putValue("Bck2BrwsrArtifactId", prj.getArtifactId());
2.104 + attr.putValue("Bck2BrwsrGroupId", prj.getGroupId());
2.105 + attr.putValue("Bck2BrwsrVersion", prj.getVersion());
2.106 + attr.putValue("Bck2BrwsrDebug", "true");
2.107 + m.getEntries().put(debug, attr);
2.108 + }
2.109 +
2.110 + FileOutputStream fos = new FileOutputStream(this.aotJar);
2.111 + JarOutputStream os = new JarOutputStream(fos, m);
2.112 +
2.113 + Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar, loader);
2.114 + if (exports != null) {
2.115 + for (String e : exports) {
2.116 + c = c.addExported(e.replace('.', '/'));
2.117 + }
2.118 + }
2.119 + {
2.120 + os.putNextEntry(new JarEntry(debug));
2.121 + Writer w = new OutputStreamWriter(os);
2.122 + c.
2.123 + obfuscation(ObfuscationLevel.NONE).
2.124 + generate(w);
2.125 + w.flush();
2.126 + os.closeEntry();
2.127 + }
2.128 + {
2.129 + os.putNextEntry(new JarEntry(minified));
2.130 +
2.131 + Writer w = new OutputStreamWriter(os);
2.132 + c.
2.133 + obfuscation(ObfuscationLevel.FULL).
2.134 + generate(w);
2.135 + w.flush();
2.136 + os.closeEntry();
2.137 + }
2.138 + os.close();
2.139 +
2.140 + projectHelper.attachArtifact(prj, "jar", "bck2brwsr", aotJar);
2.141 + } catch (IOException ex) {
2.142 + throw new MojoFailureException("Cannot generate script for " + mainJar, ex);
2.143 + }
2.144 + }
2.145 +
2.146 + private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
2.147 + List<URL> arr = new ArrayList<URL>();
2.148 + if (root != null) {
2.149 + arr.add(root.toURI().toURL());
2.150 + }
2.151 + for (Artifact a : deps) {
2.152 + if (a.getFile() != null) {
2.153 + arr.add(a.getFile().toURI().toURL());
2.154 + }
2.155 + }
2.156 + return new URLClassLoader(arr.toArray(new URL[0]), Java2JavaScript.class.getClassLoader());
2.157 + }
2.158 +}
3.1 --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java Thu Dec 04 19:07:00 2014 +0100
3.2 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java Sat Dec 06 06:28:17 2014 +0100
3.3 @@ -25,9 +25,15 @@
3.4 import java.net.MalformedURLException;
3.5 import java.net.URL;
3.6 import java.net.URLClassLoader;
3.7 +import java.nio.file.Files;
3.8 import java.util.ArrayList;
3.9 import java.util.Collection;
3.10 import java.util.List;
3.11 +import java.util.Map;
3.12 +import java.util.jar.Attributes;
3.13 +import java.util.jar.JarFile;
3.14 +import java.util.jar.Manifest;
3.15 +import java.util.zip.ZipEntry;
3.16 import org.apache.maven.artifact.Artifact;
3.17 import org.apache.maven.plugin.AbstractMojo;
3.18 import org.apache.maven.plugin.MojoExecutionException;
3.19 @@ -74,6 +80,9 @@
3.20 @Parameter(defaultValue="${project.build.directory}/bck2brwsr.js")
3.21 private File vm;
3.22
3.23 + @Parameter(defaultValue = "true")
3.24 + private boolean generateAotLibraries;
3.25 +
3.26 /**
3.27 * The obfuscation level for the generated JavaScript file.
3.28 *
3.29 @@ -109,10 +118,9 @@
3.30 continue;
3.31 }
3.32 try {
3.33 - getLog().info("Generating " + js);
3.34 aotLibrary(a, js , loader);
3.35 } catch (IOException ex) {
3.36 - throw new MojoFailureException("Can't compile" + a.getFile(), ex);
3.37 + throw new MojoFailureException("Can't compile " + a.getFile(), ex);
3.38 }
3.39 }
3.40
3.41 @@ -157,7 +165,39 @@
3.42 }
3.43 }
3.44
3.45 - private void aotLibrary(Artifact a, File js, URLClassLoader loader) throws IOException {
3.46 + private void aotLibrary(Artifact a, File js, URLClassLoader loader) throws IOException, MojoExecutionException {
3.47 + for (Artifact b : prj.getArtifacts()) {
3.48 + if ("bck2brwsr".equals(b.getClassifier())) { // NOI18N
3.49 + getLog().debug("Inspecting " + b.getFile());
3.50 + JarFile jf = new JarFile(b.getFile());
3.51 + Manifest man = jf.getManifest();
3.52 + for (Map.Entry<String, Attributes> entrySet : man.getEntries().entrySet()) {
3.53 + String entryName = entrySet.getKey();
3.54 + Attributes attr = entrySet.getValue();
3.55 +
3.56 + if (
3.57 + a.getArtifactId().equals(attr.getValue("Bck2BrwsrArtifactId")) &&
3.58 + a.getGroupId().equals(attr.getValue("Bck2BrwsrGroupId")) &&
3.59 + a.getVersion().equals(attr.getValue("Bck2BrwsrVersion")) &&
3.60 + (
3.61 + obfuscation == ObfuscationLevel.FULL && "true".equals(attr.getValue("Bck2BrwsrMinified"))
3.62 + ||
3.63 + obfuscation != ObfuscationLevel.FULL && "true".equals(attr.getValue("Bck2BrwsrDebug"))
3.64 + )
3.65 + ) {
3.66 + getLog().info("Extracting " + js + " from " + b.getFile());
3.67 + InputStream is = jf.getInputStream(new ZipEntry(entryName));
3.68 + Files.copy(is, js.toPath());
3.69 + is.close();
3.70 + return;
3.71 + }
3.72 + }
3.73 + }
3.74 + }
3.75 + if (!generateAotLibraries) {
3.76 + throw new MojoExecutionException("Not generating " + js + " and no precompiled version found!");
3.77 + }
3.78 + getLog().info("Generating " + js);
3.79 FileWriter w = new FileWriter(js);
3.80 Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, a.getFile(), loader);
3.81 c.