launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 17 Jun 2013 19:36:24 +0200
branchclassloader
changeset 1181 b703d9d71f25
parent 1179 2fee889b9830
child 1183 29302b4c0776
permissions -rw-r--r--
Initial attempt to pass this into non-static methods
     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.ArrayList;
    22 import java.util.Collections;
    23 import java.util.Enumeration;
    24 import java.util.List;
    25 import java.util.TooManyListenersException;
    26 import javafx.beans.value.ChangeListener;
    27 import javafx.scene.web.WebEngine;
    28 import netscape.javascript.JSObject;
    29 
    30 /**
    31  *
    32  * @author Jaroslav Tulach <jtulach@netbeans.org>
    33  */
    34 public final class JVMBridge {
    35     private final WebEngine engine;
    36     private final WebClassLoader cl;
    37     
    38     private static ClassLoader[] ldrs;
    39     private static ChangeListener<Void> onBck2BrwsrLoad;
    40     
    41     JVMBridge(WebEngine eng) {
    42         this.engine = eng;
    43         this.cl = new WebClassLoader(JVMBridge.class.getClassLoader().getParent());
    44     }
    45         
    46     public static void registerClassLoaders(ClassLoader[] loaders) {
    47         ldrs = loaders.clone();
    48     }
    49     
    50     public static void addBck2BrwsrLoad(ChangeListener<Void> l) throws TooManyListenersException {
    51         if (onBck2BrwsrLoad != null) {
    52             throw new TooManyListenersException();
    53         }
    54         onBck2BrwsrLoad = l;
    55     }
    56 
    57     public static void onBck2BrwsrLoad() {
    58         ChangeListener<Void> l = onBck2BrwsrLoad;
    59         if (l != null) {
    60             l.changed(null, null, null);
    61         }
    62     }
    63     
    64     public Class<?> loadClass(String name) throws ClassNotFoundException {
    65         return Class.forName(name, true, cl);
    66     }
    67     
    68     private final class WebClassLoader extends JsClassLoader {
    69         public WebClassLoader(ClassLoader parent) {
    70             super(parent);
    71         }
    72 
    73         @Override
    74         protected URL findResource(String name) {
    75             if (ldrs != null) for (ClassLoader l : ldrs) {
    76                 URL u = l.getResource(name);
    77                 if (u != null) {
    78                     return u;
    79                 }
    80             }
    81             return null;
    82         }
    83         
    84         @Override
    85         protected Enumeration<URL> findResources(String name) {
    86             List<URL> arr = new ArrayList<URL>();
    87             if (ldrs != null) {
    88                 for (ClassLoader l : ldrs) {
    89                     URL u = l.getResource(name);
    90                     if (u != null) {
    91                         arr.add(u);
    92                     }
    93                 }
    94             }
    95             return Collections.enumeration(arr);
    96         }
    97 
    98         @Override
    99         protected Fn defineFn(String code, String... names) {
   100             StringBuilder sb = new StringBuilder();
   101             sb.append("(function() {");
   102             sb.append("  var x = {};");
   103             sb.append("  x.fn = function(");
   104             String sep = "";
   105             for (String n : names) {
   106                 sb.append(sep).append(n);
   107                 sep = ",";
   108             }
   109             sb.append(") {\n");
   110             sb.append(code);
   111             sb.append("};");
   112             sb.append("return x;");
   113             sb.append("})()");
   114             
   115             JSObject x = (JSObject) engine.executeScript(sb.toString());
   116             return new JSFn(x);
   117         }
   118     }
   119     
   120     private static final class JSFn extends Fn {
   121         private final JSObject fn;
   122 
   123         public JSFn(JSObject fn) {
   124             this.fn = fn;
   125         }
   126         
   127         @Override
   128         public Object invoke(Object thiz, Object... args) throws Exception {
   129             try {
   130                 return fn.call("fn", args); // NOI18N
   131             } catch (Error t) {
   132                 t.printStackTrace();
   133                 throw t;
   134             } catch (Exception t) {
   135                 t.printStackTrace();
   136                 throw t;
   137             }
   138         }
   139     }
   140 }