launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 06 Jan 2014 13:31:04 +0100
branchNbHtml4J
changeset 1418 b8ff900a542d
parent 1282 8d29792a09c6
child 1423 237dbcd482dc
permissions -rw-r--r--
Switching to new 'NetBeans' packaging schema of forthcoming 0.7 version
     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.io.BufferedReader;
    21 import java.io.Reader;
    22 import java.net.URL;
    23 import java.util.ArrayList;
    24 import java.util.Arrays;
    25 import java.util.Collection;
    26 import java.util.List;
    27 import java.util.TooManyListenersException;
    28 import javafx.beans.value.ChangeListener;
    29 import javafx.scene.web.WebEngine;
    30 import netscape.javascript.JSObject;
    31 import org.apidesign.html.boot.spi.Fn;
    32 import org.netbeans.html.boot.impl.FindResources;
    33 import org.netbeans.html.boot.impl.FnUtils;
    34 
    35 /**
    36  *
    37  * @author Jaroslav Tulach <jtulach@netbeans.org>
    38  */
    39 public final class JVMBridge {
    40     private final WebEngine engine;
    41     private final ClassLoader cl;
    42     private final WebPresenter presenter;
    43     
    44     private static ClassLoader[] ldrs;
    45     private static ChangeListener<Void> onBck2BrwsrLoad;
    46     
    47     JVMBridge(WebEngine eng) {
    48         this.engine = eng;
    49         final ClassLoader p = JVMBridge.class.getClassLoader().getParent();
    50         this.presenter = new WebPresenter();
    51         this.cl = FnUtils.newLoader(presenter, presenter, p);
    52     }
    53         
    54     public static void registerClassLoaders(ClassLoader[] loaders) {
    55         ldrs = loaders.clone();
    56     }
    57     
    58     public static void addBck2BrwsrLoad(ChangeListener<Void> l) throws TooManyListenersException {
    59         if (onBck2BrwsrLoad != null) {
    60             throw new TooManyListenersException();
    61         }
    62         onBck2BrwsrLoad = l;
    63     }
    64 
    65     public static void onBck2BrwsrLoad() {
    66         ChangeListener<Void> l = onBck2BrwsrLoad;
    67         if (l != null) {
    68             l.changed(null, null, null);
    69         }
    70     }
    71     
    72     public Class<?> loadClass(String name) throws ClassNotFoundException {
    73         Fn.activate(presenter);
    74         return Class.forName(name, true, cl);
    75     }
    76     
    77     private final class WebPresenter implements FindResources, Fn.Presenter {
    78         @Override
    79         public void findResources(String name, Collection<? super URL> results, boolean oneIsEnough) {
    80             if (ldrs != null) for (ClassLoader l : ldrs) {
    81                 URL u = l.getResource(name);
    82                 if (u != null) {
    83                     results.add(u);
    84                 }
    85             }
    86         }
    87 
    88         @Override
    89         public Fn defineFn(String code, String... names) {
    90             StringBuilder sb = new StringBuilder();
    91             sb.append("(function() {");
    92             sb.append("  return function(");
    93             String sep = "";
    94             for (String n : names) {
    95                 sb.append(sep).append(n);
    96                 sep = ",";
    97             }
    98             sb.append(") {\n");
    99             sb.append(code);
   100             sb.append("};");
   101             sb.append("})()");
   102             
   103             JSObject x = (JSObject) engine.executeScript(sb.toString());
   104             return new JSFn(this, x);
   105         }
   106 
   107         @Override
   108         public void displayPage(URL page, Runnable onPageLoad) {
   109             throw new UnsupportedOperationException("Not supported yet.");
   110         }
   111 
   112         @Override
   113         public void loadScript(Reader code) throws Exception {
   114             BufferedReader r = new BufferedReader(code);
   115             StringBuilder sb = new StringBuilder();
   116             for (;;) {
   117                 String l = r.readLine();
   118                 if (l == null) {
   119                     break;
   120                 }
   121                 sb.append(l).append('\n');
   122             }
   123             engine.executeScript(sb.toString());
   124         }
   125     }
   126     
   127     private static final class JSFn extends Fn {
   128         private final JSObject fn;
   129 
   130         private JSFn(WebPresenter cl, JSObject fn) {
   131             super(cl);
   132             this.fn = fn;
   133         }
   134 
   135         @Override
   136         public Object invoke(Object thiz, Object... args) throws Exception {
   137             try {
   138                 List<Object> all = new ArrayList<Object>(args.length + 1);
   139                 all.add(thiz == null ? fn : thiz);
   140                 all.addAll(Arrays.asList(args));
   141                 Object ret = fn.call("call", all.toArray()); // NOI18N
   142                 return ret == fn ? null : ret;
   143             } catch (Error t) {
   144                 t.printStackTrace();
   145                 throw t;
   146             } catch (Exception t) {
   147                 t.printStackTrace();
   148                 throw t;
   149             }
   150         }
   151     }
   152 }