20080913, rgf

org.apache.bsf.engines.java
Class JavaEngine

java.lang.Object
  extended byorg.apache.bsf.util.BSFEngineImpl
      extended byorg.apache.bsf.engines.java.JavaEngine
All Implemented Interfaces:
BSFEngine, java.util.EventListener, java.beans.PropertyChangeListener

public class JavaEngine
extends BSFEngineImpl

This is the interface to Java from the Bean Scripting Framework.

The Java code must be written script-style -- that is, just the body of the function, without class or method headers or footers. The JavaEngine will generate those via a "boilerplate" wrapper:

 
 import java.lang.*;
 import java.util.*;
 public class $$CLASSNAME$$ {
   static public Object BSFJavaEngineEntry(org.apache.bsf.BSFManager bsf) {
     // Your code will be placed here
   }
 }
 
 
$$CLASSNAME$$ will be replaced by a generated classname of the form BSFJava*, and the bsf parameter can be used to retrieve application objects registered with the Bean Scripting Framework.

If you use the placeholder string $$CLASSNAME$$ elsewhere in your script -- including within text strings -- BSFJavaEngine will replace it with the generated name of the class before the Java code is compiled.

Hazards:

NOTE that it is your responsibility to convert the code into an acceptable Java string. If you're invoking the JavaEngine directly (as in the JSPLikeInJava example) that means \"quoting\" characters that would otherwise cause trouble.

ALSO NOTE that it is your responsibility to return an object, or null in lieu thereof!

Since the code has to be compiled to a Java classfile, invoking it involves a fair amount of computation to load and execute the compiler. We are currently making an attempt to manage that by caching the class after it has been loaded, but the indexing is fairly primitive. It has been suggested that the Bean Scripting Framework may want to support preload-and-name-script and execute-preloaded-script-by-name options to provide better control over when and how much overhead occurs.

Author:
Joe Kesselman, Rony G. Flatscher (added BSF_Log[Factory] to allow BSF to run without org.apache.commons.logging present)

Field Summary
(package private) static java.util.Hashtable codeToClass
           
(package private)  java.lang.Class javaclass
           
(package private)  java.lang.String minorPrefix
           
(package private) static java.lang.String placeholder
           
(package private) static java.lang.String serializeCompilation
           
 
Fields inherited from class org.apache.bsf.util.BSFEngineImpl
classLoader, classPath, declaredBeans, lang, mgr, tempDir
 
Constructor Summary
JavaEngine()
          Constructor.
 
Method Summary
 java.lang.Object call(java.lang.Object object, java.lang.String method, java.lang.Object[] args)
          This is used by an application to call into the scripting engine to make a function/method call.
 void compileScript(java.lang.String source, int lineNo, int columnNo, java.lang.Object script, CodeBuffer cb)
          Default impl of compileScript - generates code that'll create a new manager, and execute the script.
 java.lang.Object eval(java.lang.String source, int lineNo, int columnNo, java.lang.Object oscript)
          This is used by an application to evaluate a string containing some expression.
 void initialize(BSFManager mgr, java.lang.String lang, java.util.Vector declaredBeans)
          initialize the engine; called right after construction by the manager.
(package private)  java.lang.Object internalCall(java.lang.Object object, java.lang.String method, java.lang.Object[] args)
          Return an object from an extension.
 
Methods inherited from class org.apache.bsf.util.BSFEngineImpl
apply, compileApply, compileExpr, declareBean, exec, iexec, propertyChange, terminate, undeclareBean
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

javaclass

java.lang.Class javaclass

codeToClass

static java.util.Hashtable codeToClass

serializeCompilation

static java.lang.String serializeCompilation

placeholder

static java.lang.String placeholder

minorPrefix

java.lang.String minorPrefix
Constructor Detail

JavaEngine

public JavaEngine()
Constructor.

Method Detail

call

public java.lang.Object call(java.lang.Object object,
                             java.lang.String method,
                             java.lang.Object[] args)
                      throws BSFException
Description copied from interface: BSFEngine
This is used by an application to call into the scripting engine to make a function/method call. The "object" argument is the object whose method is to be called, if that applies. For non-OO languages, this is typically ignored and should be given as null. For pretend-OO languages such as VB, this would be the (String) name of the object. The arguments are given in the args array.

Parameters:
object - object on which to make the call
method - name of the method / procedure to call
args - the arguments to be given to the procedure
Throws:
BSFException - if anything goes wrong while eval'ing a BSFException is thrown. The reason indicates the problem.

compileScript

public void compileScript(java.lang.String source,
                          int lineNo,
                          int columnNo,
                          java.lang.Object script,
                          CodeBuffer cb)
                   throws BSFException
Description copied from class: BSFEngineImpl
Default impl of compileScript - generates code that'll create a new manager, and execute the script.

Specified by:
compileScript in interface BSFEngine
Overrides:
compileScript in class BSFEngineImpl
Throws:
BSFException

eval

public java.lang.Object eval(java.lang.String source,
                             int lineNo,
                             int columnNo,
                             java.lang.Object oscript)
                      throws BSFException
This is used by an application to evaluate a string containing some expression. It should store the "bsf" handle where the script can get to it, for callback purposes.

Note that Java compilation imposes serious overhead, but in exchange you get full Java performance once the classes have been created (minus the cache lookup cost).

Nobody knows whether javac is threadsafe. I'm going to serialize access to protect it.

There is no published API for invoking javac as a class. There's a trick that seems to work for Java 1.1.x, but it stopped working in Java 1.2. We will attempt to use it, then if necessary fall back on invoking javac via the command line.

Parameters:
source - (context info) the source of this expression (e.g., filename)
lineNo - (context info) the line number in source for expr
columnNo - (context info) the column number in source for expr
oscript - the expression to evaluate
Throws:
BSFException - if anything goes wrong while eval'ing a BSFException is thrown. The reason indicates the problem.

initialize

public void initialize(BSFManager mgr,
                       java.lang.String lang,
                       java.util.Vector declaredBeans)
                throws BSFException
Description copied from class: BSFEngineImpl
initialize the engine; called right after construction by the manager. Declared beans are simply kept in a vector and that's it. Subclasses must do whatever they want with it.

Specified by:
initialize in interface BSFEngine
Overrides:
initialize in class BSFEngineImpl
Throws:
BSFException

internalCall

java.lang.Object internalCall(java.lang.Object object,
                              java.lang.String method,
                              java.lang.Object[] args)
                        throws BSFException
Return an object from an extension.

Parameters:
object - Object on which to make the internal_call (ignored).
method - The name of the method to internal_call.
args - an array of arguments to be passed to the extension, which may be either Vectors of Nodes, or Strings.
Throws:
BSFException

20080913, rgf