rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 25 Jun 2014 22:50:33 +0200
branchdefprop
changeset 1636 eb97a082741b
parent 1618 f62b42f0b751
child 1638 a84f511654ae
permissions -rw-r--r--
Methods on object need to be manually enumerated
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 
    19 package org.apidesign.bck2brwsr.mojo;
    20 
    21 import java.io.File;
    22 import java.io.FileWriter;
    23 import java.io.IOException;
    24 import java.io.InputStream;
    25 import java.net.MalformedURLException;
    26 import java.net.URL;
    27 import java.net.URLClassLoader;
    28 import java.util.ArrayList;
    29 import java.util.Collection;
    30 import java.util.List;
    31 import org.apache.maven.artifact.Artifact;
    32 import org.apache.maven.plugin.AbstractMojo;
    33 import org.apache.maven.plugin.MojoExecutionException;
    34 import org.apache.maven.plugin.MojoFailureException;
    35 import org.apache.maven.plugins.annotations.LifecyclePhase;
    36 import org.apache.maven.plugins.annotations.Mojo;
    37 import org.apache.maven.plugins.annotations.Parameter;
    38 import org.apache.maven.plugins.annotations.ResolutionScope;
    39 import org.apache.maven.project.MavenProject;
    40 import org.apidesign.bck2brwsr.aot.Bck2BrwsrJars;
    41 import org.apidesign.vm4brwsr.Bck2Brwsr;
    42 import org.apidesign.vm4brwsr.ObfuscationLevel;
    43 
    44 /**
    45  *
    46  * @author Jaroslav Tulach
    47  * @since 0.9
    48  */
    49 @Mojo(name = "aot",
    50     requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
    51     defaultPhase = LifecyclePhase.PACKAGE
    52 )
    53 public class AheadOfTime extends AbstractMojo {
    54     @Parameter(defaultValue = "${project}")
    55     private MavenProject prj;
    56     
    57     @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.jar")
    58     private File mainJar;
    59 
    60     @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}.js")
    61     private File mainJavaScript;
    62     
    63     @Parameter
    64     private String[] exports;
    65     
    66     /**
    67      * Directory where to generate ahead-of-time JavaScript files for
    68      * required libraries.
    69      */
    70     @Parameter(defaultValue = "lib")
    71     private String classPathPrefix;
    72 
    73     /** Root JavaScript file to generate */
    74     @Parameter(defaultValue="${project.build.directory}/bck2brwsr.js")
    75     private File vm;
    76     
    77     /**
    78      * The obfuscation level for the generated JavaScript file.
    79      *
    80      * @since 0.5
    81      */
    82     @Parameter(defaultValue = "NONE")
    83     private ObfuscationLevel obfuscation;
    84     
    85     @Override
    86     public void execute() throws MojoExecutionException, MojoFailureException {
    87         URLClassLoader loader;
    88         try {
    89             loader = buildClassLoader(mainJar, prj.getArtifacts());
    90         } catch (MalformedURLException ex) {
    91             throw new MojoFailureException("Can't initialize classloader");
    92         }
    93         for (Artifact a : prj.getArtifacts()) {
    94             if (a.getFile() == null) {
    95                 continue;
    96             }
    97             String n = a.getFile().getName();
    98             if (!n.endsWith(".jar")) {
    99                 continue;
   100             }
   101             if ("provided".equals(a.getScope())) {
   102                 continue;
   103             }
   104             if ("system".equals(a.getScope())) {
   105                 continue;
   106             }
   107             File aot = new File(prj.getBuild().getDirectory(), classPathPrefix);
   108             aot.mkdirs();
   109             File js = new File(aot, n.substring(0, n.length() - 4) + ".js");
   110             if (js.exists()) {
   111                 getLog().info("Skipping " + js + " as it already exists.");
   112                 continue;
   113             }
   114             try {
   115                 getLog().info("Generating " + js);
   116                 aotLibrary(a, js , loader);
   117             } catch (IOException ex) {
   118                 throw new MojoFailureException("Can't compile" + a.getFile(), ex);
   119             }
   120         }
   121         
   122         try {
   123             if (mainJavaScript.exists()) {
   124                 getLog().info("Skipping " + mainJavaScript + " as it already exists.");
   125             } else {
   126                 getLog().info("Generating " + mainJavaScript);
   127                 Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar);
   128                 if (exports != null) {
   129                     for (String e : exports) {
   130                         c = c.addExported(e.replace('.', '/'));
   131                     }
   132                 }
   133                 FileWriter w = new FileWriter(mainJavaScript);
   134                 c.
   135                         obfuscation(obfuscation).
   136                         resources(loader).
   137                         generate(w);
   138                 w.close();
   139             }
   140         } catch (IOException ex) {
   141             throw new MojoFailureException("Cannot generate script for " + mainJar, ex);
   142         }
   143             
   144         try {
   145             FileWriter w = new FileWriter(vm);
   146             Bck2Brwsr.newCompiler().
   147                     obfuscation(obfuscation).
   148                     standalone(false).
   149                     resources(new Bck2Brwsr.Resources() {
   150 
   151                 @Override
   152                 public InputStream get(String resource) throws IOException {
   153                     return null;
   154                 }
   155             }).
   156                     generate(w);
   157             w.close();
   158             
   159         } catch (IOException ex) {
   160             throw new MojoExecutionException("Can't compile", ex);
   161         }
   162     }
   163 
   164     private void aotLibrary(Artifact a, File js, URLClassLoader loader) throws IOException {
   165         FileWriter w = new FileWriter(js);
   166         Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, a.getFile());
   167         c.
   168             obfuscation(obfuscation).
   169             resources(loader).
   170             generate(w);
   171         w.close();
   172     }
   173     private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
   174         List<URL> arr = new ArrayList<URL>();
   175         if (root != null) {
   176             arr.add(root.toURI().toURL());
   177         }
   178         for (Artifact a : deps) {
   179             if (a.getFile() != null) {
   180                 arr.add(a.getFile().toURI().toURL());
   181             }
   182         }
   183         return new URLClassLoader(arr.toArray(new URL[0]), Java2JavaScript.class.getClassLoader());
   184     }
   185 }