/*
* Scriptographer
*
* This file is part of Scriptographer, a Scripting Plugin for Adobe Illustrator
* http://scriptographer.org/
*
* Copyright (c) 2002-2010, Juerg Lehni
* http://scratchdisk.com/
*
* All rights reserved. See LICENSE file for details.
*
* File created on Apr 10, 2007.
*/
package com.scratchdisk.script.rhino;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.Wrapper;
import com.scratchdisk.script.Callable;
/**
* @author lehni
*
*/
public class RhinoCallable extends Callable {
Function function;
RhinoEngine engine;
RhinoCallable(RhinoEngine engine, Function function) {
this.engine = engine;
this.function = function;
}
public Object call(Object obj, Object[] args) throws RhinoScriptException {
// Retrieve wrapper object for the native java object, and call the
// function on it.
try {
Scriptable scope = ScriptableObject.getTopLevelScope(function);
Scriptable wrapper = RhinoEngine.getWrapper(obj, scope);
for (int i = 0; i < args.length; i++)
args[i] = Context.javaToJS(args[i], scope);
Context cx = Context.getCurrentContext();
Object ret = function.call(cx, wrapper, wrapper, args);
if (ret == Undefined.instance) {
// Do not return undefined, as it cannot be handled by the
// native side, e.g. ConversionUtils.toBoolean would produce
// true.
ret = null;
} else if (ret instanceof Wrapper) {
// Unwrap if the return value is a native java object:
ret = ((Wrapper) ret).unwrap();
}
return ret;
} catch (Throwable t) {
// Re-throw if it was a RhinoScriptException already
if (t.getCause() instanceof RhinoScriptException)
throw (RhinoScriptException) t.getCause();
throw new RhinoScriptException(engine, t);
}
}
public Function getCallable() {
return function;
}
public RhinoScope getScope() {
return new RhinoScope(engine,
ScriptableObject.getTopLevelScope(function));
}
}