launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 12 Jun 2013 18:19:29 +0200
branchclassloader
changeset 1174 f78cdceed17b
parent 1041 f18b7262fe91
child 1175 15c6903c8612
permissions -rw-r--r--
Trying to use JsClassLoader in FX launcher
     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.fximpl;
    19 
    20 import java.net.URL;
    21 import java.util.TooManyListenersException;
    22 import javafx.beans.value.ChangeListener;
    23 import javafx.scene.web.WebEngine;
    24 import netscape.javascript.JSObject;
    25 
    26 /**
    27  *
    28  * @author Jaroslav Tulach <jtulach@netbeans.org>
    29  */
    30 public final class JVMBridge {
    31     private final WebEngine engine;
    32     private final WebClassLoader cl;
    33     
    34     private static ClassLoader[] ldrs;
    35     private static ChangeListener<Void> onBck2BrwsrLoad;
    36     
    37     JVMBridge(WebEngine eng) {
    38         this.engine = eng;
    39         this.cl = new WebClassLoader(JVMBridge.class.getClassLoader());
    40     }
    41         
    42     public static void registerClassLoaders(ClassLoader[] loaders) {
    43         ldrs = loaders.clone();
    44     }
    45     
    46     public static void addBck2BrwsrLoad(ChangeListener<Void> l) throws TooManyListenersException {
    47         if (onBck2BrwsrLoad != null) {
    48             throw new TooManyListenersException();
    49         }
    50         onBck2BrwsrLoad = l;
    51     }
    52 
    53     public static void onBck2BrwsrLoad() {
    54         ChangeListener<Void> l = onBck2BrwsrLoad;
    55         if (l != null) {
    56             l.changed(null, null, null);
    57         }
    58     }
    59     
    60     public Class<?> loadClass(String name) throws ClassNotFoundException {
    61         return Class.forName(name, true, cl);
    62     }
    63     
    64     private final class WebClassLoader extends JsClassLoader {
    65         public WebClassLoader(ClassLoader parent) {
    66             super(parent);
    67         }
    68 
    69         @Override
    70         protected URL findResource(String name) {
    71             if (ldrs != null) for (ClassLoader l : ldrs) {
    72                 URL u = l.getResource(name);
    73                 if (u != null) {
    74                     return u;
    75                 }
    76             }
    77             return null;
    78         }
    79 
    80         @Override
    81         protected Fn defineFn(String code, String... names) {
    82             StringBuilder sb = new StringBuilder();
    83             sb.append("(function() {");
    84             sb.append("  var x = {};");
    85             sb.append("  x.fn = function(");
    86             String sep = "";
    87             for (String n : names) {
    88                 sb.append(sep).append(n);
    89                 sep = ",";
    90             }
    91             sb.append(") {\n");
    92             sb.append(code);
    93             sb.append("};");
    94             sb.append("return x;");
    95             sb.append("})()");
    96             
    97             JSObject x = (JSObject) engine.executeScript(sb.toString());
    98             return new JSFn(x);
    99         }
   100     }
   101     
   102     private static final class JSFn extends Fn {
   103         private final JSObject fn;
   104 
   105         public JSFn(JSObject fn) {
   106             this.fn = fn;
   107         }
   108         
   109         @Override
   110         public Object invoke(Object... args) throws Exception {
   111             return fn.call("fn", args); // NOI18N
   112         }
   113     }
   114 }