mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Bck2BrswrMojo.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 07 Feb 2013 12:58:12 +0100
branchemul
changeset 694 0d277415ed02
parent 168 1d4bf362c3a4
permissions -rw-r--r--
Rebasing the Inflater support on jzlib which, unlike GNU ClassPath, has correct implementation of Huffman code. Making the implementation more easily testable by turning Inflater and ZipInputStream into pure delegates. Current implementation is going to need proper long support.
jaroslav@111
     1
/**
jaroslav@111
     2
 * Back 2 Browser Bytecode Translator
jaroslav@111
     3
 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@111
     4
 *
jaroslav@111
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@111
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@111
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@111
     8
 *
jaroslav@111
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@111
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@111
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@111
    12
 * GNU General Public License for more details.
jaroslav@111
    13
 *
jaroslav@111
    14
 * You should have received a copy of the GNU General Public License
jaroslav@111
    15
 * along with this program. Look for COPYING file in the top folder.
jaroslav@111
    16
 * If not, see http://opensource.org/licenses/GPL-2.0.
jaroslav@111
    17
 */
jaroslav@109
    18
package org.apidesign.bck2brwsr.mojo;
jaroslav@109
    19
jaroslav@109
    20
import org.apache.maven.plugin.AbstractMojo;
jaroslav@109
    21
jaroslav@109
    22
import java.io.File;
jaroslav@109
    23
import java.io.FileWriter;
jaroslav@305
    24
import java.io.IOException;
jaroslav@109
    25
import java.net.MalformedURLException;
jaroslav@109
    26
import java.net.URL;
jaroslav@109
    27
import java.net.URLClassLoader;
jaroslav@109
    28
import java.util.ArrayList;
jaroslav@109
    29
import java.util.Collection;
jaroslav@109
    30
import java.util.List;
jaroslav@109
    31
import org.apache.maven.artifact.Artifact;
jaroslav@109
    32
import org.apache.maven.plugin.MojoExecutionException;
jaroslav@109
    33
import org.apache.maven.plugins.annotations.LifecyclePhase;
jaroslav@109
    34
import org.apache.maven.plugins.annotations.Mojo;
jaroslav@109
    35
import org.apache.maven.plugins.annotations.Parameter;
jaroslav@109
    36
import org.apache.maven.project.MavenProject;
jaroslav@305
    37
import org.apidesign.vm4brwsr.Bck2Brwsr;
jaroslav@109
    38
jaroslav@109
    39
/** Compiles classes into JavaScript. */
jaroslav@109
    40
@Mojo(name="j2js", defaultPhase=LifecyclePhase.PROCESS_CLASSES)
jaroslav@109
    41
public class Bck2BrswrMojo extends AbstractMojo {
jaroslav@109
    42
    public Bck2BrswrMojo() {
jaroslav@109
    43
    }
jaroslav@109
    44
    /** Root of the class files */
jaroslav@109
    45
    @Parameter(defaultValue="${project.build.directory}/classes")
jaroslav@109
    46
    private File classes;
jaroslav@109
    47
    /** File to generate. Defaults bootjava.js in the first non-empty 
jaroslav@109
    48
     package under the classes directory */
jaroslav@109
    49
    @Parameter
jaroslav@109
    50
    private File javascript;
jaroslav@109
    51
    
jaroslav@109
    52
    @Parameter(defaultValue="${project}")
jaroslav@109
    53
    private MavenProject prj;
jaroslav@109
    54
    
jaroslav@109
    55
    
jaroslav@109
    56
jaroslav@109
    57
    @Override
jaroslav@109
    58
    public void execute() throws MojoExecutionException {
jaroslav@109
    59
        if (!classes.isDirectory()) {
jaroslav@109
    60
            throw new MojoExecutionException("Can't find " + classes);
jaroslav@109
    61
        }
jaroslav@109
    62
jaroslav@109
    63
        if (javascript == null) {
jaroslav@109
    64
            javascript = new File(findNonEmptyFolder(classes), "bootjava.js");
jaroslav@109
    65
        }
jaroslav@109
    66
jaroslav@109
    67
        List<String> arr = new ArrayList<String>();
jaroslav@134
    68
        long newest = collectAllClasses("", classes, arr);
jaroslav@109
    69
        
jaroslav@134
    70
        if (javascript.lastModified() > newest) {
jaroslav@134
    71
            return;
jaroslav@134
    72
        }
jaroslav@109
    73
jaroslav@109
    74
        try {
jaroslav@109
    75
            URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
jaroslav@109
    76
            FileWriter w = new FileWriter(javascript);
jaroslav@305
    77
            Bck2Brwsr.generate(w, url, arr.toArray(new String[0]));
jaroslav@109
    78
            w.close();
jaroslav@305
    79
        } catch (IOException ex) {
jaroslav@109
    80
            throw new MojoExecutionException("Can't compile", ex);
jaroslav@109
    81
        }
jaroslav@109
    82
    }
jaroslav@109
    83
jaroslav@109
    84
    private static File findNonEmptyFolder(File dir) throws MojoExecutionException {
jaroslav@109
    85
        if (!dir.isDirectory()) {
jaroslav@109
    86
            throw new MojoExecutionException("Not a directory " + dir);
jaroslav@109
    87
        }
jaroslav@109
    88
        File[] arr = dir.listFiles();
jaroslav@109
    89
        if (arr.length == 1 && arr[0].isDirectory()) {
jaroslav@109
    90
            return findNonEmptyFolder(arr[0]);
jaroslav@109
    91
        }
jaroslav@109
    92
        return dir;
jaroslav@109
    93
    }
jaroslav@109
    94
jaroslav@134
    95
    private static long collectAllClasses(String prefix, File toCheck, List<String> arr) {
jaroslav@109
    96
        File[] files = toCheck.listFiles();
jaroslav@109
    97
        if (files != null) {
jaroslav@134
    98
            long newest = 0L;
jaroslav@109
    99
            for (File f : files) {
jaroslav@134
   100
                long lastModified = collectAllClasses(prefix + f.getName() + "/", f, arr);
jaroslav@134
   101
                if (newest < lastModified) {
jaroslav@134
   102
                    newest = lastModified;
jaroslav@134
   103
                }
jaroslav@109
   104
            }
jaroslav@134
   105
            return newest;
jaroslav@109
   106
        } else if (toCheck.getName().endsWith(".class")) {
jaroslav@109
   107
            arr.add(prefix.substring(0, prefix.length() - 7));
jaroslav@134
   108
            return toCheck.lastModified();
jaroslav@134
   109
        } else {
jaroslav@134
   110
            return 0L;
jaroslav@109
   111
        }
jaroslav@109
   112
    }
jaroslav@109
   113
jaroslav@109
   114
    private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
jaroslav@109
   115
        List<URL> arr = new ArrayList<URL>();
jaroslav@109
   116
        arr.add(root.toURI().toURL());
jaroslav@109
   117
        for (Artifact a : deps) {
jaroslav@109
   118
            arr.add(a.getFile().toURI().toURL());
jaroslav@109
   119
        }
jaroslav@109
   120
        return new URLClassLoader(arr.toArray(new URL[0]), Bck2BrswrMojo.class.getClassLoader());
jaroslav@109
   121
    }
jaroslav@109
   122
}