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]

Reply via email to