launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 28 Mar 2016 05:55:43 +0200
changeset 1914 88b00e03fc8f
parent 1787 ea12a3bb4b33
child 1920 6cfab6c60fba
permissions -rw-r--r--
Introducing vmtest.precompiled=<regexp> to verify that bck2brwsr generated resources are really used
jaroslav@1033
     1
/**
jaroslav@1033
     2
 * Back 2 Browser Bytecode Translator
jaroslav@1787
     3
 * Copyright (C) 2012-2015 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@1033
     4
 *
jaroslav@1033
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@1033
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@1033
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@1033
     8
 *
jaroslav@1033
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@1033
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@1033
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@1033
    12
 * GNU General Public License for more details.
jaroslav@1033
    13
 *
jaroslav@1033
    14
 * You should have received a copy of the GNU General Public License
jaroslav@1033
    15
 * along with this program. Look for COPYING file in the top folder.
jaroslav@1033
    16
 * If not, see http://opensource.org/licenses/GPL-2.0.
jaroslav@1033
    17
 */
jaroslav@1033
    18
package org.apidesign.bck2brwsr.launcher;
jaroslav@1033
    19
jaroslav@1371
    20
import java.io.File;
jaroslav@1033
    21
import java.io.IOException;
jaroslav@1371
    22
import java.io.InputStreamReader;
jaroslav@1371
    23
import java.io.Reader;
jaroslav@1389
    24
import java.net.MalformedURLException;
jaroslav@1599
    25
import java.net.URISyntaxException;
jaroslav@1371
    26
import java.net.URL;
jaroslav@1525
    27
import java.util.HashSet;
jaroslav@1525
    28
import java.util.Set;
jaroslav@1371
    29
import java.util.logging.Level;
jaroslav@1914
    30
import java.util.regex.Pattern;
jaroslav@1033
    31
jaroslav@1033
    32
/**
jaroslav@1033
    33
 * Lightweight server to launch Bck2Brwsr applications and tests.
jaroslav@1033
    34
 * Supports execution in native browser as well as Java's internal 
jaroslav@1033
    35
 * execution engine.
jaroslav@1033
    36
 */
jaroslav@1088
    37
final class Bck2BrwsrLauncher extends BaseHTTPLauncher {
jaroslav@1525
    38
    private Set<String> testClasses = new HashSet<String>();
jaroslav@1033
    39
    
jaroslav@1033
    40
    public Bck2BrwsrLauncher(String cmd) {
jaroslav@1088
    41
        super(cmd);
jaroslav@1033
    42
    }
jaroslav@1033
    43
    
jaroslav@1033
    44
    @Override
jaroslav@1088
    45
    String harnessResource() {
jaroslav@1088
    46
        return "org/apidesign/bck2brwsr/launcher/harness.xhtml";
jaroslav@1033
    47
    }
jaroslav@1489
    48
jaroslav@1489
    49
    @Override
jaroslav@1746
    50
    Object compileJar(URL jar, URL precompiled) throws IOException {
jaroslav@1746
    51
        if (precompiled != null) {
jaroslav@1746
    52
            LOG.log(Level.INFO, "Found precompiled JAR version of {0} at {1}. Using.", new Object[]{jar, precompiled});
jaroslav@1746
    53
            return precompiled.openStream();
jaroslav@1746
    54
        }
jaroslav@1599
    55
        File f;
jaroslav@1599
    56
        try {
jaroslav@1599
    57
            f = new File(jar.toURI());
jaroslav@1599
    58
        } catch (URISyntaxException ex) {
jaroslav@1599
    59
            throw new IOException(ex);
jaroslav@1599
    60
        }
jaroslav@1914
    61
        final String precompile = System.getProperty("vmtest.precompiled");
jaroslav@1914
    62
        if (precompile != null && Pattern.compile(precompile).matcher(jar.toString()).find()) {
jaroslav@1914
    63
            throw new IOException("Compilation of " + jar + " forbidden");
jaroslav@1914
    64
        }
jaroslav@1746
    65
        LOG.log(Level.INFO, "No precompiled version for {0} found. Compiling.", jar);
jaroslav@1599
    66
        return CompileCP.compileJAR(f, testClasses);
jaroslav@1525
    67
    }
jaroslav@1525
    68
jaroslav@1525
    69
    @Override
jaroslav@1525
    70
    public InvocationContext createInvocation(Class<?> clazz, String method) {
jaroslav@1525
    71
        testClasses.add(clazz.getName().replace('.', '/'));
jaroslav@1525
    72
        return super.createInvocation(clazz, method);
jaroslav@1489
    73
    }
jaroslav@1489
    74
jaroslav@1505
    75
    @Override String compileFromClassPath(URL f, Res loader) throws IOException {
jaroslav@1505
    76
        return CompileCP.compileFromClassPath(f, loader);
jaroslav@1489
    77
    }
jaroslav@1033
    78
    
jaroslav@1033
    79
    @Override
jaroslav@1088
    80
    void generateBck2BrwsrJS(StringBuilder sb, final Res loader) throws IOException {
jaroslav@1371
    81
        String b2b = System.getProperty("bck2brwsr.js");
jaroslav@1371
    82
        if (b2b != null) {
jaroslav@1371
    83
            LOG.log(Level.INFO, "Serving bck2brwsr.js from {0}", b2b);
jaroslav@1389
    84
            URL bu;
jaroslav@1389
    85
            try {
jaroslav@1389
    86
                bu = new URL(b2b);
jaroslav@1389
    87
            } catch (MalformedURLException ex) {
jaroslav@1389
    88
                File f = new File(b2b);
jaroslav@1389
    89
                if (f.exists()) {
jaroslav@1389
    90
                    bu = f.toURI().toURL();
jaroslav@1389
    91
                } else {
jaroslav@1389
    92
                    throw ex;
jaroslav@1389
    93
                }
jaroslav@1389
    94
            }
jaroslav@1389
    95
            try (Reader r = new InputStreamReader(bu.openStream())) {
jaroslav@1371
    96
                char[] arr = new char[4096];
jaroslav@1371
    97
                for (;;) {
jaroslav@1371
    98
                   int len = r.read(arr);
jaroslav@1371
    99
                   if (len == -1) {
jaroslav@1371
   100
                       break;
jaroslav@1371
   101
                   }
jaroslav@1371
   102
                   sb.append(arr, 0, len);
jaroslav@1371
   103
                }
jaroslav@1371
   104
            }
jaroslav@1371
   105
        } else {
jaroslav@1371
   106
            LOG.log(Level.INFO, "Generating bck2brwsr.js from scratch", b2b);
jaroslav@1513
   107
            CompileCP.compileVM(sb, loader);
jaroslav@1371
   108
        }
jaroslav@1088
   109
        sb.append(
jaroslav@1390
   110
              "(function WrapperVM(global) {\n"
jaroslav@1390
   111
            + "  var cache = {};\n"
jaroslav@1530
   112
            + "  var empty = {};\n"
jaroslav@1375
   113
            + "  function ldCls(res, skip) {\n"
jaroslav@1390
   114
            + "    var c = cache[res];\n"
jaroslav@1390
   115
            + "    if (c) {\n"
jaroslav@1530
   116
            + "      if (c[skip] === empty) return null;\n"
jaroslav@1390
   117
            + "      if (c[skip]) return c[skip];\n"
jaroslav@1390
   118
            + "    } else {\n"
jaroslav@1390
   119
            + "      cache[res] = c = new Array();\n"
jaroslav@1390
   120
            + "    }\n"
jaroslav@1088
   121
            + "    var request = new XMLHttpRequest();\n"
jaroslav@1375
   122
            + "    request.open('GET', '/classes/' + res + '?skip=' + skip, false);\n"
jaroslav@1088
   123
            + "    request.send();\n"
jaroslav@1390
   124
            + "    if (request.status !== 200) {\n"
jaroslav@1390
   125
            + "      c[skip] = null;\n"
jaroslav@1390
   126
            + "      return null;\n"
jaroslav@1390
   127
            + "    }\n"
jaroslav@1489
   128
            + "    var arr = eval(request.responseText);\n"
jaroslav@1531
   129
            + "    if (arr === null) c[skip] = empty;\n"
jaroslav@1531
   130
            + "    else c[skip] = arr;\n"
jaroslav@1088
   131
            + "    return arr;\n"
jaroslav@1088
   132
            + "  }\n"
jaroslav@1088
   133
            + "  var prevvm = global.bck2brwsr;\n"
jaroslav@1088
   134
            + "  global.bck2brwsr = function() {\n"
jaroslav@1088
   135
            + "    var args = Array.prototype.slice.apply(arguments);\n"
jaroslav@1088
   136
            + "    args.unshift(ldCls);\n"
jaroslav@1088
   137
            + "    return prevvm.apply(null, args);\n"
jaroslav@1088
   138
            + "  };\n"
jaroslav@1598
   139
            + "  global.bck2brwsr.register = prevvm.register;\n"
jaroslav@1088
   140
            + "})(this);\n"
jaroslav@1088
   141
        );
jaroslav@1371
   142
        LOG.log(Level.INFO, "Serving bck2brwsr.js", b2b);
jaroslav@1033
   143
    }
jaroslav@1033
   144
jaroslav@1033
   145
}