Package org.codehaus.commons.compiler

# Interface IScriptEvaluator

All Superinterfaces:
  `ICookable`, `IMultiCookable`

All Known Implementing Classes:
  `ScriptEvaluator`, `ScriptEvaluator`

public interface IScriptEvaluator extends ICookable, IMultiCookable
An engine that executes a script in JVM bytecode.

The syntax of the script to compile is a sequence of import declarations (not allowed if you compile many scripts at a time, see below) followed by a sequence of statements, as defined in the Java Language Specification, Java SE 7 Edition, sections 7.5 and 14.

An implementation may or may not implement the concept of "local methods", i.e. method declarations being freely intermixed with statements.

Example:

       import java.text.*;

       System.out.println("HELLO");
       System.out.println(new DecimalFormat("####,###.##").format(a));

(Notice that this expression refers to a parameter "a", as explained below.)

The script may complete abnormally, e.g. through a RETURN statement:

       if (a == null) {
           System.out.println("Oops!");
           return;
       }

Optionally, the script may be declared with a non-void return type. In this case, the last statement of the script must be a RETURN statement (or a THROW statement), and all RETURN statements in the script must return a value with the given type.

The script evaluator is implemented by creating and compiling a temporary compilation unit defining one class with one method the body of which consists of the statements of the script.

To set up a `IScriptEvaluator` object, proceed as follows:

1. Create an `IScriptEvaluator`-implementing class.
2. Configure the `IScriptEvaluator` by calling any of the following methods:
   - `setReturnType(Class)`
   - `setParameters(String[], Class[])`
   - `setThrownExceptions(Class[])`
   - `ISimpleCompiler.setParentClassLoader(ClassLoader)`
   - `IClassBodyEvaluator.setDefaultImports(String[])`
3. Call any of the `Cookable.cook(Reader)` methods to scan, parse, compile and load the script into the JVM.

After the `IScriptEvaluator` object is created, the script can be executed as often with different parameter values (see `evaluate(Object[])`). This execution 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 script, the exceptions that this method (i.e. the script) is allowed to throw, and the `ClassLoader` that is used to define the generated class and to load classes referenced by the script.

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

- `setMethodNames(String[])`
- `setParameters(String[][], Class[][])`
- `setReturnTypes(Class[])`
- `setStaticMethod(boolean[])`
- `setThrownExceptions(Class[][])`
- `ICookable.cook(Reader)`
- `evaluate(int, Object[])`

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

## Field Summary

Fields
Modifier and Type
Field
Description
`static final String`
`DEFAULT_METHOD_NAME`
The name of the generated method(s), if no custom method name is configured with `setMethodNames(String[])`.
`static final Class<?>`
`DEFAULT_RETURN_TYPE`
The return type for any script for which no return type is explicitly configured.

## Method Summary

Modifier and Type
Method
Description
`void`
`cook(Reader... readers)`
Same as `ICookable.cook(Reader)`, but for multiple scripts.
`void`
`cook(String[] strings)`
Same as `ICookable.cook(String)`, but for multiple scripts.
`void`
`cook(String[] fileNames, Reader[] readers)`
Same as `ICookable.cook(String, Reader)`, but cooks a set of scripts into one class.
`void`
`cook(String[] fileNames, String[] strings)`
Same as `ICookable.cook(String, String)`, but for multiple scripts.
`<T> T`
`createFastEvaluator(Reader reader, Class<T> interfaceToImplement, String[] parameterNames)`
If the parameter and return types of the expression are known at compile time, then a "fast" script evaluator can be instantiated through this method.
`<T> T`
`createFastEvaluator(String script, Class<T> interfaceToImplement, String[] parameterNames)`
`Object`
`evaluate()`
Shorthand for `evaluate``(new Object[0])`.
`Object`
`evaluate(int idx, Object[] arguments)`
Same as `evaluate(Object[])`, but for multiple scripts.
`Object`
`evaluate(Object[] arguments)`
Calls the script with concrete parameter values.
`Class<?>`
`getClazz()`
`String[]`
`getDefaultImports()`
`Class<?>`
`getDefaultReturnType()`
`Method`
`getMethod()`
`Method`
`getMethod(int idx)`
Same as `getMethod()`, but for multiple scripts.
`Method[]`
`getResult()`
`void`
`setClassName(String className)`
`void`
`setCompileErrorHandler(ErrorHandler compileErrorHandler)`
Installs an `ErrorHandler` which is invoked during compilation on each error.
`void`
`setDebuggingInformation(boolean debugSource, boolean debugLines, boolean debugVars)`
Determines what kind of debugging information is included in the generates classes.
`void`
`setDefaultImports(String... defaultImports)`
`void`
`setDefaultReturnType(Class<?> defaultReturnType)`
When this `IScriptEvaluator` is coooked, then the defaultReturnType applies to all scripts for which no explicit return type was configured.
`void`
`setExtendedClass(Class<?> extendedClass)`
`void`
`setImplementedInterfaces(Class<?>[] implementedInterfaces)`
`void`
`setMethodName(String methodName)`
Defines the name of the generated method.
`void`
`setMethodNames(String[] methodNames)`
Same as `setMethodName(String)`, but for multiple scripts.
`void`
`setOverrideMethod(boolean overrideMethod)`
Defines whether the generated method overrides a methods declared in a supertype.
`void`
`setOverrideMethod(boolean[] overrideMethod)`
Same as `setOverrideMethod(boolean)`, but for multiple scripts.
`void`
`setParameters(String[][] names, Class<?>[][] types)`
Same as `setParameters(String[], Class[])`, but for multiple scripts.
`void`
`setParameters(String[] names, Class<?>[] types)`
Defines the names and types of the parameters of the generated method.
`void`
`setParentClassLoader(ClassLoader parentClassLoader)`
The "parent class loader" is used to load referenced classes.
`void`
`setReturnType(Class<?> returnType)`
Defines the return type of the generated method.
`void`
`setReturnTypes(Class<?>[] returnTypes)`
Configures the return types of the generated methods.
`void`
`setStaticMethod(boolean staticMethod)`
Defines whether the generated method should be STATIC or not.
`void`
`setStaticMethod(boolean[] staticMethod)`
Same as `setStaticMethod(boolean)`, but for multiple scripts.
`void`
`setThrownExceptions(Class<?>[] thrownExceptions)`
Defines the exceptions that the generated method may throw.
`void`
`setThrownExceptions(Class<?>[][] thrownExceptions)`
Same as `setThrownExceptions(Class[])`, but for multiple scripts.
`void`
`setWarningHandler(WarningHandler warningHandler)`
By default, warnings are discarded, but an application my install a custom `WarningHandler`.

### Methods inherited from interface org.codehaus.commons.compiler.ICookable

`cook, cook, cook, cook, cook, cook, cook, cook, cookFile, cookFile, cookFile, cookFile, getBytecodes, setSourceVersion, setTargetVersion`

### Methods inherited from interface org.codehaus.commons.compiler.IMultiCookable

`cook, cook, cook, cook, cookFiles, cookFiles, cookFiles, cookFiles`

## Field Details

### DEFAULT_METHOD_NAME

static final String DEFAULT_METHOD_NAME
The name of the generated method(s), if no custom method name is configured with `setMethodNames(String[])`.

The `'*'` in this string is replaced with the method index, starting at 0.

See Also:
  - Constant Field Values

### DEFAULT_RETURN_TYPE

static final Class<?> DEFAULT_RETURN_TYPE
The return type for any script for which no return type is explicitly configured.

## Method Details

### setParentClassLoader

void setParentClassLoader(@Nullable 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.

### setDebuggingInformation

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`".

### setCompileErrorHandler

void setCompileErrorHandler(@Nullable 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` - `null` to restore the default behavior (throwing a `CompileException`)

### setWarningHandler

void setWarningHandler(@Nullable WarningHandler warningHandler)
By default, warnings are discarded, but an application my install a custom `WarningHandler`.

Parameters:
  `warningHandler` - `null` to indicate that no warnings be issued

### setClassName

void setClassName(String className)

See Also:
  - `IClassBodyEvaluator.setClassName(String)`

### setImplementedInterfaces

void setImplementedInterfaces(Class<?>[] implementedInterfaces)

See Also:
  - `IClassBodyEvaluator.setImplementedInterfaces(Class[])`

### setExtendedClass

void setExtendedClass(Class<?> extendedClass)

See Also:
  - `IClassBodyEvaluator.setExtendedClass(Class)`

### setDefaultReturnType

void setDefaultReturnType(Class<?> defaultReturnType)
When this `IScriptEvaluator` is coooked, then the defaultReturnType applies to all scripts for which no explicit return type was configured.

The initial default return type (if you want, the "default-default" return type) is `void.class`.

See Also:
  - `setReturnType(Class)`
  - `setReturnTypes(Class[])`

### getDefaultReturnType

Class<?> getDefaultReturnType()

Returns:
  The default return type that was previously configured with `setDefaultReturnType(Class)`, or `DEFAULT_RETURN_TYPE`

### setOverrideMethod

void setOverrideMethod(boolean overrideMethod)
Defines whether the generated method overrides a methods declared in a supertype.

### setStaticMethod

void setStaticMethod(boolean staticMethod)
Defines whether the generated method should be STATIC or not. Defaults to `true`.

### setReturnType

void setReturnType(Class<?> returnType)
Defines the return type of the generated method. Value `null` means "use the default return type".

See Also:
  - `setDefaultReturnType(Class)`

### setMethodName

void setMethodName(@Nullable String methodName)
Defines the name of the generated method. Initially, the method name is "eval*".

Parameters:
  `methodName` - `null` means reset to default name
See Also:
  - `DEFAULT_METHOD_NAME`

### setParameters

void setParameters(String[] names, Class<?>[] types)
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 script is cooked.

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

The default is to have zero parameters.

### setThrownExceptions

void setThrownExceptions(Class<?>[] thrownExceptions)
Defines the exceptions that the generated method may throw.

### evaluate

@Nullable Object evaluate() throws InvocationTargetException
Shorthand for `evaluate``(new Object[0])`.

Throws:
  `InvocationTargetException`

### evaluate

@Nullable Object evaluate(@Nullable Object[] arguments) throws InvocationTargetException
Calls the script with concrete parameter values.

Each argument 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 `setReturnType(Class)`.

This method is thread-safe.

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` - The actual parameter values
Throws:
  `IllegalStateException` - This IScriptEvaluator is not yet cooked
  `InvocationTargetException`

### getMethod

Method getMethod()

Returns:
  The generated and loaded `Method`
Throws:
  `IllegalStateException` - This IScriptEvaluator is not yet cooked

### setOverrideMethod

void setOverrideMethod(boolean[] overrideMethod)
Same as `setOverrideMethod(boolean)`, but for multiple scripts.

### setStaticMethod

void setStaticMethod(boolean[] staticMethod)
Same as `setStaticMethod(boolean)`, but for multiple scripts.

### setReturnTypes

void setReturnTypes(Class<?>[] returnTypes)
Configures the return types of the generated methods. If an element of the array is `null`, then use the "default return type" for that script.

Parameters:
  `returnTypes` - The methods' return types; `null` elements mean "use the default return type"
See Also:
  - `setDefaultReturnType(Class)`
  - `getDefaultReturnType()`

### setMethodNames

void setMethodNames(String[] methodNames)
Same as `setMethodName(String)`, but for multiple scripts.

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

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

### setParameters

void setParameters(String[][] names, Class<?>[][] types)
Same as `setParameters(String[], Class[])`, but for multiple scripts.

### setThrownExceptions

void setThrownExceptions(Class<?>[][] thrownExceptions)
Same as `setThrownExceptions(Class[])`, but for multiple scripts.

### cook

void cook(Reader... readers) throws CompileException, IOException
Same as `ICookable.cook(Reader)`, but for multiple scripts.

Specified by:
  `cook` in interface `IMultiCookable`
Throws:
  `CompileException`
  `IOException`

### cook

void cook(String[] fileNames, Reader[] readers) throws CompileException, IOException
Same as `ICookable.cook(String, Reader)`, but cooks a set of scripts into one class. Notice that if any of the scripts causes trouble, the entire compilation will fail. If you need to report which of the scripts causes the exception, you may want to use the `fileNames` parameter to distinguish between the individual token sources.

Iff the number of scanners is one, then that single script may contain leading IMPORT directives.

s

Specified by:
  `cook` in interface `IMultiCookable`
Throws:
  `IllegalStateException` - if any of the preceding `set...()` had an array size different from that of `scanners`
  `CompileException`
  `IOException`

### cook

void cook(String[] strings) throws CompileException
Same as `ICookable.cook(String)`, but for multiple scripts.

Specified by:
  `cook` in interface `IMultiCookable`
Throws:
  `CompileException`

### cook

void cook(String[] fileNames, String[] strings) throws CompileException
Same as `ICookable.cook(String, String)`, but for multiple scripts.

Specified by:
  `cook` in interface `IMultiCookable`
Throws:
  `CompileException`

### evaluate

@Nullable Object evaluate(int idx, @Nullable Object[] arguments) throws InvocationTargetException
Same as `evaluate(Object[])`, but for multiple scripts.

Throws:
  `InvocationTargetException`

### getMethod

Method getMethod(int idx)
Same as `getMethod()`, but for multiple scripts.

### createFastEvaluator

<T> T createFastEvaluator(String script, Class<T> interfaceToImplement, String[] parameterNames) throws CompileException

Parameters:
  `script` - Contains the sequence of script tokens
Throws:
  `CompileException`
See Also:
  - `createFastEvaluator(Reader, Class, String[])`

### createFastEvaluator

<T> T createFastEvaluator(Reader reader, Class<T> interfaceToImplement, String[] parameterNames) throws CompileException, IOException
If the parameter and return types of the expression are known at compile time, then a "fast" script evaluator can be instantiated through this method.

Script 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);
     }
     ...
     IScriptEvaluator se = CompilerFactoryFactory.getDefaultCompilerFactory().newScriptEvaluator();

     // Optionally configure the SE her:
     se.setClassName("Bar");
     se.setDefaultImports(new String[] { "java.util.*" });
     se.setExtendedClass(SomeOtherClass.class);
     se.setParentClassLoader(someClassLoader);

     Foo f = (Foo) se.createFastScriptEvaluator(
         "return a - b;",
         Foo.class,
         new String[] { "a", "b" }
     );
     System.out.println("1 - 2 = " + f.bar(1, 2));

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 either be declared `public`, or with package scope in the same package as the generated class (see `setClassName(String)`).

s

Parameters:
  `reader` - Produces the stream of script tokens
  `interfaceToImplement` - Must declare exactly one method
  `parameterNames` - The names of the parameters of that method
Returns:
  An object that implements the given interface
Throws:
  `CompileException`
  `IOException`

### setDefaultImports

void setDefaultImports(String... defaultImports)

See Also:
  - `IClassBodyEvaluator.setDefaultImports(String...)`

### getDefaultImports

String[] getDefaultImports()

See Also:
  - `IClassBodyEvaluator.getDefaultImports()`

### getClazz

Class<?> getClazz()

See Also:
  - `IClassBodyEvaluator.getClazz()`

### getResult

Method[] getResult()

Returns:
  The generated and loaded methods that implement the cooked scripts
Throws:
  `IllegalStateException` - This `IScriptEvaluator` is not yet cooked