boot/src/main/java/org/apidesign/html/boot/impl/FnUtils.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 12 Sep 2013 09:33:50 +0200
changeset 288 8c5b40231d26
parent 191 f48398ae1418
child 294 7a3abb6bcfc9
child 309 7025177bd67e
permissions -rw-r--r--
Support for multiple FX WebViews running at once in isolation
     1 /**
     2  * HTML via Java(tm) Language Bindings
     3  * Copyright (C) 2013 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. apidesign.org
    13  * designates this particular file as subject to the
    14  * "Classpath" exception as provided by apidesign.org
    15  * in the License file that accompanied this code.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program. Look for COPYING file in the top folder.
    19  * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
    20  */
    21 package org.apidesign.html.boot.impl;
    22 
    23 import java.io.InputStream;
    24 import java.io.InputStreamReader;
    25 import java.io.Reader;
    26 import java.net.URL;
    27 import java.util.ArrayList;
    28 import java.util.Collections;
    29 import java.util.Enumeration;
    30 import java.util.List;
    31 import org.apidesign.html.boot.spi.Fn;
    32 
    33 /**
    34  *
    35  * @author Jaroslav Tulach <jtulach@netbeans.org>
    36  */
    37 public final class FnUtils {
    38     private static final ThreadLocal<Fn.Presenter> CURRENT = new ThreadLocal<Fn.Presenter>();
    39     
    40     private FnUtils() {
    41     }
    42     
    43     public static Fn define(Class<?> caller, String code, String... names) {
    44         return currentPresenter().defineFn(code, names);
    45     }
    46     
    47     public static boolean isJavaScriptCapable(ClassLoader l) {
    48         return l instanceof JsClassLoader;
    49     }
    50     
    51     public static boolean isValid(Fn fn) {
    52         return fn != null && fn.isValid();
    53     }
    54 
    55     public static ClassLoader newLoader(final FindResources f, final Fn.Presenter d, ClassLoader parent) {
    56         return new JsClassLoader(parent) {
    57             @Override
    58             protected URL findResource(String name) {
    59                 List<URL> l = res(name, true);
    60                 return l.isEmpty() ? null : l.get(0);
    61             }
    62             
    63             @Override
    64             protected Enumeration<URL> findResources(String name) {
    65                 return Collections.enumeration(res(name, false));
    66             }
    67             
    68             private List<URL> res(String name, boolean oneIsEnough) {
    69                 List<URL> l = new ArrayList<URL>();
    70                 f.findResources(name, l, oneIsEnough);
    71                 return l;
    72             }
    73             
    74             @Override
    75             protected Fn defineFn(String code, String... names) {
    76                 return d.defineFn(code, names);
    77             }
    78 
    79             @Override
    80             protected void loadScript(Reader code) throws Exception {
    81                 d.loadScript(code);
    82             }
    83         };
    84     }
    85 
    86     static String callback(final String body) {
    87         return new JsCallback() {
    88             @Override
    89             protected CharSequence callMethod(
    90                 String ident, String fqn, String method, String params
    91             ) {
    92                 StringBuilder sb = new StringBuilder();
    93                 sb.append("vm.").append(mangle(fqn, method, params));
    94                 sb.append("(");
    95                 if (ident != null) {
    96                     sb.append(ident);
    97                 }
    98                 return sb;
    99             }
   100 
   101         }.parse(body);
   102     }
   103 
   104     static void loadScript(JsClassLoader jcl, String resource) {
   105         final InputStream script = jcl.getResourceAsStream(resource);
   106         if (script == null) {
   107             throw new NullPointerException("Can't find " + resource);
   108         }
   109         try {
   110             Reader isr = null;
   111             try {
   112                 isr = new InputStreamReader(script, "UTF-8");
   113                 jcl.loadScript(isr);
   114             } finally {
   115                 if (isr != null) {
   116                     isr.close();
   117                 }
   118             }
   119         } catch (Exception ex) {
   120             throw new IllegalStateException("Can't execute " + resource, ex);
   121         } 
   122     }
   123 
   124     public static Fn.Presenter currentPresenter() {
   125         Fn.Presenter p = CURRENT.get();
   126         if (p == null) {
   127             throw new IllegalStateException("No current WebView context around!");
   128         }
   129         return p;
   130     }
   131     
   132     public static Fn.Presenter currentPresenter(Fn.Presenter p) {
   133         Fn.Presenter prev = CURRENT.get();
   134         CURRENT.set(p);
   135         return prev;
   136     }
   137 }