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]