Package org.apache.bsf.engines.javascript

Source Code of org.apache.bsf.engines.javascript.RhinoScriptEngine

package org.apache.bsf.engines.javascript;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.GenericScriptEngine;
import javax.script.Invocable;
import javax.script.Namespace;
import javax.script.ScriptContext;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;

import org.apache.bsf.util.BSFInvocation;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.WrappedException;

/**
* This is interface to Netscape's Rhino (JavaScript) form Web Scripting
* Framework.
* NOTE : Some of the code were taken form JavaScript engine used in
* Jakarta Apache Beans Scritping Framework.
*
* @author Nandika Jayawardana <nandika@opensource.lk>
* @author Sanka Samaranayake  <sanka@opensource.lk>
*/
public class RhinoScriptEngine extends GenericScriptEngine implements Compilable, Invocable{
    private RhinoNamespaceBridge rhinospace;
    private BSFInvocation invoker;
   
   
    /**
     * Constructs an instance of RhinoScriptEngine.
     */
    public RhinoScriptEngine(){
        super();
        // setting up the Engine Namespace ..
        rhinospace = new RhinoNamespaceBridge(this);
        invoker = new BSFInvocation(this);
    }
   
    public RhinoScriptEngine(Namespace namespace){
        super(namespace);
        rhinospace = new RhinoNamespaceBridge(this);
    }
 
    public Object call(String methodName, Object thiz, Object[] args)
            throws ScriptException {
     
        Context cx;
        Scriptable scope;
        Object retValue = null;
       
        if (thiz != null && !(thiz instanceof Scriptable)) {
             throw new IllegalArgumentException(thiz
                              + " is not a valid JavaScript object");
        }
       
        scope = (thiz == null) ? rhinospace : (Scriptable) thiz;
       
        try {
         
            cx = Context.enter();
            Object func = scope.get(methodName, scope);
           
            if (func == null || !(func instanceof Function)) {
                throw new EvaluatorException("Function " + methodName
                          + " not found");
            }
           
            cx.setGeneratingDebug(false);
            cx.setGeneratingSource(false);
            cx.setOptimizationLevel(-1);
            retValue = ((Function) func).call(cx, scope,
                               (Scriptable) thiz, args);
           
        } catch (Throwable throwable) {
            errorHandler(throwable);
        } finally {
            Context.exit();
        }
       
        return unwrap(retValue);
    }
   
    public Object call(String methodName, Object[] args)
            throws ScriptException {
        return call(methodName, null, args);
    }
   
    public CompiledScript compile(Reader reader) throws ScriptException {
     
        Context cx;
        Script script = null;
       
        try {
         
            cx = Context.enter();
            String source =
                ((String) rhinospace.get("javax.script.filename") != null)
                ? (String) rhinospace.get("javax.script.filename")
                : "<unknown>";
               
                script = cx.compileReader(reader, source, 0, null);
               
        } catch (Throwable throwable) {
            errorHandler(throwable);
        } finally {
            Context.exit();
        }
       
        return new RhinoCompiledScript(script, this);
    }
   
    public CompiledScript compile(String script) throws ScriptException {
        return compile(new StringReader(script));
    }
   
    public Namespace createNamespace(){
        return new RhinoNamespaceBridge(this);
    }
       
    public Object eval(Reader reader, ScriptContext context)
            throws ScriptException{
    
        Context cx;
        Object retVal = null;
        RhinoNamespaceBridge oldSpace = rhinospace;
        String source = (get("javax.script.filename") != null)
                ? get("javax.script.filename").toString()
                : "<unknown>";
       
        try {
         
            cx = Context.enter();
            cx.setGeneratingDebug(false);
            cx.setGeneratingSource(false);
            cx.setOptimizationLevel(-1);
            Scriptable sc = getScope(context);
            retVal = cx.evaluateReader(sc, reader, source, 0, null);
        } catch (JavaScriptException ex) {
            errorHandler(ex);
        } catch (IOException ioe) {
            errorHandler(ioe);
        } finally {
            rhinospace = oldSpace;
            Context.exit();
        }
       
        return unwrap(retVal);
    }
   
    public Object eval(String script, ScriptContext context)
            throws ScriptException {
        return eval(new StringReader(script), context);
    }
       
    public ScriptEngineFactory getFactory() {
        return new RhinoScriptEngineFactory();
    }
   
    public Object getInterface(Class clasz) {
        return invoker.getInterface(clasz);
    }
   
    public Object unwrap(Object value){
        value = (value instanceof NativeJavaObject) ?
                ((NativeJavaObject)value).unwrap() : value;
        return !(value instanceof Undefined) ? value : null;
    }
   
    public Scriptable getScope(ScriptContext context){
        RhinoNamespaceBridge targetScope;
       
        Namespace enginespace =  context.getNamespace(ScriptContext.ENGINE_SCOPE),
              globalsapce = context.getNamespace(ScriptContext.GLOBAL_SCOPE);
       
        if (enginespace != null && enginespace != rhinospace) {
          if (enginespace instanceof RhinoNamespaceBridge) {
                targetScope = (RhinoNamespaceBridge)enginespace;
            } else {
              targetScope = new RhinoNamespaceBridge(enginespace);
            }         
        } else {
          targetScope = rhinospace;
        }
       
       
        if (globalspace != null) {
          targetScope.setGlobalNamespace(globalspace);         
        }
       
        targetScope.put("context", context);
        return targetScope;
    }

    public void errorHandler(Throwable throwable) throws ScriptException{
        String message = null;
        String source = null;
        int lineNumber = -1;
        int columnNumber = -1;
       
        // gets the wrapped exception if the argument is a wrapper
        if(throwable instanceof WrappedException){
            throwable = ((WrappedException)throwable).getWrappedException();
        }
        /*
        if(throwable instanceof JavaScriptException){
            message = throwable.getLocalizedMessage();
            source = ((JavaScriptException)throwable).getSourceName();
           
            if(((JavaScriptException)throwable).getLineNumber() != 0){
                lineNumber = ((JavaScriptException)throwable).getLineNumber();
            }
           
        }else if(throwable instanceof EvaluatorException){
            message = ((EvaluatorException)throwable).getLocalizedMessage();
            source = ((EvaluatorException)throwable).getSourceName();
           
            if(((EvaluatorException)throwable).getLineNumber() != 0){
                lineNumber = ((EvaluatorException)throwable).getLineNumber();
            }
            if(((EvaluatorException)throwable).getColumnNumber() != 0){
                columnNumber = ((EvaluatorException)throwable).getColumnNumber();
            }
        }else if(throwable instanceof StackOverflowError){
            message = "STACK OVERFLOW :";
        }
        */
        if(message == null){
            message = throwable.toString();
        }
       
        if(throwable instanceof Error &&
                !(throwable instanceof StackOverflowError)){
            throw (Error)throwable;
        }else{
            throw new ScriptException(message, source, lineNumber, columnNumber);
        }       
    }
}
TOP

Related Classes of org.apache.bsf.engines.javascript.RhinoScriptEngine

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.