ovidiu 02/04/01 21:37:16 Added: src/scratchpad/schecoon/src/org/apache/cocoon/components/flow/javascript JavaScriptInterpreter.java Log: Moved from the above directory. Revision Changes Path 1.1 xml-cocoon2/src/scratchpad/schecoon/src/org/apache/cocoon/components/flow/javascript/JavaScriptInterpreter.java Index: JavaScriptInterpreter.java =================================================================== package org.apache.cocoon.components.flow.javascript; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.List; import org.apache.avalon.framework.activity.Initializable; import org.apache.cocoon.components.flow.Interpreter; import org.apache.cocoon.components.flow.AbstractInterpreter; import org.apache.cocoon.components.flow.WebContinuation; import org.apache.cocoon.components.treeprocessor.InvokeContext; import org.apache.cocoon.environment.Environment; import org.apache.cocoon.environment.Source; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.NativeArray; import org.mozilla.javascript.PropertyException; import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; /** * Interface with the JavaScript interpreter. * * @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a> * @since March 25, 2002 */ public class JavaScriptInterpreter extends AbstractInterpreter implements Initializable { // This is the only optimization level that supports continuations // in the Christoper Oliver's Rhino JavaScript implementation static int OPTIMIZATION_LEVEL = -1; JSGlobal scope; public void initialize() throws Exception { Context context = Context.enter(); context.setOptimizationLevel(OPTIMIZATION_LEVEL); try { scope = new JSGlobal(context); // Register some handy classes with JavaScript, so we can make // use of them from the flow layer. // Access to the Cocoon log ScriptableObject.defineClass(scope, JSLog.class); // Access to Cocoon internal objects ScriptableObject.defineClass(scope, JSCocoon.class); // Wrapper for WebContinuation ScriptableObject.defineClass(scope, JSWebContinuation.class); // Define some functions on the top level scope String[] names = { "print" }; try { ((ScriptableObject)scope) .defineFunctionProperties(names, JSGlobal.class, ScriptableObject.DONTENUM); } catch (PropertyException e) { throw new Error(e.getMessage()); } // Define some global variables in JavaScript Object args[] = {}; Scriptable log = context.newObject(scope, "Log", args); ((JSLog)log).setLogger(getLogger()); scope.put("log", scope, log); } catch (Exception e) { context.exit(); System.out.println("problem initializing JavaScriptInterpreter: "); e.printStackTrace(); throw e; } } protected Scriptable enterContext(Environment environment, InvokeContext ctx) throws Exception { Context context = Context.enter(); context.setOptimizationLevel(OPTIMIZATION_LEVEL); context.setCompileFunctionsWithDynamicScope(true); Scriptable thrScope = context.newObject(scope); thrScope.setPrototype(scope); // We want 'thrScope' to be a new top-level scope, so set its // parent scope to null. This means that any variables created // by assignments will be properties of "thrScope". thrScope.setParentScope(null); // Put in the thread scope the Cocoon object, which gives access // to the interpreter object, and some Cocoon objects. See // JSCocoon for more details. Object args[] = {}; Scriptable cocoon = context.newObject(scope, "Cocoon", args); ((JSCocoon)cocoon).setInterpreter(this); ((JSCocoon)cocoon).setContext(manager, environment, ctx); ((JSCocoon)cocoon).setContinuationsManager(continuationsMgr); ((JSCocoon)cocoon).setScope(thrScope); thrScope.put("cocoon", thrScope, cocoon); return thrScope; } /** * Remove the Cocoon object from the JavaScript thread scope so it * can be garbage collected, together with all the objects it * contains. */ protected void exitContext(Scriptable thrScope) { JSCocoon cocoon = (JSCocoon)thrScope.get("cocoon", thrScope); cocoon.invalidateContext(); Context.getCurrentContext().exit(); } public Source readScript(Environment environment, String sourceName) throws Exception { Scriptable thrScope = null; Source source = null; System.out.println("Reading file " + sourceName); try { thrScope = enterContext(environment, null); source = environment.resolve(sourceName); InputStream inputStream = source.getInputStream(); Reader reader = new BufferedReader(new InputStreamReader(inputStream)); Context ctx = Context.getCurrentContext(); ctx.evaluateReader(scope, reader, sourceName, 1, null); } catch (Exception ex) { ex.printStackTrace(); throw ex; } finally { exitContext(thrScope); } return source; } public void callFunction(String funName, List params, Environment environment, InvokeContext ctx) throws Exception { Scriptable thrScope = null; checkForModifiedScripts(environment); try { thrScope = enterContext(environment, ctx); Object callFunction = scope.get("callFunction", thrScope); if (callFunction == Scriptable.NOT_FOUND) throw new RuntimeException("Cannot find 'callFunction' " + "(system.js not loaded?)"); Object fun = scope.get(funName, thrScope); if (fun == Scriptable.NOT_FOUND) throw new RuntimeException("'" + funName + "' is undefined!"); if (!(fun instanceof Function)) throw new RuntimeException("'" + funName + "' is not a function!"); Context cx = Context.getCurrentContext(); int size = (params != null ? params.size() : 0); Object[] funArgs = new Object[size]; if (size != 0) { for (int i = 0; i < size; i++) { Object obj = ((Interpreter.Argument)params.get(i)).value; funArgs[i] = ScriptRuntime.toObject(cx, thrScope, obj); } } NativeArray funArgsArray = new NativeArray(funArgs); Object callFunArgs[] = { fun, funArgsArray }; ((Function) callFunction).call(cx, thrScope, thrScope, callFunArgs); } finally { exitContext(thrScope); } } public void handleContinuation(String id, Environment environment, InvokeContext ctx) throws Exception { WebContinuation wk = continuationsMgr.lookupWebContinuation(id); if (wk == null) throw new RuntimeException("No continuation with id " + id); Context context = Context.enter(); context.setOptimizationLevel(OPTIMIZATION_LEVEL); context.setCompileFunctionsWithDynamicScope(true); // Obtain the JS continuation object from it, and setup the // JSCocoon object associated in the dynamic scope of the saved // continuation with the environment and context objects. JSWebContinuation jswk = (JSWebContinuation)wk.getUserObject(); JSCocoon cocoon = jswk.getJSCocoon(); cocoon.setContext(manager, environment, ctx); Scriptable kScope = cocoon.getScope(); // We can now resume the processing from the state saved by the // continuation object. Setup the JavaScript Context object. Object handleContFunction = scope.get("handleContinuation", kScope); if (handleContFunction == Scriptable.NOT_FOUND) throw new RuntimeException("Cannot find 'handleContinuation' " + "(system.js not loaded?)"); Object args[] = { jswk }; try { ((Function)handleContFunction).call(context, kScope, kScope, args); } finally { context.exit(); } } }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]