Web Site

org.codehaus.janino
Class ExpressionEvaluator

java.lang.Object
  extended byorg.codehaus.janino.Cookable
      extended byorg.codehaus.janino.SimpleCompiler
          extended byorg.codehaus.janino.ClassBodyEvaluator
              extended byorg.codehaus.janino.ScriptEvaluator
                  extended byorg.codehaus.janino.ExpressionEvaluator

public class ExpressionEvaluator
extends ScriptEvaluator

An engine that evaluates expressions in JavaTM bytecode.

The syntax of the expression to compile is that of a JavaTM expression, as defined in the Java Language Specification, 2nd edition, section 15. Notice that a JavaTM expression does not have a concluding semicolon.

Example:

   a + 7 * b
(Notice that this expression refers to two parameters "a" and "b", as explained below.)

The expression may optionally be preceeded with a sequence of import directives like

   import java.text.*;
   new DecimalFormat("####,###.##").format(10200020.345345)
 
(Notice that the import directive is concluded with a semicolon, while the expression is not.) This feature is not available if you compile many expressions at a time (see below).

The expression evaluator is implemented by creating and compiling a temporary compilation unit defining one class with one static method with one RETURN statement.

To set up an ExpressionEvaluator object, proceed as follows:

  1. Create the ExpressionEvaluator using ExpressionEvaluator()
  2. Configure the ExpressionEvaluator by calling any of the following methods:
  3. Call any of the Cookable.cook(Scanner) methods to scan, parse, compile and load the expression into the JVM.
After the ExpressionEvaluator object is set up, the expression can be evaluated as often with different parameter values (see ScriptEvaluator.evaluate(Object[])). This evaluation is very fast, compared to the compilation.

Less common methods exist that allow for the specification of the name of the generated class, the class it extends, the interfaces it implements, the name of the method that executes the expression, the exceptions that this method (i.e. the expression) is allowed to throw, and the ClassLoader that is used to define the generated class and to load classes referenced by the expression.

Alternatively, a number of "convenience constructors" exist that execute the steps described above instantly.

If you want to compile many expressions at the same time, you have the option to cook an array of expressions in one ExpressionEvaluator by using the following methods:

Notice that these methods have array parameters in contrast to their one-expression brethren.

Notice that for functionally identical ExpressionEvaluators, Object.equals(java.lang.Object) will return true. E.g. "a+b" and "c + d" are functionally identical if "a" and "c" have the same type, and so do "b" and "d".

If the parameter and return types of the expression are known at compile time, then a "fast" expression evaluator can be instantiated through createFastExpressionEvaluator(String, Class, String[], ClassLoader). Expression evaluation is faster than through ScriptEvaluator.evaluate(Object[]), because it is not done through reflection but through direct method invocation.

Example:

 public interface Foo {
     int bar(int a, int b);
 }
 ...
 Foo f = (Foo) ExpressionEvaluator.createFastExpressionEvaluator(
     "a + b",                    // expression to evaluate
     Foo.class,                  // interface that describes the expression's signature
     new String[] { "a", "b" },  // the parameters' names
     (ClassLoader) null          // Use current thread's context class loader
 );
 System.out.println("1 + 2 = " + f.bar(1, 2)); // Evaluate the expression
 
Notice: The interfaceToImplement must either be declared public, or with package scope in the root package (i.e. "no" package).

On my system (Intel P4, 2 GHz, MS Windows XP, JDK 1.4.1), expression "x + 1" evaluates as follows:

Server JVMClient JVM
Normal EE23.7 ns64.0 ns
Fast EE31.2 ns42.2 ns
(How can it be that interface method invocation is slower than reflection for the server JVM?)

The expression may refer to a set of parameters with the given parameterNames and parameterTypes.

parameterNames and parameterTypes must have the same number of elements.

The parameters and/or the return value can be of primitive type, e.g. Double.TYPE.

The optionalClassLoader serves two purposes:

If the optionalClassLoader is null, then the current thread's context class loader is used.

A number of constructors exist that provide useful default values for the various parameters, or parse their script from a String instead of a Scanner. (You hardly want to use a scanner other than the default scanner.)

If the type of the expression is not fixed, you can pass a null optionalExpressionType argument; in this case, references are returned as Objects, and primitive values are wrapped in their wrapper classes.

If optionalExpressionType is Void.TYPE, then the expression must be an invocation of a void method.


Field Summary
static java.lang.Class ANY_TYPE
           
 
Fields inherited from class org.codehaus.janino.ScriptEvaluator
optionalMethodNames, optionalParameterNames, optionalParameterTypes, optionalReturnTypes, optionalStaticMethod, optionalThrownExceptions
 
Fields inherited from class org.codehaus.janino.ClassBodyEvaluator
className, DEFAULT_CLASS_NAME, ZERO_CLASSES
 
Fields inherited from class org.codehaus.janino.SimpleCompiler
BOOT_CLASS_LOADER
 
Constructor Summary
ExpressionEvaluator()
           
ExpressionEvaluator(Scanner scanner, java.lang.String className, java.lang.Class optionalExtendedType, java.lang.Class[] implementedTypes, boolean staticMethod, java.lang.Class expressionType, java.lang.String methodName, java.lang.String[] parameterNames, java.lang.Class[] parameterTypes, java.lang.Class[] thrownExceptions, java.lang.ClassLoader optionalParentClassLoader)
          Equivalent to
ExpressionEvaluator(java.lang.String expression, java.lang.Class expressionType, java.lang.String[] parameterNames, java.lang.Class[] parameterTypes)
          Equivalent to
ExpressionEvaluator(java.lang.String expression, java.lang.Class expressionType, java.lang.String[] parameterNames, java.lang.Class[] parameterTypes, java.lang.Class[] thrownExceptions, java.lang.Class optionalExtendedType, java.lang.Class[] implementedTypes, java.lang.ClassLoader optionalParentClassLoader)
          Equivalent to
ExpressionEvaluator(java.lang.String expression, java.lang.Class expressionType, java.lang.String[] parameterNames, java.lang.Class[] parameterTypes, java.lang.Class[] thrownExceptions, java.lang.ClassLoader optionalParentClassLoader)
          Equivalent to
 
Method Summary
static java.lang.Object createFastExpressionEvaluator(Scanner scanner, java.lang.String[] optionalDefaultImports, java.lang.String className, java.lang.Class optionalExtendedType, java.lang.Class interfaceToImplement, java.lang.String[] parameterNames, java.lang.ClassLoader optionalParentClassLoader)
          Creates a "fast expression evaluator".
static java.lang.Object createFastExpressionEvaluator(Scanner scanner, java.lang.String className, java.lang.Class optionalExtendedType, java.lang.Class interfaceToImplement, java.lang.String[] parameterNames, java.lang.ClassLoader optionalParentClassLoader)
          Creates a "fast expression evaluator" from the given Scanner with no default imports.
static java.lang.Object createFastExpressionEvaluator(java.lang.String expression, java.lang.Class interfaceToImplement, java.lang.String[] parameterNames, java.lang.ClassLoader optionalParentClassLoader)
          Creates a "fast expression evaluator" from the given String expression, generating a class with the ClassBodyEvaluator.DEFAULT_CLASS_NAME that extends Object.
protected  java.lang.Class getDefaultReturnType()
           
protected  Java.Block makeBlock(int idx, Scanner scanner)
          Fill the given block by parsing statements until EOF and adding them to the block.
 void setExpressionType(java.lang.Class expressionType)
          Define the type of the expression.
 void setExpressionTypes(java.lang.Class[] expressionTypes)
           
 
Methods inherited from class org.codehaus.janino.ScriptEvaluator
compileToMethods, cook, cook, cook, cook, cook, createFastEvaluator, createFastEvaluator, createFastScriptEvaluator, createFastScriptEvaluator, createFastScriptEvaluator, createFastScriptEvaluator, evaluate, evaluate, getMethod, getMethod, makeMethodDeclaration, setMethodName, setMethodNames, setParameters, setParameters, setReturnType, setReturnTypes, setStaticMethod, setStaticMethod, setThrownExceptions, setThrownExceptions
 
Methods inherited from class org.codehaus.janino.ClassBodyEvaluator
addPackageMemberClassDeclaration, compileToClass, createFastClassBodyEvaluator, createFastClassBodyEvaluator, getClazz, makeCompilationUnit, setClassName, setDefaultImports, setExtendedType, setImplementedTypes
 
Methods inherited from class org.codehaus.janino.SimpleCompiler
classesToTypes, classToType, compileToClassLoader, equals, getClassLoader, hashCode, main, setParentClassLoader, setParentClassLoader, setUpClassLoaders
 
Methods inherited from class org.codehaus.janino.Cookable
cook, cook, cook, cook, cook, cook, cook, cookFile, cookFile, cookFile, cookFile
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ANY_TYPE

public static final java.lang.Class ANY_TYPE
Constructor Detail

ExpressionEvaluator

public ExpressionEvaluator(java.lang.String expression,
                           java.lang.Class expressionType,
                           java.lang.String[] parameterNames,
                           java.lang.Class[] parameterTypes)
                    throws CompileException,
                           Parser.ParseException,
                           Scanner.ScanException
Equivalent to
 ExpressionEvaluator ee = new ExpressionEvaluator();
 ee.setExpressionType(expressionType);
 ee.setParameters(parameterNames, parameterTypes);
 ee.cook(expression);

See Also:
ExpressionEvaluator(), setExpressionType(Class), ScriptEvaluator.setParameters(String[], Class[]), Cookable.cook(String)

ExpressionEvaluator

public ExpressionEvaluator(java.lang.String expression,
                           java.lang.Class expressionType,
                           java.lang.String[] parameterNames,
                           java.lang.Class[] parameterTypes,
                           java.lang.Class[] thrownExceptions,
                           java.lang.ClassLoader optionalParentClassLoader)
                    throws CompileException,
                           Parser.ParseException,
                           Scanner.ScanException
Equivalent to
 ExpressionEvaluator ee = new ExpressionEvaluator();
 ee.setExpressionType(expressionType);
 ee.setParameters(parameterNames, parameterTypes);
 ee.setThrownExceptions(thrownExceptions);
 ee.setParentClassLoader(optionalParentClassLoader);
 ee.cook(expression);

See Also:
ExpressionEvaluator(), setExpressionType(Class), ScriptEvaluator.setParameters(String[], Class[]), ScriptEvaluator.setThrownExceptions(Class[]), SimpleCompiler.setParentClassLoader(ClassLoader), Cookable.cook(String)

ExpressionEvaluator

public ExpressionEvaluator(java.lang.String expression,
                           java.lang.Class expressionType,
                           java.lang.String[] parameterNames,
                           java.lang.Class[] parameterTypes,
                           java.lang.Class[] thrownExceptions,
                           java.lang.Class optionalExtendedType,
                           java.lang.Class[] implementedTypes,
                           java.lang.ClassLoader optionalParentClassLoader)
                    throws CompileException,
                           Parser.ParseException,
                           Scanner.ScanException
Equivalent to
 ExpressionEvaluator ee = new ExpressionEvaluator();
 ee.setExpressionType(expressionType);
 ee.setParameters(parameterNames, parameterTypes);
 ee.setThrownExceptions(thrownExceptions);
 ee.setExtendedType(optionalExtendedType);
 ee.setImplementedTypes(implementedTypes);
 ee.setParentClassLoader(optionalParentClassLoader);
 ee.cook(expression);

See Also:
ExpressionEvaluator(), setExpressionType(Class), ScriptEvaluator.setParameters(String[], Class[]), ScriptEvaluator.setThrownExceptions(Class[]), ClassBodyEvaluator.setExtendedType(Class), ClassBodyEvaluator.setImplementedTypes(Class[]), SimpleCompiler.setParentClassLoader(ClassLoader), Cookable.cook(String)

ExpressionEvaluator

public ExpressionEvaluator(Scanner scanner,
                           java.lang.String className,
                           java.lang.Class optionalExtendedType,
                           java.lang.Class[] implementedTypes,
                           boolean staticMethod,
                           java.lang.Class expressionType,
                           java.lang.String methodName,
                           java.lang.String[] parameterNames,
                           java.lang.Class[] parameterTypes,
                           java.lang.Class[] thrownExceptions,
                           java.lang.ClassLoader optionalParentClassLoader)
                    throws Scanner.ScanException,
                           Parser.ParseException,
                           CompileException,
                           java.io.IOException
Equivalent to
 ExpressionEvaluator ee = new ExpressionEvaluator();
 ee.setClassName(className);
 ee.setExtendedType(optionalExtendedType);
 ee.setImplementedTypes(implementedTypes);
 ee.setStaticMethod(staticMethod);
 ee.setExpressionType(expressionType);
 ee.setMethodName(methodName);
 ee.setParameters(parameterNames, parameterTypes);
 ee.setThrownExceptions(thrownExceptions);
 ee.setParentClassLoader(optionalParentClassLoader);
 ee.cook(scanner);

See Also:
ExpressionEvaluator(), ClassBodyEvaluator.setClassName(String), ClassBodyEvaluator.setExtendedType(Class), ClassBodyEvaluator.setImplementedTypes(Class[]), ScriptEvaluator.setStaticMethod(boolean), setExpressionType(Class), ScriptEvaluator.setMethodName(String), ScriptEvaluator.setParameters(String[], Class[]), ScriptEvaluator.setThrownExceptions(Class[]), SimpleCompiler.setParentClassLoader(ClassLoader), Cookable.cook(Scanner)

ExpressionEvaluator

public ExpressionEvaluator()
Method Detail

setExpressionType

public void setExpressionType(java.lang.Class expressionType)
Define the type of the expression. The special type ANY_TYPE allows the expression to return any type (primitive or reference).

Defaults to ANY_TYPE.


setExpressionTypes

public void setExpressionTypes(java.lang.Class[] expressionTypes)

getDefaultReturnType

protected java.lang.Class getDefaultReturnType()
Overrides:
getDefaultReturnType in class ScriptEvaluator

makeBlock

protected Java.Block makeBlock(int idx,
                               Scanner scanner)
                        throws Parser.ParseException,
                               Scanner.ScanException,
                               java.io.IOException
Description copied from class: ScriptEvaluator
Fill the given block by parsing statements until EOF and adding them to the block.

Overrides:
makeBlock in class ScriptEvaluator
Throws:
Parser.ParseException
Scanner.ScanException
java.io.IOException

createFastExpressionEvaluator

public static java.lang.Object createFastExpressionEvaluator(java.lang.String expression,
                                                             java.lang.Class interfaceToImplement,
                                                             java.lang.String[] parameterNames,
                                                             java.lang.ClassLoader optionalParentClassLoader)
                                                      throws CompileException,
                                                             Parser.ParseException,
                                                             Scanner.ScanException
Creates a "fast expression evaluator" from the given String expression, generating a class with the ClassBodyEvaluator.DEFAULT_CLASS_NAME that extends Object.

See the class description for an explanation of the "fast expression evaluator" concept.

Throws:
CompileException
Parser.ParseException
Scanner.ScanException
See Also:
createFastExpressionEvaluator(Scanner, String[], String, Class, Class, String[], ClassLoader), ExpressionEvaluator

createFastExpressionEvaluator

public static java.lang.Object createFastExpressionEvaluator(Scanner scanner,
                                                             java.lang.String className,
                                                             java.lang.Class optionalExtendedType,
                                                             java.lang.Class interfaceToImplement,
                                                             java.lang.String[] parameterNames,
                                                             java.lang.ClassLoader optionalParentClassLoader)
                                                      throws CompileException,
                                                             Parser.ParseException,
                                                             Scanner.ScanException,
                                                             java.io.IOException
Creates a "fast expression evaluator" from the given Scanner with no default imports.

See the class description for an explanation of the "fast expression evaluator" concept.

Throws:
CompileException
Parser.ParseException
Scanner.ScanException
java.io.IOException
See Also:
createFastExpressionEvaluator(Scanner, String[], String, Class, Class, String[], ClassLoader), ExpressionEvaluator

createFastExpressionEvaluator

public static java.lang.Object createFastExpressionEvaluator(Scanner scanner,
                                                             java.lang.String[] optionalDefaultImports,
                                                             java.lang.String className,
                                                             java.lang.Class optionalExtendedType,
                                                             java.lang.Class interfaceToImplement,
                                                             java.lang.String[] parameterNames,
                                                             java.lang.ClassLoader optionalParentClassLoader)
                                                      throws CompileException,
                                                             Parser.ParseException,
                                                             Scanner.ScanException,
                                                             java.io.IOException
Creates a "fast expression evaluator".

See the class description for an explanation of the "fast expression evaluator" concept.

Notice: The interfaceToImplement must either be declared public, or with package scope in the same package as className.

Parameters:
scanner - Source of expression tokens
optionalDefaultImports - Default imports, e.g. { "java.util.Map", "java.io.*" }
className - Name of generated class
optionalExtendedType - Class to extend
interfaceToImplement - Must declare exactly the one method that defines the expression's signature
parameterNames - The expression references the parameters through these names
optionalParentClassLoader - Used to load referenced classes, defaults to the current thread's "context class loader"
Returns:
an object that implements the given interface and extends the optionalExtendedType
Throws:
CompileException
Parser.ParseException
Scanner.ScanException
java.io.IOException
See Also:
ExpressionEvaluator

Web Site