jaroslav@123: /** jaroslav@123: * HTML via Java(tm) Language Bindings jaroslav@123: * Copyright (C) 2013 Jaroslav Tulach jaroslav@123: * jaroslav@123: * This program is free software: you can redistribute it and/or modify jaroslav@123: * it under the terms of the GNU General Public License as published by jaroslav@123: * the Free Software Foundation, version 2 of the License. jaroslav@123: * jaroslav@123: * This program is distributed in the hope that it will be useful, jaroslav@123: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@123: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@123: * GNU General Public License for more details. apidesign.org jaroslav@123: * designates this particular file as subject to the jaroslav@123: * "Classpath" exception as provided by apidesign.org jaroslav@123: * in the License file that accompanied this code. jaroslav@123: * jaroslav@123: * You should have received a copy of the GNU General Public License jaroslav@123: * along with this program. Look for COPYING file in the top folder. jaroslav@123: * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException jaroslav@123: */ jaroslav@123: jaroslav@128: package org.apidesign.html.boot.impl; jaroslav@123: jaroslav@323: import java.io.Closeable; jaroslav@163: import java.io.Reader; jaroslav@123: import java.net.URL; jaroslav@123: import java.net.URLClassLoader; jaroslav@123: import java.util.ArrayList; jaroslav@123: import java.util.Arrays; jaroslav@123: import java.util.Collection; jaroslav@123: import java.util.List; jaroslav@123: import javax.script.Invocable; jaroslav@123: import javax.script.ScriptEngine; jaroslav@123: import javax.script.ScriptEngineManager; jaroslav@123: import javax.script.ScriptException; jaroslav@128: import org.apidesign.html.boot.spi.Fn; jaroslav@123: import org.testng.annotations.BeforeClass; jaroslav@288: import org.testng.annotations.BeforeMethod; jaroslav@123: jaroslav@123: /** jaroslav@123: * jaroslav@123: * @author Jaroslav Tulach jaroslav@123: */ jaroslav@123: public class FnTest extends JsClassLoaderBase { jaroslav@288: private static Fn.Presenter presenter; jaroslav@123: jaroslav@123: public FnTest() { jaroslav@123: } jaroslav@123: jaroslav@123: @BeforeClass jaroslav@123: public static void createClassLoader() throws Exception { jaroslav@123: ScriptEngineManager sem = new ScriptEngineManager(); jaroslav@123: final ScriptEngine eng = sem.getEngineByMimeType("text/javascript"); jaroslav@123: jaroslav@123: final URL my = FnTest.class.getProtectionDomain().getCodeSource().getLocation(); jaroslav@123: ClassLoader parent = JsClassLoaderTest.class.getClassLoader().getParent(); jaroslav@123: final URLClassLoader ul = new URLClassLoader(new URL[] { my }, parent); jaroslav@123: jaroslav@128: class Impl implements FindResources, Fn.Presenter { jaroslav@123: @Override jaroslav@123: public void findResources(String path, Collection results, boolean oneIsEnough) { jaroslav@123: URL u = ul.findResource(path); jaroslav@123: if (u != null) { jaroslav@123: results.add(u); jaroslav@123: } jaroslav@123: } jaroslav@123: jaroslav@123: @Override jaroslav@123: public Fn defineFn(String code, String... names) { jaroslav@123: StringBuilder sb = new StringBuilder(); jaroslav@123: sb.append("(function() {"); jaroslav@123: sb.append("return function("); jaroslav@123: String sep = ""; jaroslav@123: for (String n : names) { jaroslav@123: sb.append(sep); jaroslav@123: sb.append(n); jaroslav@123: sep = ", "; jaroslav@123: } jaroslav@123: sb.append(") {"); jaroslav@123: sb.append(code); jaroslav@123: sb.append("};"); jaroslav@123: sb.append("})()"); jaroslav@123: try { jaroslav@123: final Object val = eng.eval(sb.toString()); jaroslav@288: return new Fn(this) { jaroslav@123: @Override jaroslav@289: public Object invoke(Object thiz, Object... args) throws Exception { jaroslav@123: List all = new ArrayList(args.length + 1); jaroslav@123: all.add(thiz == null ? val : thiz); jaroslav@123: all.addAll(Arrays.asList(args)); jaroslav@123: Invocable inv = (Invocable)eng; jaroslav@161: try { jaroslav@161: Object ret = inv.invokeMethod(val, "call", all.toArray()); jaroslav@214: return val.equals(ret) ? null : ret; jaroslav@161: } catch (ScriptException ex) { jaroslav@161: throw ex; jaroslav@161: } jaroslav@123: } jaroslav@123: }; jaroslav@123: } catch (ScriptException ex) { jaroslav@123: throw new LinkageError("Can't parse: " + sb, ex); jaroslav@123: } jaroslav@123: } jaroslav@127: jaroslav@127: @Override jaroslav@128: public void displayPage(URL resource, Runnable r) { jaroslav@127: throw new UnsupportedOperationException(); jaroslav@127: } jaroslav@163: jaroslav@163: @Override jaroslav@163: public void loadScript(Reader code) throws Exception { jaroslav@163: eng.eval(code); jaroslav@163: } jaroslav@123: } jaroslav@123: Impl impl = new Impl(); jaroslav@126: ClassLoader loader = FnUtils.newLoader(impl, impl, parent); jaroslav@288: presenter = impl; jaroslav@123: jaroslav@323: Closeable close = FnContext.activate(impl); jaroslav@123: methodClass = loader.loadClass(JsMethods.class.getName()); jaroslav@323: close.close(); jaroslav@123: } jaroslav@288: jaroslav@288: @BeforeMethod public void initPresenter() { jaroslav@309: FnContext.currentPresenter(presenter); jaroslav@288: } jaroslav@123: }