launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/FXBrwsrLauncher.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 18 Apr 2016 05:15:11 +0200
changeset 1926 789849cabcc7
parent 1787 ea12a3bb4b33
permissions -rw-r--r--
Include the unit test initialization script in generated bck2brwsr.js rather than embedding it in the harness.html page
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012-2015 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 org.apidesign.bck2brwsr.launcher.fximpl.FXBrwsr;
    22 import java.io.IOException;
    23 import java.io.InputStream;
    24 import java.lang.reflect.Method;
    25 import java.net.JarURLConnection;
    26 import java.net.URI;
    27 import java.net.URISyntaxException;
    28 import java.net.URL;
    29 import java.net.URLClassLoader;
    30 import java.util.ArrayList;
    31 import java.util.Enumeration;
    32 import java.util.List;
    33 
    34 import java.util.concurrent.Executors;
    35 import java.util.jar.Manifest;
    36 import java.util.logging.Level;
    37 import java.util.logging.Logger;
    38 import javafx.application.Platform;
    39 import org.apidesign.bck2brwsr.launcher.fximpl.JVMBridge;
    40 
    41 /**
    42  *
    43  * @author Jaroslav Tulach <jtulach@netbeans.org>
    44  */
    45 final class FXBrwsrLauncher extends BaseHTTPLauncher {
    46     private static final Logger LOG = Logger.getLogger(FXBrwsrLauncher.class.getName());
    47     static {
    48         try {
    49             Method m = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
    50             m.setAccessible(true);
    51             URL l = new URL("file://" + System.getProperty("java.home") + "/lib/jfxrt.jar");
    52             LOG.log(Level.INFO, "url : {0}", l);
    53             m.invoke(ClassLoader.getSystemClassLoader(), l);
    54         } catch (Exception ex) {
    55             throw new LinkageError("Can't add jfxrt.jar on the classpath", ex);
    56         }
    57     }
    58 
    59     public FXBrwsrLauncher(String ignore) {
    60         super(null);
    61     }
    62 
    63     @Override
    64     protected Object[] showBrwsr(final URI url) throws IOException {
    65         try {
    66             LOG.log(Level.INFO, "showBrwsr for {0}", url);
    67             JVMBridge.registerClassLoaders(loaders());
    68             LOG.info("About to launch WebView");
    69             Executors.newSingleThreadExecutor().submit(new Runnable() {
    70                 @Override
    71                 public void run() {
    72                     LOG.log(Level.INFO, "In FX thread. Launching!");
    73                     try {
    74                         List<String> params = new ArrayList<String>();
    75                         params.add(url.toString());
    76                         if (isDebugged()) {
    77                             params.add("--toolbar=true");
    78                             params.add("--firebug=true");
    79                             String ud = System.getProperty("netbeans.user");
    80                             if (ud != null) {
    81                                 params.add("--userdir=" + ud);
    82                             }
    83                         }
    84                         FXBrwsr.launch(FXBrwsr.class, params.toArray(new String[params.size()]));
    85                         LOG.log(Level.INFO, "Launcher is back. Closing");
    86                         close();
    87                         System.exit(0);
    88                     } catch (Throwable ex) {
    89                         LOG.log(Level.WARNING, "Error launching Web View", ex);
    90                     }
    91                 }
    92             });
    93         } catch (Throwable ex) {
    94             LOG.log(Level.WARNING, "Can't open WebView", ex);
    95         }
    96         return null;
    97     }
    98     
    99     @Override
   100     void generateBck2BrwsrJS(StringBuilder sb, Res loader, String url, boolean unitTestMode) throws IOException {
   101         sb.append("(function() {\n"
   102             + "  var impl = this.bck2brwsr;\n"
   103             + "  this.bck2brwsr = function() { return impl; };\n");
   104         sb.append("})(window);\n");
   105         JVMBridge.onBck2BrwsrLoad();
   106         if (unitTestMode) {
   107             sb.append("var vm = bck2brwsr();\n");
   108             sb.append("try {\n");
   109             sb.append("    (function() {\n");
   110             sb.append("        var cls = vm.loadClass('org.apidesign.bck2brwsr.launcher.fximpl.Console');\n");
   111             sb.append("        // fxbrwsr mangling\n");
   112             sb.append("        var inst = cls.newInstance();\n");
   113             int last = url.lastIndexOf('/');
   114             url = url.substring(0, last + 1);
   115             sb.append("        inst.harness('").append(url).append("/data');\n");
   116             sb.append("    })();\n");
   117             sb.append("} catch (err) {\n");
   118             sb.append("    alert('Error executing harness: ' + err);\n");
   119             sb.append("}\n");
   120         }
   121     }
   122 
   123     @Override
   124     public void close() throws IOException {
   125         super.close();
   126         Platform.exit();
   127     }
   128 
   129     String harnessResource() {
   130         return "org/apidesign/bck2brwsr/launcher/fximpl/harness.html";
   131     }
   132 
   133     public static void main(String... args) throws IOException {
   134         String startPage = null;
   135 
   136         final ClassLoader cl = FXBrwsrLauncher.class.getClassLoader();
   137         URL[] manifestURL = { null };
   138         startPage = findStartPage(cl, startPage, manifestURL);
   139         if (startPage == null) {
   140             throw new NullPointerException("Can't find StartPage tag in manifests!");
   141         }
   142         
   143         File dir = new File(".");
   144         if (manifestURL[0].getProtocol().equals("jar")) {
   145             try {
   146                 dir = new File(
   147                     ((JarURLConnection)manifestURL[0].openConnection()).getJarFileURL().toURI()
   148                 ).getParentFile();
   149             } catch (URISyntaxException ex) {
   150                 LOG.log(Level.WARNING, "Can't find root directory", ex);
   151             }
   152         }
   153         
   154         Launcher.showDir("fxbrwsr", dir, cl, startPage);
   155     }
   156     
   157     private static String findStartPage(
   158         final ClassLoader cl, String startPage, URL[] startURL
   159     ) throws IOException {
   160         Enumeration<URL> en = cl.getResources("META-INF/MANIFEST.MF");
   161         while (en.hasMoreElements()) {
   162             URL url = en.nextElement();
   163             Manifest mf;
   164             InputStream is = null;
   165             try {
   166                 is = url.openStream();
   167                 mf = new Manifest(is);
   168             } finally {
   169                 if (is != null) is.close();
   170             }
   171             String sp = mf.getMainAttributes().getValue("StartPage");
   172             if (sp != null) {
   173                 startPage = sp;
   174                 if (startURL != null) {
   175                     startURL[0] = url;
   176                 }
   177                 break;
   178             }
   179         }
   180         return startPage;
   181     }
   182     
   183     private static boolean isDebugged() {
   184         try {
   185             return isDebuggedImpl();
   186         } catch (LinkageError e) {
   187             return false;
   188         }
   189     }
   190 
   191     private static boolean isDebuggedImpl() {
   192         java.lang.management.RuntimeMXBean runtime;
   193         runtime = java.lang.management.ManagementFactory.getRuntimeMXBean();
   194         List<String> args = runtime.getInputArguments();
   195         if (args.contains("-Xdebug")) { // NOI18N
   196             return true;
   197         }
   198         return false;
   199     }
   200 }