1.1 --- a/launcher/fx/pom.xml Mon Jun 17 19:55:31 2013 +0200
1.2 +++ b/launcher/fx/pom.xml Thu Jun 20 10:22:50 2013 +0200
1.3 @@ -75,5 +75,10 @@
1.4 <artifactId>asm</artifactId>
1.5 <version>4.1</version>
1.6 </dependency>
1.7 + <dependency>
1.8 + <groupId>org.apidesign.html</groupId>
1.9 + <artifactId>net.java.html.boot</artifactId>
1.10 + <version>0.4-SNAPSHOT</version>
1.11 + </dependency>
1.12 </dependencies>
1.13 </project>
2.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/Fn.java Mon Jun 17 19:55:31 2013 +0200
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,32 +0,0 @@
2.4 -/**
2.5 - * Back 2 Browser Bytecode Translator
2.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.7 - *
2.8 - * This program is free software: you can redistribute it and/or modify
2.9 - * it under the terms of the GNU General Public License as published by
2.10 - * the Free Software Foundation, version 2 of the License.
2.11 - *
2.12 - * This program is distributed in the hope that it will be useful,
2.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.15 - * GNU General Public License for more details.
2.16 - *
2.17 - * You should have received a copy of the GNU General Public License
2.18 - * along with this program. Look for COPYING file in the top folder.
2.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
2.20 - */
2.21 -package org.apidesign.bck2brwsr.launcher.fximpl;
2.22 -
2.23 -/**
2.24 - *
2.25 - * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.26 - */
2.27 -public abstract class Fn {
2.28 - public static Fn define(Class<?> caller, String code, String... names) {
2.29 - JsClassLoader cl = (JsClassLoader)caller.getClassLoader();
2.30 - return cl.defineFn(code, names);
2.31 - }
2.32 -
2.33 - public abstract Object invoke(Object thiz, Object... args) throws Exception;
2.34 -
2.35 -}
3.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java Mon Jun 17 19:55:31 2013 +0200
3.2 +++ b/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JVMBridge.java Thu Jun 20 10:22:50 2013 +0200
3.3 @@ -17,17 +17,21 @@
3.4 */
3.5 package org.apidesign.bck2brwsr.launcher.fximpl;
3.6
3.7 +import org.apidesign.html.boot.spi.Fn;
3.8 import java.net.URL;
3.9 import java.util.ArrayList;
3.10 import java.util.Arrays;
3.11 +import java.util.Collection;
3.12 import java.util.Collections;
3.13 import java.util.Enumeration;
3.14 import java.util.List;
3.15 import java.util.TooManyListenersException;
3.16 import javafx.beans.value.ChangeListener;
3.17 import javafx.scene.web.WebEngine;
3.18 -import javax.script.Invocable;
3.19 +import net.java.html.boot.BrowserBuilder;
3.20 import netscape.javascript.JSObject;
3.21 +import org.apidesign.html.boot.impl.FindResources;
3.22 +import org.apidesign.html.boot.impl.FnUtils;
3.23
3.24 /**
3.25 *
3.26 @@ -35,14 +39,16 @@
3.27 */
3.28 public final class JVMBridge {
3.29 private final WebEngine engine;
3.30 - private final WebClassLoader cl;
3.31 + private final ClassLoader cl;
3.32
3.33 private static ClassLoader[] ldrs;
3.34 private static ChangeListener<Void> onBck2BrwsrLoad;
3.35
3.36 JVMBridge(WebEngine eng) {
3.37 this.engine = eng;
3.38 - this.cl = new WebClassLoader(JVMBridge.class.getClassLoader().getParent());
3.39 + final ClassLoader p = JVMBridge.class.getClassLoader().getParent();
3.40 + WebClassLoader wcl = new WebClassLoader(p);
3.41 + this.cl = FnUtils.newLoader(wcl, wcl, p);
3.42 }
3.43
3.44 public static void registerClassLoaders(ClassLoader[] loaders) {
3.45 @@ -67,38 +73,25 @@
3.46 return Class.forName(name, true, cl);
3.47 }
3.48
3.49 - private final class WebClassLoader extends JsClassLoader {
3.50 + private final class WebClassLoader implements FindResources, Fn.Presenter {
3.51 + private final ClassLoader cl;
3.52 +
3.53 public WebClassLoader(ClassLoader parent) {
3.54 - super(parent);
3.55 + this.cl = parent;
3.56 }
3.57
3.58 @Override
3.59 - protected URL findResource(String name) {
3.60 + public void findResources(String name, Collection<? super URL> results, boolean oneIsEnough) {
3.61 if (ldrs != null) for (ClassLoader l : ldrs) {
3.62 URL u = l.getResource(name);
3.63 if (u != null) {
3.64 - return u;
3.65 + results.add(u);
3.66 }
3.67 }
3.68 - return null;
3.69 - }
3.70 -
3.71 - @Override
3.72 - protected Enumeration<URL> findResources(String name) {
3.73 - List<URL> arr = new ArrayList<URL>();
3.74 - if (ldrs != null) {
3.75 - for (ClassLoader l : ldrs) {
3.76 - URL u = l.getResource(name);
3.77 - if (u != null) {
3.78 - arr.add(u);
3.79 - }
3.80 - }
3.81 - }
3.82 - return Collections.enumeration(arr);
3.83 }
3.84
3.85 @Override
3.86 - protected Fn defineFn(String code, String... names) {
3.87 + public Fn defineFn(String code, String... names) {
3.88 StringBuilder sb = new StringBuilder();
3.89 sb.append("(function() {");
3.90 sb.append(" return function(");
3.91 @@ -115,6 +108,11 @@
3.92 JSObject x = (JSObject) engine.executeScript(sb.toString());
3.93 return new JSFn(x);
3.94 }
3.95 +
3.96 + @Override
3.97 + public void displayPage(URL page, Runnable onPageLoad) {
3.98 + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
3.99 + }
3.100 }
3.101
3.102 private static final class JSFn extends Fn {
4.1 --- a/launcher/fx/src/main/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoader.java Mon Jun 17 19:55:31 2013 +0200
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,396 +0,0 @@
4.4 -/**
4.5 - * Back 2 Browser Bytecode Translator
4.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.7 - *
4.8 - * This program is free software: you can redistribute it and/or modify
4.9 - * it under the terms of the GNU General Public License as published by
4.10 - * the Free Software Foundation, version 2 of the License.
4.11 - *
4.12 - * This program is distributed in the hope that it will be useful,
4.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.15 - * GNU General Public License for more details.
4.16 - *
4.17 - * You should have received a copy of the GNU General Public License
4.18 - * along with this program. Look for COPYING file in the top folder.
4.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
4.20 - */
4.21 -package org.apidesign.bck2brwsr.launcher.fximpl;
4.22 -
4.23 -import java.io.IOException;
4.24 -import java.io.InputStream;
4.25 -import java.net.URL;
4.26 -import java.util.ArrayList;
4.27 -import java.util.Enumeration;
4.28 -import java.util.List;
4.29 -import org.objectweb.asm.AnnotationVisitor;
4.30 -import org.objectweb.asm.ClassReader;
4.31 -import org.objectweb.asm.ClassVisitor;
4.32 -import org.objectweb.asm.ClassWriter;
4.33 -import org.objectweb.asm.Label;
4.34 -import org.objectweb.asm.MethodVisitor;
4.35 -import org.objectweb.asm.Opcodes;
4.36 -import org.objectweb.asm.Type;
4.37 -import org.objectweb.asm.signature.SignatureReader;
4.38 -import org.objectweb.asm.signature.SignatureVisitor;
4.39 -
4.40 -/**
4.41 - *
4.42 - * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.43 - */
4.44 -abstract class JsClassLoader extends ClassLoader {
4.45 - JsClassLoader(ClassLoader parent) {
4.46 - super(parent);
4.47 - }
4.48 -
4.49 - @Override
4.50 - protected abstract URL findResource(String name);
4.51 -
4.52 - @Override
4.53 - protected abstract Enumeration<URL> findResources(String name);
4.54 -
4.55 - @Override
4.56 - protected Class<?> findClass(String name) throws ClassNotFoundException {
4.57 - if (name.startsWith("javafx")) {
4.58 - return Class.forName(name);
4.59 - }
4.60 - if (name.startsWith("netscape")) {
4.61 - return Class.forName(name);
4.62 - }
4.63 - if (name.startsWith("com.sun")) {
4.64 - return Class.forName(name);
4.65 - }
4.66 - if (name.equals(JsClassLoader.class.getName())) {
4.67 - return JsClassLoader.class;
4.68 - }
4.69 - if (name.equals(Fn.class.getName())) {
4.70 - return Fn.class;
4.71 - }
4.72 - URL u = findResource(name.replace('.', '/') + ".class");
4.73 - if (u != null) {
4.74 - InputStream is = null;
4.75 - try {
4.76 - is = u.openStream();
4.77 - byte[] arr = new byte[is.available()];
4.78 - int len = 0;
4.79 - while (len < arr.length) {
4.80 - int read = is.read(arr, len, arr.length - len);
4.81 - if (read == -1) {
4.82 - throw new IOException("Can't read " + u);
4.83 - }
4.84 - len += read;
4.85 - }
4.86 - is.close();
4.87 - is = null;
4.88 - ClassReader cr = new ClassReader(arr);
4.89 - FindInClass tst = new FindInClass(null);
4.90 - cr.accept(tst, 0);
4.91 - if (tst.found > 0) {
4.92 - ClassWriter w = new ClassWriterEx(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
4.93 - FindInClass fic = new FindInClass(w);
4.94 - cr.accept(fic, 0);
4.95 - arr = w.toByteArray();
4.96 - }
4.97 - if (arr != null) {
4.98 - return defineClass(name, arr, 0, arr.length);
4.99 - }
4.100 - } catch (IOException ex) {
4.101 - throw new ClassNotFoundException("Can't load " + name, ex);
4.102 - } finally {
4.103 - try {
4.104 - if (is != null) is.close();
4.105 - } catch (IOException ex) {
4.106 - throw new ClassNotFoundException(null, ex);
4.107 - }
4.108 - }
4.109 - }
4.110 - if (name.startsWith("org.apidesign.bck2brwsr.launcher.fximpl.Fn")) {
4.111 - return Class.forName(name);
4.112 - }
4.113 -
4.114 - return super.findClass(name);
4.115 - }
4.116 -
4.117 - protected abstract Fn defineFn(String code, String... names);
4.118 -
4.119 -
4.120 - private static final class FindInClass extends ClassVisitor {
4.121 - private String name;
4.122 - private int found;
4.123 -
4.124 - public FindInClass(ClassVisitor cv) {
4.125 - super(Opcodes.ASM4, cv);
4.126 - }
4.127 -
4.128 - @Override
4.129 - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
4.130 - this.name = name;
4.131 - super.visit(version, access, name, signature, superName, interfaces);
4.132 - }
4.133 -
4.134 -
4.135 -
4.136 - @Override
4.137 - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
4.138 - return new FindInMethod(access, name, desc,
4.139 - super.visitMethod(access & (~Opcodes.ACC_NATIVE), name, desc, signature, exceptions)
4.140 - );
4.141 - }
4.142 -
4.143 - private final class FindInMethod extends MethodVisitor {
4.144 - private final String name;
4.145 - private final String desc;
4.146 - private final int access;
4.147 - private List<String> args;
4.148 - private String body;
4.149 - private boolean bodyGenerated;
4.150 -
4.151 - public FindInMethod(int access, String name, String desc, MethodVisitor mv) {
4.152 - super(Opcodes.ASM4, mv);
4.153 - this.access = access;
4.154 - this.name = name;
4.155 - this.desc = desc;
4.156 - }
4.157 -
4.158 - @Override
4.159 - public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
4.160 - if ("Lorg/apidesign/bck2brwsr/core/JavaScriptBody;".equals(desc)) { // NOI18N
4.161 - found++;
4.162 - return new FindInAnno();
4.163 - }
4.164 - return super.visitAnnotation(desc, visible);
4.165 - }
4.166 -
4.167 - private void generateJSBody(List<String> args, String body) {
4.168 - this.args = args;
4.169 - this.body = body;
4.170 - }
4.171 -
4.172 - @Override
4.173 - public void visitCode() {
4.174 - if (body == null) {
4.175 - return;
4.176 - }
4.177 - generateBody();
4.178 - }
4.179 -
4.180 - private boolean generateBody() {
4.181 - if (bodyGenerated) {
4.182 - return false;
4.183 - }
4.184 - bodyGenerated = true;
4.185 -
4.186 - super.visitFieldInsn(
4.187 - Opcodes.GETSTATIC, FindInClass.this.name,
4.188 - "$$bck2brwsr$$" + name + "_" + found,
4.189 - "Lorg/apidesign/bck2brwsr/launcher/fximpl/Fn;"
4.190 - );
4.191 - super.visitInsn(Opcodes.DUP);
4.192 - Label ifNotNull = new Label();
4.193 - super.visitJumpInsn(Opcodes.IFNONNULL, ifNotNull);
4.194 -
4.195 - // init Fn
4.196 - super.visitInsn(Opcodes.POP);
4.197 - super.visitLdcInsn(Type.getObjectType(FindInClass.this.name));
4.198 - super.visitLdcInsn(body);
4.199 - super.visitIntInsn(Opcodes.SIPUSH, args.size());
4.200 - super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
4.201 - for (int i = 0; i < args.size(); i++) {
4.202 - String name = args.get(i);
4.203 - super.visitInsn(Opcodes.DUP);
4.204 - super.visitIntInsn(Opcodes.BIPUSH, i);
4.205 - super.visitLdcInsn(name);
4.206 - super.visitInsn(Opcodes.AASTORE);
4.207 - }
4.208 - super.visitMethodInsn(Opcodes.INVOKESTATIC,
4.209 - "org/apidesign/bck2brwsr/launcher/fximpl/Fn", "define",
4.210 - "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/String;)Lorg/apidesign/bck2brwsr/launcher/fximpl/Fn;"
4.211 - );
4.212 - // end of Fn init
4.213 -
4.214 - super.visitLabel(ifNotNull);
4.215 -
4.216 - final int offset;
4.217 - if ((access & Opcodes.ACC_STATIC) == 0) {
4.218 - offset = 1;
4.219 - super.visitIntInsn(Opcodes.ALOAD, 0);
4.220 - } else {
4.221 - offset = 0;
4.222 - super.visitInsn(Opcodes.ACONST_NULL);
4.223 - }
4.224 -
4.225 - super.visitIntInsn(Opcodes.SIPUSH, args.size());
4.226 - super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
4.227 -
4.228 - class SV extends SignatureVisitor {
4.229 - private boolean nowReturn;
4.230 - private Type returnType;
4.231 - private int index;
4.232 -
4.233 - public SV() {
4.234 - super(Opcodes.ASM4);
4.235 - }
4.236 -
4.237 - @Override
4.238 - public void visitBaseType(char descriptor) {
4.239 - final Type t = Type.getType("" + descriptor);
4.240 - if (nowReturn) {
4.241 - returnType = t;
4.242 - return;
4.243 - }
4.244 - FindInMethod.super.visitInsn(Opcodes.DUP);
4.245 - FindInMethod.super.visitIntInsn(Opcodes.SIPUSH, index);
4.246 - FindInMethod.super.visitVarInsn(t.getOpcode(Opcodes.ILOAD), index + offset);
4.247 - String factory;
4.248 - switch (descriptor) {
4.249 - case 'I': factory = "java/lang/Integer"; break;
4.250 - case 'J': factory = "java/lang/Long"; break;
4.251 - case 'S': factory = "java/lang/Short"; break;
4.252 - case 'F': factory = "java/lang/Float"; break;
4.253 - case 'D': factory = "java/lang/Double"; break;
4.254 - case 'Z': factory = "java/lang/Boolean"; break;
4.255 - case 'C': factory = "java/lang/Character"; break;
4.256 - case 'B': factory = "java/lang/Byte"; break;
4.257 - default: throw new IllegalStateException(t.toString());
4.258 - }
4.259 - FindInMethod.super.visitMethodInsn(Opcodes.INVOKESTATIC,
4.260 - factory, "valueOf", "(" + descriptor + ")L" + factory + ";"
4.261 - );
4.262 - FindInMethod.super.visitInsn(Opcodes.AASTORE);
4.263 - index++;
4.264 - }
4.265 -
4.266 - @Override
4.267 - public void visitClassType(String name) {
4.268 - if (nowReturn) {
4.269 - returnType = Type.getObjectType(name);
4.270 - return;
4.271 - }
4.272 - FindInMethod.super.visitInsn(Opcodes.DUP);
4.273 - FindInMethod.super.visitIntInsn(Opcodes.SIPUSH, index);
4.274 - FindInMethod.super.visitVarInsn(Opcodes.ALOAD, index + offset);
4.275 - FindInMethod.super.visitInsn(Opcodes.AASTORE);
4.276 - index++;
4.277 - }
4.278 -
4.279 - @Override
4.280 - public SignatureVisitor visitReturnType() {
4.281 - nowReturn = true;
4.282 - return this;
4.283 - }
4.284 -
4.285 -
4.286 - }
4.287 - SV sv = new SV();
4.288 - SignatureReader sr = new SignatureReader(desc);
4.289 - sr.accept(sv);
4.290 -
4.291 - super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
4.292 - "org/apidesign/bck2brwsr/launcher/fximpl/Fn", "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"
4.293 - );
4.294 - switch (sv.returnType.getSort()) {
4.295 - case Type.VOID:
4.296 - super.visitInsn(Opcodes.RETURN);
4.297 - break;
4.298 - case Type.ARRAY:
4.299 - case Type.OBJECT:
4.300 - super.visitTypeInsn(Opcodes.CHECKCAST, sv.returnType.getInternalName());
4.301 - super.visitInsn(Opcodes.ARETURN);
4.302 - break;
4.303 - default:
4.304 - super.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Number");
4.305 - super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
4.306 - "java/lang/Number", sv.returnType.getClassName() + "Value", "()" + sv.returnType.getDescriptor()
4.307 - );
4.308 - super.visitInsn(sv.returnType.getOpcode(Opcodes.IRETURN));
4.309 - }
4.310 - return true;
4.311 - }
4.312 -
4.313 - @Override
4.314 - public void visitEnd() {
4.315 - super.visitEnd();
4.316 - if (body != null) {
4.317 - if (generateBody()) {
4.318 - // native method
4.319 - super.visitMaxs(1, 0);
4.320 - }
4.321 - FindInClass.this.visitField(
4.322 - Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,
4.323 - "$$bck2brwsr$$" + name + "_" + found,
4.324 - "Lorg/apidesign/bck2brwsr/launcher/fximpl/Fn;",
4.325 - null, null
4.326 - );
4.327 - }
4.328 - }
4.329 -
4.330 -
4.331 -
4.332 -
4.333 -
4.334 - private final class FindInAnno extends AnnotationVisitor {
4.335 - private List<String> args = new ArrayList<String>();
4.336 - private String body;
4.337 -
4.338 - public FindInAnno() {
4.339 - super(Opcodes.ASM4);
4.340 - }
4.341 -
4.342 - @Override
4.343 - public void visit(String name, Object value) {
4.344 - if (name == null) {
4.345 - args.add((String) value);
4.346 - return;
4.347 - }
4.348 - assert name.equals("body");
4.349 - body = (String) value;
4.350 - }
4.351 -
4.352 - @Override
4.353 - public AnnotationVisitor visitArray(String name) {
4.354 - return this;
4.355 - }
4.356 -
4.357 - @Override
4.358 - public void visitEnd() {
4.359 - if (body != null) {
4.360 - generateJSBody(args, body);
4.361 - }
4.362 - }
4.363 - }
4.364 - }
4.365 - }
4.366 -
4.367 - private class ClassWriterEx extends ClassWriter {
4.368 -
4.369 - public ClassWriterEx(ClassReader classReader, int flags) {
4.370 - super(classReader, flags);
4.371 - }
4.372 -
4.373 - @Override
4.374 - protected String getCommonSuperClass(final String type1, final String type2) {
4.375 - Class<?> c, d;
4.376 - ClassLoader classLoader = JsClassLoader.this;
4.377 - try {
4.378 - c = Class.forName(type1.replace('/', '.'), false, classLoader);
4.379 - d = Class.forName(type2.replace('/', '.'), false, classLoader);
4.380 - } catch (Exception e) {
4.381 - throw new RuntimeException(e.toString());
4.382 - }
4.383 - if (c.isAssignableFrom(d)) {
4.384 - return type1;
4.385 - }
4.386 - if (d.isAssignableFrom(c)) {
4.387 - return type2;
4.388 - }
4.389 - if (c.isInterface() || d.isInterface()) {
4.390 - return "java/lang/Object";
4.391 - } else {
4.392 - do {
4.393 - c = c.getSuperclass();
4.394 - } while (!c.isAssignableFrom(d));
4.395 - return c.getName().replace('.', '/');
4.396 - }
4.397 - }
4.398 - }
4.399 -}
5.1 --- a/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java Mon Jun 17 19:55:31 2013 +0200
5.2 +++ b/launcher/fx/src/test/java/org/apidesign/bck2brwsr/launcher/fximpl/JsClassLoaderTest.java Thu Jun 20 10:22:50 2013 +0200
5.3 @@ -23,12 +23,15 @@
5.4 import java.net.URLClassLoader;
5.5 import java.util.ArrayList;
5.6 import java.util.Arrays;
5.7 -import java.util.Enumeration;
5.8 +import java.util.Collection;
5.9 import java.util.List;
5.10 import javax.script.Invocable;
5.11 import javax.script.ScriptEngine;
5.12 import javax.script.ScriptEngineManager;
5.13 import javax.script.ScriptException;
5.14 +import org.apidesign.html.boot.spi.Fn;
5.15 +import org.apidesign.html.boot.impl.FindResources;
5.16 +import org.apidesign.html.boot.impl.FnUtils;
5.17 import static org.testng.Assert.*;
5.18 import org.testng.annotations.BeforeClass;
5.19 import org.testng.annotations.Test;
5.20 @@ -52,13 +55,17 @@
5.21 final URL my = JsClassLoaderTest.class.getProtectionDomain().getCodeSource().getLocation();
5.22 ClassLoader parent = JsClassLoaderTest.class.getClassLoader().getParent();
5.23 final URLClassLoader ul = new URLClassLoader(new URL[] { my }, parent);
5.24 - loader = new JsClassLoader(parent) {
5.25 + class Fr implements FindResources, Fn.Presenter {
5.26 @Override
5.27 - protected URL findResource(String name) {
5.28 - return ul.getResource(name);
5.29 + public void findResources(String path, Collection<? super URL> results, boolean oneIsEnough) {
5.30 + URL u = ul.getResource(path);
5.31 + if (u != null) {
5.32 + results.add(u);
5.33 + }
5.34 }
5.35 +
5.36 @Override
5.37 - protected Fn defineFn(String code, String... names) {
5.38 + public Fn defineFn(String code, String... names) {
5.39 StringBuilder sb = new StringBuilder();
5.40 sb.append("(function() {");
5.41 sb.append("return function(");
5.42 @@ -91,11 +98,12 @@
5.43 }
5.44
5.45 @Override
5.46 - protected Enumeration<URL> findResources(String name) {
5.47 + public void displayPage(URL page, Runnable onPageLoad) {
5.48 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
5.49 }
5.50 - };
5.51 + }
5.52
5.53 + loader = FnUtils.newLoader(new Fr(), new Fr(), parent);
5.54 methodClass = loader.loadClass(JsMethods.class.getName());
5.55 }
5.56