Introducing Agent-Class to allow java.lang.instrument-like transforms of the @JavaScriptBody annotation
2 * HTML via Java(tm) Language Bindings
3 * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
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.
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.
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
21 package org.apidesign.html.boot.impl;
23 import org.apidesign.html.boot.spi.Fn;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.Reader;
28 import java.util.Enumeration;
32 * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
34 abstract class JsClassLoader extends ClassLoader {
35 JsClassLoader(ClassLoader parent) {
37 setDefaultAssertionStatus(JsClassLoader.class.desiredAssertionStatus());
41 protected abstract URL findResource(String name);
44 protected abstract Enumeration<URL> findResources(String name);
47 protected Class<?> findClass(String name) throws ClassNotFoundException {
48 if (name.startsWith("javafx")) {
49 return Class.forName(name);
51 if (name.startsWith("netscape")) {
52 return Class.forName(name);
54 if (name.startsWith("com.sun")) {
55 return Class.forName(name);
57 if (name.equals(JsClassLoader.class.getName())) {
58 return JsClassLoader.class;
60 if (name.equals(Fn.class.getName())) {
63 if (name.equals(Fn.Presenter.class.getName())) {
64 return Fn.Presenter.class;
66 if (name.equals(FnUtils.class.getName())) {
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")
74 return Class.forName(name);
76 URL u = findResource(name.replace('.', '/') + ".class");
78 InputStream is = null;
81 byte[] arr = new byte[is.available()];
83 while (len < arr.length) {
84 int read = is.read(arr, len, arr.length - len);
86 throw new IOException("Can't read " + u);
92 arr = FnUtils.transform(JsClassLoader.this, arr);
94 return defineClass(name, arr, 0, arr.length);
96 } catch (IOException ex) {
97 throw new ClassNotFoundException("Can't load " + name, ex);
100 if (is != null) is.close();
101 } catch (IOException ex) {
102 throw new ClassNotFoundException(null, ex);
106 return super.findClass(name);
109 protected abstract Fn defineFn(String code, String... names);
110 protected abstract void loadScript(Reader code) throws Exception;