launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 30 Apr 2014 15:04:10 +0200
branchclosure
changeset 1513 ba912ef24b27
parent 1505 706b66d8c481
parent 1390 fe8f6b27c702
child 1525 777bd3ed81ba
permissions -rw-r--r--
Merging from default branch and resolving conflicts. mvn install -DskipTests passes OK.
     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 package org.apidesign.bck2brwsr.launcher;
    19 
    20 import java.io.File;
    21 import java.io.FileReader;
    22 import java.io.IOException;
    23 import java.io.InputStream;
    24 import java.io.InputStreamReader;
    25 import java.io.Reader;
    26 import java.net.MalformedURLException;
    27 import java.net.URL;
    28 import java.util.jar.JarFile;
    29 import java.util.logging.Level;
    30 import org.apidesign.vm4brwsr.Bck2Brwsr;
    31 
    32 /**
    33  * Lightweight server to launch Bck2Brwsr applications and tests.
    34  * Supports execution in native browser as well as Java's internal 
    35  * execution engine.
    36  */
    37 final class Bck2BrwsrLauncher extends BaseHTTPLauncher {
    38     
    39     public Bck2BrwsrLauncher(String cmd) {
    40         super(cmd);
    41     }
    42     
    43     @Override
    44     String harnessResource() {
    45         return "org/apidesign/bck2brwsr/launcher/harness.xhtml";
    46     }
    47 
    48     @Override
    49     String compileJar(JarFile jar) throws IOException {
    50         return CompileCP.compileJAR(jar);
    51     }
    52 
    53     @Override String compileFromClassPath(URL f, Res loader) throws IOException {
    54         return CompileCP.compileFromClassPath(f, loader);
    55     }
    56     
    57     @Override
    58     void generateBck2BrwsrJS(StringBuilder sb, final Res loader) throws IOException {
    59         String b2b = System.getProperty("bck2brwsr.js");
    60         if (b2b != null) {
    61             LOG.log(Level.INFO, "Serving bck2brwsr.js from {0}", b2b);
    62             URL bu;
    63             try {
    64                 bu = new URL(b2b);
    65             } catch (MalformedURLException ex) {
    66                 File f = new File(b2b);
    67                 if (f.exists()) {
    68                     bu = f.toURI().toURL();
    69                 } else {
    70                     throw ex;
    71                 }
    72             }
    73             try (Reader r = new InputStreamReader(bu.openStream())) {
    74                 char[] arr = new char[4096];
    75                 for (;;) {
    76                    int len = r.read(arr);
    77                    if (len == -1) {
    78                        break;
    79                    }
    80                    sb.append(arr, 0, len);
    81                 }
    82             }
    83         } else {
    84             LOG.log(Level.INFO, "Generating bck2brwsr.js from scratch", b2b);
    85             CompileCP.compileVM(sb, loader);
    86         }
    87         sb.append(
    88               "(function WrapperVM(global) {\n"
    89             + "  var cache = {};\n"
    90             + "  function ldCls(res, skip) {\n"
    91             + "    var c = cache[res];\n"
    92             + "    if (c) {\n"
    93             + "      if (c[skip]) return c[skip];\n"
    94             + "      if (c[skip] === null) return null;\n"
    95             + "    } else {\n"
    96             + "      cache[res] = c = new Array();\n"
    97             + "    }\n"
    98             + "    var request = new XMLHttpRequest();\n"
    99             + "    request.open('GET', '/classes/' + res + '?skip=' + skip, false);\n"
   100             + "    request.send();\n"
   101             + "    if (request.status !== 200) {\n"
   102             + "      c[skip] = null;\n"
   103             + "      return null;\n"
   104             + "    }\n"
   105             + "    var arr = eval(request.responseText);\n"
   106             + "    c[skip] = arr;\n"
   107             + "    return arr;\n"
   108             + "  }\n"
   109             + "  var prevvm = global.bck2brwsr;\n"
   110             + "  global.bck2brwsr = function() {\n"
   111             + "    var args = Array.prototype.slice.apply(arguments);\n"
   112             + "    args.unshift(ldCls);\n"
   113             + "    return prevvm.apply(null, args);\n"
   114             + "  };\n"
   115             + "  global.bck2brwsr.registerExtension = prevvm.registerExtension;\n"
   116             + "})(this);\n"
   117         );
   118         LOG.log(Level.INFO, "Serving bck2brwsr.js", b2b);
   119     }
   120 
   121 }