Package org.apache.bsf.engines.jython

Source Code of org.apache.bsf.engines.jython.JythonEngine$BSFPythonInterpreter

/*
* Copyright 2004,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.bsf.engines.jython;

import java.io.ByteArrayInputStream;
import java.util.Vector;

import org.apache.bsf.BSFDeclaredBean;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
import org.apache.bsf.util.BSFEngineImpl;
import org.apache.bsf.util.BSFFunctions;
import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyJavaInstance;
import org.python.core.PyObject;
import org.python.util.InteractiveInterpreter;

/**
* This is the interface to Jython (http://www.jython.org/) from BSF.
* It's derived from the JPython 1.x engine
*
* @author   Sanjiva Weerawarana
* @author   Finn Bock <bckfnn@worldonline.dk>
* @author   Chuck Murcko
*/

public class JythonEngine extends BSFEngineImpl {
  BSFPythonInterpreter interp;
 
  /**
   * call the named method of the given object.
   */
  public Object call (Object object, String method, Object[] args)
      throws BSFException {
      try {
          PyObject[] pyargs = Py.EmptyObjects;

          if (args != null) {
              pyargs = new PyObject[args.length];
              for (int i = 0; i < pyargs.length; i++)
                  pyargs[i] = Py.java2py(args[i]);
          }

          if (object != null) {
              PyObject o = Py.java2py(object);
              return unwrap(o.invoke(method, pyargs));
          }

          PyObject m = interp.get(method);

          if (m == null)
              m = interp.eval(method);
          if (m != null) {
              return unwrap(m.__call__(pyargs));
          }

          return null;
      } catch (PyException e) {
          throw new BSFException (BSFException.REASON_EXECUTION_ERROR,
                                  "exception from Jython:\n" + e, e);
      }
  }

  /**
   * Declare a bean
   */
  public void declareBean (BSFDeclaredBean bean) throws BSFException {
  interp.set (bean.name, bean.bean);
  }

  /**
   * Evaluate an anonymous function (differs from eval() in that apply()
   * handles multiple lines).
   */
  public Object apply (String source, int lineNo, int columnNo,
                       Object funcBody, Vector paramNames,
                       Vector arguments) throws BSFException {
      try {
          /* We wrapper the original script in a function definition, and
           * evaluate the function. A hack, no question, but it allows
           * apply() to pretend to work on Jython.
           */
          StringBuffer script = new StringBuffer(byteify(funcBody.toString()));
          int index = 0;
          script.insert(0, "def bsf_temp_fn():\n");
        
          while (index < script.length()) {
              if (script.charAt(index) == '\n') {
                  script.insert(index+1, '\t');
              }
              index++;
          }
         
          interp.exec (script.toString ());
         
          Object result = interp.eval ("bsf_temp_fn()");
         
          if (result != null && result instanceof PyJavaInstance)
              result = ((PyJavaInstance)result).__tojava__(Object.class);
          return result;
      } catch (PyException e) {
          throw new BSFException (BSFException.REASON_EXECUTION_ERROR,
                                  "exception from Jython:\n" + e, e);
      }
  }

  /**
   * Evaluate an expression.
   */
  public Object eval (String source, int lineNo, int columnNo,
          Object script) throws BSFException {
  try {
    Object result = interp.eval (byteify(script.toString ()));
    if (result != null && result instanceof PyJavaInstance)
    result = ((PyJavaInstance)result).__tojava__(Object.class);
    return result;
  } catch (PyException e) {
    throw new BSFException (BSFException.REASON_EXECUTION_ERROR,
            "exception from Jython:\n" + e, e);
  }
  }

  /**
   * Execute a script.
   */
  public void exec (String source, int lineNo, int columnNo,
        Object script) throws BSFException {
  try {
    interp.exec (byteify(script.toString ()));
  } catch (PyException e) {
    throw new BSFException (BSFException.REASON_EXECUTION_ERROR,
            "exception from Jython:\n" + e, e);
  }
  }

  /**
   * Execute script code, emulating console interaction.
   */
  public void iexec (String source, int lineNo, int columnNo,
                     Object script) throws BSFException {
      String scriptStr = byteify(script.toString());
      int newline = scriptStr.indexOf("\n");

      if (newline > -1)
          scriptStr = scriptStr.substring(0, newline);

      try {
          if (interp.buffer.length() > 0)
              interp.buffer.append("\n");
          interp.buffer.append(scriptStr);
          if (!(interp.runsource(interp.buffer.toString())))
              interp.resetbuffer();
      } catch (PyException e) {
          interp.resetbuffer();
          throw new BSFException(BSFException.REASON_EXECUTION_ERROR,
                                 "exception from Jython:\n" + e, e);
      }
  }

  /**
   * Initialize the engine.
   */
  public void initialize (BSFManager mgr, String lang,
              Vector declaredBeans) throws BSFException {
  super.initialize (mgr, lang, declaredBeans);

  // create an interpreter
  interp = new BSFPythonInterpreter ();

    // ensure that output and error streams are re-directed correctly
    interp.setOut(System.out);
    interp.setErr(System.err);
   
  // register the mgr with object name "bsf"
  interp.set ("bsf", new BSFFunctions (mgr, this));

    // Declare all declared beans to the interpreter
  int size = declaredBeans.size ();
  for (int i = 0; i < size; i++) {
    declareBean ((BSFDeclaredBean) declaredBeans.elementAt (i));
  }
  }

  /**
   * Undeclare a previously declared bean.
   */
  public void undeclareBean (BSFDeclaredBean bean) throws BSFException {
  interp.set (bean.name, null);
  }

  public Object unwrap(PyObject result) {
  if (result != null) {
     Object ret = result.__tojava__(Object.class);
     if (ret != Py.NoConversion)
      return ret;
  }
  return result;
  }
 
  private String byteify (String orig) {
      // Ugh. Jython likes to be fed bytes, rather than the input string.
      ByteArrayInputStream bais =
          new ByteArrayInputStream(orig.getBytes());
      StringBuffer s = new StringBuffer();
      int c;
     
      while ((c = bais.read()) >= 0) {
          s.append((char)c);
      }

      return s.toString();
  }
 
  private class BSFPythonInterpreter extends InteractiveInterpreter {

      public BSFPythonInterpreter() {
          super();
      }

      // Override runcode so as not to print the stack dump
      public void runcode(PyObject code) {
          try {
              this.exec(code);
          } catch (PyException exc) {
              throw exc;
          }
      }
  }
}
TOP

Related Classes of org.apache.bsf.engines.jython.JythonEngine$BSFPythonInterpreter

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.