/******************************************************************************* * Copyright (c) 2001, 2010 Mathew A. Nelson and Robocode contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://robocode.sourceforge.net/license/epl-v10.html * * Contributors: * Pavel Savara * - Initial implementation *******************************************************************************/ package net.sf.robocode.js.host.security; import net.sf.robocode.host.security.RobotClassLoader; import net.sf.robocode.io.Logger; import net.sf.robocode.io.URLJarCollector; import java.net.URL; import java.net.URLConnection; import java.io.*; import org.mozilla.javascript.*; import robocode.robotinterfaces.IBasicRobot; /** * @author Pavel Savara (original) */ public class JsRobotClassLoader extends RobotClassLoader { ContextFactory fac; Context cx; Scriptable scope; IBasicRobot robotInstance; public JsRobotClassLoader(URL robotClassPath, String robotFullClassName) { super(robotClassPath, robotFullClassName); fac = new ContextFactory(); } @Override public Class<?> loadRobotMainClass(boolean resolve) throws ClassNotFoundException { try { cx = fac.enterContext(); cx.setApplicationClassLoader(this); cx.setWrapFactory(new PrimitiveWrapFactory()); scope = cx.initStandardObjects(); String script = robotClassPath.toString() + fullClassName.replace('.', '/') + ".js"; URL sUrl = new URL(script); final URLConnection conn = URLJarCollector.openConnection(sUrl); final InputStream is = conn.getInputStream(); cx.evaluateReader(scope, new InputStreamReader(is), script, 1, null); Object robot = scope.get("robot", scope); if (robot == Scriptable.NOT_FOUND) { throw new ClassNotFoundException("robot variable was not set"); } robot = Context.jsToJava(robot, IBasicRobot.class); if (!(robot instanceof IBasicRobot)) { return null; } robotInstance = (IBasicRobot) robot; robotClass = robot.getClass(); return robotClass; } catch (Throwable e) { Logger.logError(e); throw new ClassNotFoundException(e.getMessage(), e); } } public IBasicRobot createRobotInstance() throws ClassNotFoundException, InstantiationException, IllegalAccessException { loadRobotMainClass(true); return robotInstance; } @Override public void cleanup() { super.cleanup(); scope = null; cx = null; fac = null; } class PrimitiveWrapFactory extends WrapFactory { @Override public Object wrap(Context context, Scriptable scope, Object obj, Class staticType) { if (obj instanceof String || obj instanceof Number || obj instanceof Boolean) { return obj; } else if (obj instanceof Character) { char[] a = { (Character) obj}; return new String(a); } return super.wrap(cx, scope, obj, staticType); } @Override public org.mozilla.javascript.Scriptable wrapNewObject(Context context, Scriptable scope, Object obj) { return super.wrapNewObject(context, scope, obj); } @Override public Scriptable wrapAsJavaObject(Context context, Scriptable scope, Object obj, Class staticType) { return super.wrapAsJavaObject(context, scope, obj, staticType); } } }