Top Description Fields Methods
org.codehaus.commons.compiler

public Interface IExpressionEvaluator

extends ICookable, IMultiCookable
Imports
java.io.IOException, .Reader, java.lang.reflect.InvocationTargetException, .Method, org.codehaus.commons.compiler.lang.ClassLoaders, org.codehaus.commons.nullanalysis.Nullable

An engine that evaluates expressions in JVM bytecode.

The syntax of the expression to compile is that of a Java expression, as defined in JLS7, section 15. Notice that a Java 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).

To set up an IExpressionEvaluator object, proceed as follows:

  1. Create an IExpressionEvaluator-derived class
  2. Configure the IExpressionEvaluator by calling any of the following methods:
  3. Call any of the cook(String, java.io.Reader) methods to scan, parse, compile and load the expression into the JVM.

After the IExpressionEvaluator object is set up, the expression can be evaluated as often with different parameter values (see 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.

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

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

Notice that for functionally identical IExpressionEvaluators, java.lang.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".

'JLS7' refers to the Java Language Specification, Java SE 7 Edition.

Field Summary

Modifier and TypeField and Description
public static final Class<?>
ANY_TYPE

Special value for setExpressionType(Class) that indicates that the expression may have any type.

public static final String
DEFAULT_CLASS_NAME

The fully qualified name of the generated class, iff not reconfigured by setClassName(String).

public static final Class<?>
DEFAULT_EXPRESSION_TYPE

The type of all expressions that were not reconfigured with setExpressionTypes(Class[]).

Method Summary

Modifier and TypeMethod and Description
public <T> T
createFastEvaluator(String expression, Class<? extends T> interfaceToImplement, String... parameterNames)

If the parameter and return types of the expression are known at compile time, then a "fast" expression evaluator can be instantiated through createFastEvaluator(String, Class, String[]).

public <T> T
createFastEvaluator(Reader reader, Class<? extends T> interfaceToImplement, String... parameterNames)

public Object
evaluate()

Shorthand for evaluate(new Object[0]).

public Object
evaluate(Object[]
The actual parameter values
arguments
)

Evaluates the expression with concrete parameter values.

public Object
evaluate(int idx, Object[] arguments)

Same as evaluate(Object[]), but for multiple expressions.

public Class<?>

Returns:

The generated Class
getClazz
()

public Class<?>

Returns:

The currently configured "default expression type"
getDefaultExpressionType
()

public String[]

Returns:

The default imports that were previously configured with setDefaultImports(String...)
getDefaultImports
()

public Method

Returns:

The generated and loaded java.lang.reflect.Method
getMethod
()

public Method
getMethod(int idx)

Same as getMethod(), but for multiple expressions.

public Method[]

Returns:

The generated and loaded methods that implement the cooked expressions
getResult
()

public void
setClassName(String className)

Sets the name of the generated class.

public void
setCompileErrorHandler(ErrorHandler
null to restore the default behavior (throwing a CompileException)
compileErrorHandler
)

Installs an ErrorHandler which is invoked during compilation on each error.

public void
setDebuggingInformation(boolean debugSource, boolean debugLines, boolean debugVars)

Determines what kind of debugging information is included in the generates classes.

public void
setDefaultExpressionType(Class<?> defaultExpressionType)

Reconfigures the "default expression type"; if no expression type is configured for an expression, then, when cooking this IExpressionEvaluator, the "default expression type" is used for the expression

public void
setDefaultImports(String... defaultImports)

"Default imports" add to the system import "java.lang", i.e. the evaluator may refer to classes imported by default imports without having to explicitly declare IMPORT statements.

public void
setExpressionType(Class<?> expressionType)

Defines the type of the expression.

public void
setExpressionTypes(Class<?>[] expressionTypes)

Configures the types of the expressions.

public void
setExtendedClass(Class<?> extendedType)

Sets a particular superclass that the generated class will extend.

public void
setImplementedInterfaces(Class<?>[] implementedTypes)

Configures the interfaces that the generated class implements.

public void
setMethodName(String
null means reset to default name
methodName
)

Defines the name of the generated method.

public void
setMethodNames(String[] methodNames)

Same as setMethodName(String), but for multiple expressions.

public void
setOverrideMethod(boolean overrideMethod)

Defines whether the generated method overrides a methods declared in a supertype.

public void
setOverrideMethod(boolean[] overrideMethod)

Same as setOverrideMethod(boolean), but for multiple expressions.

public void
setParameters(String[] parameterNames, Class<?>[] parameterTypes)

Defines the names and types of the parameters of the generated method.

public void
setParameters(String[][] parameterNames, Class<?>[][] parameterTypes)

Same as setParameters(String[], Class[]), but for multiple expressions.

public void
setParentClassLoader(ClassLoader parentClassLoader)

The "parent class loader" is used to load referenced classes.

public void
setReturnType(Class<?> returnType)

Deprecated Use setExpressionType(Class) instead
public void
setStaticMethod(boolean staticMethod)

Defines whether the generated method should be STATIC or not.

public void
setStaticMethod(boolean[] staticMethod)

Same as setStaticMethod(boolean), but for multiple expressions.

public void
setThrownExceptions(Class<?>[] thrownExceptions)

Defines the exceptions that the generated method may throw.

public void
setThrownExceptions(Class<?>[][] thrownExceptions)

Same as setThrownExceptions(Class[]), but for multiple expressions.

public void
setWarningHandler(WarningHandler
null to indicate that no warnings be issued
warningHandler
)

By default, warnings are discarded, but an application my install a custom WarningHandler.

Inherited from org.codehaus.commons.compiler.ICookable:
cookcookcookcookcookcookcookcookcookFilecookFilecookFilecookFilegetBytecodessetSourceVersionsetTargetVersion
Inherited from org.codehaus.commons.compiler.IMultiCookable:
cookcookcookcookcookcookcookcookcookFilescookFilescookFilescookFiles

Field Detail

ANY_TYPEback to summary
public static final Class<?> ANY_TYPE

Deprecated

Since autoboxing was introduced in JANINO, this feature is no longer necessary because you can use expression type Object.class

Special value for setExpressionType(Class) that indicates that the expression may have any type.

Annotations
@Deprecated
DEFAULT_CLASS_NAMEback to summary
public static final String DEFAULT_CLASS_NAME

The fully qualified name of the generated class, iff not reconfigured by setClassName(String).

DEFAULT_EXPRESSION_TYPEback to summary
public static final Class<?> DEFAULT_EXPRESSION_TYPE

The type of all expressions that were not reconfigured with setExpressionTypes(Class[]).

Method Detail

createFastEvaluatorback to summary
public <T> T createFastEvaluator(String expression, Class<? extends T> interfaceToImplement, String... parameterNames) throws CompileException

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

Example:

public interface Foo {
    int bar(int a, int b);
}
...
ExpressionEvaluator ee = CompilerFactoryFactory.getDefaultCompilerFactory().newExpressionEvaluator();

// Optionally configure the EE here...
ee.setClassName("Bar");
ee.setDefaultImports(new String[] { "java.util.*" });
ee.setExtendedClass(SomeOtherClass.class);
ee.setParentClassLoader(someClassLoader);

// Optionally configure the EE here...
Foo f = (Foo) ee.createFastEvaluator(
    "a + b",                    // expression to evaluate
    Foo.class,                  // interface that describes the expression's signature
    new String[] { "a", "b" }   // the parameters' names
);
System.out.println("1 + 2 = " + f.bar(1, 2)); // Evaluate the expression

All other configuration (implemented type, static method, return type, method name, parameter names and types, thrown exceptions) are predetermined by the interfaceToImplement.

Notice: The interfaceToImplement must be accessible by the compiled class, i.e. either be declared public, or with protected or default access in the package of the compiled class (see setClassName(String).

createFastEvaluatorback to summary
public <T> T createFastEvaluator(Reader reader, Class<? extends T> interfaceToImplement, String... parameterNames) throws CompileException, IOException
See Also
createFastEvaluator(String, Class, String[])
evaluateback to summary
public Object evaluate() throws InvocationTargetException

Shorthand for evaluate(new Object[0]).

Annotations
@Nullable
evaluateback to summary
public Object evaluate(Object[] arguments) throws InvocationTargetException

Evaluates the expression with concrete parameter values.

Each argument value must have the same type as specified through the "parameterTypes" parameter of setParameters(String[], Class[]).

Arguments of primitive type must passed with their wrapper class objects.

The object returned has the class as specified through setExpressionType(Class).

This method is thread-safe.

Null arguments is equivalent with new Object[0].

Notice: In version 3.1.8, the arguments parameter was changed from Object[] to Object..., which turned out to be a really bad decision because it caused a very ugly invocation ambiguity with evaluate(int, Object[]). Thus, with version 3.1.10, the parameter was changed back to Object[].

Parameters
arguments:Object[]

The actual parameter values

Annotations
@Nullable
evaluateback to summary
public Object evaluate(int idx, Object[] arguments) throws InvocationTargetException

Same as evaluate(Object[]), but for multiple expressions.

Notice: In version 3.1.8, the arguments parameter was changed from Object[] to Object..., which turned out to be a really bad decision because it caused a very ugly invocation ambiguity with evaluate(int, Object[]). Thus, with version 3.1.10, the parameter was changed back to Object[].

Annotations
@Nullable
getClazzback to summary
public Class<?> getClazz()
Returns:Class<?>

The generated Class

Exceptions
IllegalStateException:
This IClassBodyEvaluator is not yet cooked
getDefaultExpressionTypeback to summary
public Class<?> getDefaultExpressionType()
Returns:Class<?>

The currently configured "default expression type"

See Also
setDefaultExpressionType(Class)
getDefaultImportsback to summary
public String[] getDefaultImports()
Returns:String[]

The default imports that were previously configured with setDefaultImports(String...)

getMethodback to summary
public Method getMethod()
Returns:Method

The generated and loaded java.lang.reflect.Method

Exceptions
IllegalStateException:
This IExpressionEvaluator is not yet cooked
getMethodback to summary
public Method getMethod(int idx)

Same as getMethod(), but for multiple expressions.

getResultback to summary
public Method[] getResult()
Returns:Method[]

The generated and loaded methods that implement the cooked expressions

Exceptions
IllegalStateException:
This IScriptEvaluator is not yet cooked
setClassNameback to summary
public void setClassName(String className)

Sets the name of the generated class. Defaults to DEFAULT_CLASS_NAME. In most cases, there is no need to set this name, because the generated class is loaded into its own java.lang.ClassLoader where its name cannot collide with classes generated by other evaluators.

One reason to use this function is to have a class name in a non-default package, which can be relevant when types and members with DEFAULT accessibility are accessed.

setCompileErrorHandlerback to summary
public void setCompileErrorHandler(ErrorHandler compileErrorHandler)

Installs an ErrorHandler which is invoked during compilation on each error. (By default, the compilation throws a CompileException on the first error and terminates.)

If the given ErrorHandler throws a CompileException, then the compilation terminates and the exception is propagated.

If the given ErrorHandler does not throw a CompileException but completes normally, then the compilation may or may not continue, depending on the error. Iff the compilation completes normally but errors were reported, then it will throw a CompileException indicating the number of errors.

In other words: The ErrorHandler may throw a CompileException or not, but the compilation will definitely throw a CompileException if one or more compile errors have occurred.

Parameters
compileErrorHandler:ErrorHandler

null to restore the default behavior (throwing a CompileException)

setDebuggingInformationback to summary
public void setDebuggingInformation(boolean debugSource, boolean debugLines, boolean debugVars)

Determines what kind of debugging information is included in the generates classes. The default is typically "-g:none".

setDefaultExpressionTypeback to summary
public void setDefaultExpressionType(Class<?> defaultExpressionType)

Reconfigures the "default expression type"; if no expression type is configured for an expression, then, when cooking this IExpressionEvaluator, the "default expression type" is used for the expression

setDefaultImportsback to summary
public void setDefaultImports(String... defaultImports)

"Default imports" add to the system import "java.lang", i.e. the evaluator may refer to classes imported by default imports without having to explicitly declare IMPORT statements.

Notice that JDK 5 "static imports" are also supported, as shown here:

    sc.setDefaultImports(
        "java.util.Map",                          // Single type import
        "java.io.*",                              // Type-import-on-demand
        "static java.util.Collections.EMPTY_MAP", // Single static import
        "static java.util.Collections.*",         // Static-import-on-demand
    );
setExpressionTypeback to summary
public void setExpressionType(Class<?> expressionType)

Defines the type of the expression.

Defaults to Object.class, which, thanks to autoboxing, allows for any expression type (including primitive types).

If expressionType is void.class, then the expression must be an invocation of a void method.

setExpressionTypesback to summary
public void setExpressionTypes(Class<?>[] expressionTypes)

Configures the types of the expressions.

Unless this method is called, all expressions have type Object.class.

If any expression has type void.class, then it must be an invocation of a void method.

setExtendedClassback to summary
public void setExtendedClass(Class<?> extendedType)

Sets a particular superclass that the generated class will extend. If extendedClass is null, the generated class will extend Object.

The usual reason to set a base class for an evaluator is that the generated class can directly access the superclass's (non-private) members.

setImplementedInterfacesback to summary
public void setImplementedInterfaces(Class<?>[] implementedTypes)

Configures the interfaces that the generated class implements.

setMethodNameback to summary
public void setMethodName(String methodName)

Defines the name of the generated method. Initially, the method name is eval*.

Parameters
methodName:String

null means reset to default name

See Also
IScriptEvaluator#DEFAULT_METHOD_NAME
setMethodNamesback to summary
public void setMethodNames(String[] methodNames)

Same as setMethodName(String), but for multiple expressions.

Define the names of the generated methods. By default the methods have distinct and implementation-specific names.

If two expressions have the same name, then they must have different parameter types (see setParameters(String[][], Class[][])).

setOverrideMethodback to summary
public void setOverrideMethod(boolean overrideMethod)

Defines whether the generated method overrides a methods declared in a supertype.

setOverrideMethodback to summary
public void setOverrideMethod(boolean[] overrideMethod)

Same as setOverrideMethod(boolean), but for multiple expressions.

setParametersback to summary
public void setParameters(String[] parameterNames, Class<?>[] parameterTypes)

Defines the names and types of the parameters of the generated method.

names.length and types.length must be equal. This invariant may be checked immediately, or later when the expression is cooked.

The parameters can be of primitive type, e.g. double.class.

The default is to have zero parameters.

setParametersback to summary
public void setParameters(String[][] parameterNames, Class<?>[][] parameterTypes)

Same as setParameters(String[], Class[]), but for multiple expressions.

setParentClassLoaderback to summary
public void setParentClassLoader(ClassLoader parentClassLoader)

The "parent class loader" is used to load referenced classes. Useful values are:

System.getSystemClassLoader() The running JVM's class path
Thread.currentThread().getContextClassLoader() or null The class loader effective for the invoking thread
ClassLoaders#BOOTCLASSPATH_CLASS_LOADER The running JVM's boot class path

The parent class loader defaults to the current thread's context class loader.

setReturnTypeback to summary
public void setReturnType(Class<?> returnType)

Deprecated

Use setExpressionType(Class) instead

Annotations
@Deprecated
setStaticMethodback to summary
public void setStaticMethod(boolean staticMethod)

Defines whether the generated method should be STATIC or not. Defaults to true.

setStaticMethodback to summary
public void setStaticMethod(boolean[] staticMethod)

Same as setStaticMethod(boolean), but for multiple expressions.

setThrownExceptionsback to summary
public void setThrownExceptions(Class<?>[] thrownExceptions)

Defines the exceptions that the generated method may throw.

setThrownExceptionsback to summary
public void setThrownExceptions(Class<?>[][] thrownExceptions)

Same as setThrownExceptions(Class[]), but for multiple expressions.

setWarningHandlerback to summary
public void setWarningHandler(WarningHandler warningHandler)

By default, warnings are discarded, but an application my install a custom WarningHandler.

Parameters
warningHandler:WarningHandler

null to indicate that no warnings be issued