boot/src/main/java/org/apidesign/html/boot/impl/JsClassLoader.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 06 Nov 2013 15:15:54 +0100
changeset 323 86aabecda7a3
parent 309 7025177bd67e
child 352 67d1fd89cc80
child 358 80702021b851
permissions -rw-r--r--
Introducing Agent-Class to allow java.lang.instrument-like transforms of the @JavaScriptBody annotation
     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 org.apidesign.html.boot.spi.Fn;
    24 import java.io.IOException;
    25 import java.io.InputStream;
    26 import java.io.Reader;
    27 import java.net.URL;
    28 import java.util.Enumeration;
    29 
    30 /** 
    31  *
    32  * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    33  */
    34 abstract class JsClassLoader extends ClassLoader {
    35     JsClassLoader(ClassLoader parent) {
    36         super(parent);
    37         setDefaultAssertionStatus(JsClassLoader.class.desiredAssertionStatus());
    38     }
    39     
    40     @Override
    41     protected abstract URL findResource(String name);
    42     
    43     @Override
    44     protected abstract Enumeration<URL> findResources(String name);
    45 
    46     @Override
    47     protected Class<?> findClass(String name) throws ClassNotFoundException {
    48         if (name.startsWith("javafx")) {
    49             return Class.forName(name);
    50         }
    51         if (name.startsWith("netscape")) {
    52             return Class.forName(name);
    53         }
    54         if (name.startsWith("com.sun")) {
    55             return Class.forName(name);
    56         }
    57         if (name.equals(JsClassLoader.class.getName())) {
    58             return JsClassLoader.class;
    59         }
    60         if (name.equals(Fn.class.getName())) {
    61             return Fn.class;
    62         }
    63         if (name.equals(Fn.Presenter.class.getName())) {
    64             return Fn.Presenter.class;
    65         }
    66         if (name.equals(FnUtils.class.getName())) {
    67             return FnUtils.class;
    68         }
    69         if (
    70             name.equals("org.apidesign.html.boot.spi.Fn") ||
    71             name.equals("org.apidesign.html.boot.impl.FnUtils") ||
    72             name.equals("org.apidesign.html.boot.impl.FnContext")
    73         ) {
    74             return Class.forName(name);
    75         }
    76         URL u = findResource(name.replace('.', '/') + ".class");
    77         if (u != null) {
    78             InputStream is = null;
    79             try {
    80                 is = u.openStream();
    81                 byte[] arr = new byte[is.available()];
    82                 int len = 0;
    83                 while (len < arr.length) {
    84                     int read = is.read(arr, len, arr.length - len);
    85                     if (read == -1) {
    86                         throw new IOException("Can't read " + u);
    87                     }
    88                     len += read;
    89                 }
    90                 is.close();
    91                 is = null;
    92                 arr = FnUtils.transform(JsClassLoader.this, arr);
    93                 if (arr != null) {
    94                     return defineClass(name, arr, 0, arr.length);
    95                 }
    96             } catch (IOException ex) {
    97                 throw new ClassNotFoundException("Can't load " + name, ex);
    98             } finally {
    99                 try {
   100                     if (is != null) is.close();
   101                 } catch (IOException ex) {
   102                     throw new ClassNotFoundException(null, ex);
   103                 }
   104             }
   105         }
   106         return super.findClass(name);
   107     }
   108     
   109     protected abstract Fn defineFn(String code, String... names);
   110     protected abstract void loadScript(Reader code) throws Exception;
   111 }