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