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
jaroslav@123
     1
/**
jaroslav@123
     2
 * HTML via Java(tm) Language Bindings
jaroslav@123
     3
 * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@123
     4
 *
jaroslav@123
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@123
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@123
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@123
     8
 *
jaroslav@123
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@123
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@123
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@123
    12
 * GNU General Public License for more details. apidesign.org
jaroslav@123
    13
 * designates this particular file as subject to the
jaroslav@123
    14
 * "Classpath" exception as provided by apidesign.org
jaroslav@123
    15
 * in the License file that accompanied this code.
jaroslav@123
    16
 *
jaroslav@123
    17
 * You should have received a copy of the GNU General Public License
jaroslav@123
    18
 * along with this program. Look for COPYING file in the top folder.
jaroslav@123
    19
 * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
jaroslav@123
    20
 */
jaroslav@123
    21
package org.apidesign.html.boot.impl;
jaroslav@123
    22
jaroslav@123
    23
import org.apidesign.html.boot.spi.Fn;
jaroslav@123
    24
import java.io.IOException;
jaroslav@123
    25
import java.io.InputStream;
jaroslav@163
    26
import java.io.Reader;
jaroslav@123
    27
import java.net.URL;
jaroslav@123
    28
import java.util.Enumeration;
jaroslav@123
    29
jaroslav@123
    30
/** 
jaroslav@123
    31
 *
jaroslav@123
    32
 * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@123
    33
 */
jaroslav@123
    34
abstract class JsClassLoader extends ClassLoader {
jaroslav@123
    35
    JsClassLoader(ClassLoader parent) {
jaroslav@123
    36
        super(parent);
jaroslav@143
    37
        setDefaultAssertionStatus(JsClassLoader.class.desiredAssertionStatus());
jaroslav@123
    38
    }
jaroslav@123
    39
    
jaroslav@123
    40
    @Override
jaroslav@123
    41
    protected abstract URL findResource(String name);
jaroslav@123
    42
    
jaroslav@123
    43
    @Override
jaroslav@123
    44
    protected abstract Enumeration<URL> findResources(String name);
jaroslav@123
    45
jaroslav@123
    46
    @Override
jaroslav@123
    47
    protected Class<?> findClass(String name) throws ClassNotFoundException {
jaroslav@123
    48
        if (name.startsWith("javafx")) {
jaroslav@123
    49
            return Class.forName(name);
jaroslav@123
    50
        }
jaroslav@123
    51
        if (name.startsWith("netscape")) {
jaroslav@123
    52
            return Class.forName(name);
jaroslav@123
    53
        }
jaroslav@123
    54
        if (name.startsWith("com.sun")) {
jaroslav@123
    55
            return Class.forName(name);
jaroslav@123
    56
        }
jaroslav@123
    57
        if (name.equals(JsClassLoader.class.getName())) {
jaroslav@123
    58
            return JsClassLoader.class;
jaroslav@123
    59
        }
jaroslav@123
    60
        if (name.equals(Fn.class.getName())) {
jaroslav@123
    61
            return Fn.class;
jaroslav@123
    62
        }
jaroslav@288
    63
        if (name.equals(Fn.Presenter.class.getName())) {
jaroslav@288
    64
            return Fn.Presenter.class;
jaroslav@288
    65
        }
jaroslav@124
    66
        if (name.equals(FnUtils.class.getName())) {
jaroslav@124
    67
            return FnUtils.class;
jaroslav@124
    68
        }
jaroslav@309
    69
        if (
jaroslav@309
    70
            name.equals("org.apidesign.html.boot.spi.Fn") ||
jaroslav@309
    71
            name.equals("org.apidesign.html.boot.impl.FnUtils") ||
jaroslav@309
    72
            name.equals("org.apidesign.html.boot.impl.FnContext")
jaroslav@309
    73
        ) {
jaroslav@309
    74
            return Class.forName(name);
jaroslav@309
    75
        }
jaroslav@123
    76
        URL u = findResource(name.replace('.', '/') + ".class");
jaroslav@123
    77
        if (u != null) {
jaroslav@123
    78
            InputStream is = null;
jaroslav@123
    79
            try {
jaroslav@123
    80
                is = u.openStream();
jaroslav@123
    81
                byte[] arr = new byte[is.available()];
jaroslav@123
    82
                int len = 0;
jaroslav@123
    83
                while (len < arr.length) {
jaroslav@123
    84
                    int read = is.read(arr, len, arr.length - len);
jaroslav@123
    85
                    if (read == -1) {
jaroslav@123
    86
                        throw new IOException("Can't read " + u);
jaroslav@123
    87
                    }
jaroslav@123
    88
                    len += read;
jaroslav@123
    89
                }
jaroslav@123
    90
                is.close();
jaroslav@123
    91
                is = null;
jaroslav@323
    92
                arr = FnUtils.transform(JsClassLoader.this, arr);
jaroslav@123
    93
                if (arr != null) {
jaroslav@123
    94
                    return defineClass(name, arr, 0, arr.length);
jaroslav@123
    95
                }
jaroslav@123
    96
            } catch (IOException ex) {
jaroslav@123
    97
                throw new ClassNotFoundException("Can't load " + name, ex);
jaroslav@123
    98
            } finally {
jaroslav@123
    99
                try {
jaroslav@123
   100
                    if (is != null) is.close();
jaroslav@123
   101
                } catch (IOException ex) {
jaroslav@123
   102
                    throw new ClassNotFoundException(null, ex);
jaroslav@123
   103
                }
jaroslav@123
   104
            }
jaroslav@123
   105
        }
jaroslav@123
   106
        return super.findClass(name);
jaroslav@123
   107
    }
jaroslav@123
   108
    
jaroslav@123
   109
    protected abstract Fn defineFn(String code, String... names);
jaroslav@163
   110
    protected abstract void loadScript(Reader code) throws Exception;
jaroslav@123
   111
}