ovidiu 02/03/17 13:58:35 Modified: src/scratchpad/schecoon/src/org/apache/cocoon/components/flow JavaScriptInterpreter.java Log: Make available on the JavaScript top level the log and the Cocoon objects. Define print on the top level. Refactored JavaScript scope creation and destruction in separate methods, to be used by both callFunction and readScript. Revision Changes Path 1.5 +99 -76 xml-cocoon2/src/scratchpad/schecoon/src/org/apache/cocoon/components/flow/JavaScriptInterpreter.java Index: JavaScriptInterpreter.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/schecoon/src/org/apache/cocoon/components/flow/JavaScriptInterpreter.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- JavaScriptInterpreter.java 15 Mar 2002 23:38:51 -0000 1.4 +++ JavaScriptInterpreter.java 17 Mar 2002 21:58:35 -0000 1.5 @@ -11,111 +11,156 @@ import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.component.ComponentManager; -import org.apache.avalon.framework.component.Composable; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.logger.AbstractLoggable; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.thread.ThreadSafe; import org.apache.cocoon.Constants; +import org.apache.cocoon.components.flow.javascript.JSCocoon; +import org.apache.cocoon.components.flow.javascript.JSGlobal; +import org.apache.cocoon.components.flow.javascript.JSLog; import org.apache.cocoon.components.treeprocessor.InvokeContext; import org.apache.cocoon.environment.Environment; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.Response; +import org.apache.cocoon.environment.Source; import org.apache.cocoon.environment.http.HttpEnvironment; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; +import org.mozilla.javascript.PropertyException; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; -public class JavaScriptInterpreter extends AbstractLoggable - implements Component, Interpreter, Initializable, Contextualizable, - Composable, ThreadSafe +public class JavaScriptInterpreter extends AbstractInterpreter + implements Initializable { + // This is the only optimization level that supports continuations + // in the Rhino JavaScript implementation + static int OPTIMIZATION_LEVEL = -1; + Scriptable scope; - org.apache.cocoon.environment.Context context; - ComponentManager manager; public void initialize() throws Exception { Context context = org.mozilla.javascript.Context.enter(); + context.setOptimizationLevel(OPTIMIZATION_LEVEL); try { - scope = context.initStandardObjects(null); + scope = context.initStandardObjects(new JSGlobal()); + + // 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); + + // 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; } } - public void contextualize(org.apache.avalon.framework.context.Context context) - throws ContextException + protected Scriptable enterContext(Environment environment) + throws Exception { - this.context = (org.apache.cocoon.environment.Context) - context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); - } + Context context = Context.enter(); + context.setOptimizationLevel(OPTIMIZATION_LEVEL); + context.setCompileFunctionsWithDynamicScope(true); + Scriptable thrScope = context.newObject(scope); - public void compose(ComponentManager manager) - { - this.manager = manager; + 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).setEnvironment(environment); + thrScope.put("cocoon", scope, 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) + { + if (thrScope != null) + thrScope.delete("cocoon"); + Context.getCurrentContext().exit(); } - public synchronized void readScript(String source) + public synchronized Source readScript(Environment environment, + String sourceName) throws Exception { - Context ctx = Context.enter(); - try { - InputStream is = context.getResourceAsStream(source); - Reader reader = new BufferedReader(new InputStreamReader(is)); + Scriptable thrScope = null; + Source source = null; - System.out.println("evaluating JavaScript " + source - + ", scope = " + scope); + System.out.println("Reading JavaScript script " + sourceName); - Object result = ctx.evaluateReader(scope, reader, source, 1, null); - System.out.println("JavaScript result = " + result); - result = scope.get("myf", scope); - System.out.println("myf = " + result); + try { + thrScope = enterContext(environment); + 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 { - ctx.exit(); + exitContext(thrScope); } + return source; } public void callFunction(String funName, List params, Environment environment, InvokeContext ctx) throws Exception { - Context context = Context.enter(); -// context.setCompileFunctionsWithDynamicScope(true); - Scriptable thrScope = context.newObject(scope); + Scriptable thrScope = null; + checkForModifiedScripts(environment); System.out.println("JavaScript: invoking " + funName + ", params = " + params); try { - 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(scope); - - // Put in the thread scope the environment, the request, the - // response, and the interpreter objects. - Map objectModel = environment.getObjectModel(); - Request request - = (Request)objectModel.get(ObjectModelHelper.REQUEST_OBJECT); - Response response - = (Response)objectModel.get(ObjectModelHelper.RESPONSE_OBJECT); - - thrScope.put("environment", thrScope, environment); - thrScope.put("request", thrScope, request); - thrScope.put("response", thrScope, response); - thrScope.put("interpreter", thrScope, this); - - Object fun = thrScope.get(funName, scope); - System.out.println("function " + funName + " = " + fun); + thrScope = enterContext(environment); + Object fun = scope.get(funName, thrScope); if (fun == Scriptable.NOT_FOUND) throw new RuntimeException("'" + funName + "' is undefined!"); @@ -129,38 +174,16 @@ funArgs[i] = ((Interpreter.Argument)params.get(i)).value; } - Object result = ((Function) fun).call(context, thrScope, thrScope, funArgs); - if (result != context.getUndefinedValue()) - System.out.println("result = " + context.toString(result)); - -// String funCall = funName + "();"; -// Object result = context.evaluateString(thrScope, funCall, -// "org.apache.cocoon.flow.JavaScriptInterpreter", -// 1, null); -// System.out.println("result = " + result); + Context cx = Context.getCurrentContext(); + ((Function) fun).call(cx, thrScope, thrScope, funArgs); } finally { - // Remove the environment, request, response and interpreter - // objects from the JavaScript thread scope so they can be - // garbage collected. - thrScope.delete("environment"); - thrScope.delete("request"); - thrScope.delete("response"); - thrScope.delete("interpreter"); - context.exit(); + exitContext(thrScope); } } public void processPipeline(String name, HashMap pipelineArgs, Object bizData) throws Exception { - } - - class JSShell extends ScriptableObject - { - public String getClassName() - { - return "global"; - } } }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]