| java.lang.Object org.codehaus.janino.Cookable org.codehaus.janino.SimpleCompiler org.codehaus.janino.ClassBodyEvaluator org.codehaus.janino.ScriptEvaluator
All known Subclasses: org.codehaus.janino.ExpressionEvaluator,
ScriptEvaluator | public class ScriptEvaluator extends ClassBodyEvaluator (Code) | | An engine that executes a script in JavaTM 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, 2nd
edition, sections
7.5
and
14.
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
ScriptEvaluator object, proceed as follows:
-
Create the
ScriptEvaluator using
ScriptEvaluator.ScriptEvaluator()
-
Configure the
ScriptEvaluator by calling any of the following methods:
-
Call any of the
org.codehaus.janino.Cookable.cook(Scanner) methods to scan,
parse, compile and load the script into the JVM.
After the
ScriptEvaluator object is created, the script can be executed as often with
different parameter values (see
ScriptEvaluator.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.
Alternatively, a number of "convenience constructors" exist that execute the steps described
above instantly. Their use is discouraged.
If you want to compile many scripts at the same time, you have the option to cook an
array of scripts in one
ScriptEvaluator by using the following methods:
Notice that these methods have array parameters in contrast to their one-script brethren.
|
Constructor Summary | |
public | ScriptEvaluator(String script) | public | ScriptEvaluator(String script, Class returnType) | public | ScriptEvaluator(String script, Class returnType, String[] parameterNames, Class[] parameterTypes) | public | ScriptEvaluator(String script, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions) | public | ScriptEvaluator(String optionalFileName, InputStream is, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) | public | ScriptEvaluator(String optionalFileName, Reader reader, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) | public | ScriptEvaluator(Scanner scanner, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) | public | ScriptEvaluator(Scanner scanner, Class optionalExtendedType, Class[] implementedTypes, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) | public | ScriptEvaluator(Scanner scanner, String className, Class optionalExtendedType, Class[] implementedTypes, boolean staticMethod, Class returnType, String methodName, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) | public | ScriptEvaluator() |
Method Summary | |
protected void | compileToMethods(Java.CompilationUnit compilationUnit, String[] methodNames, Class[][] parameterTypes) | final public void | cook(Scanner scanner) | final public void | cook(Scanner[] scanners) Like
ScriptEvaluator.cook(Scanner) , but cooks a set of scripts into one class. | final public void | cook(Reader[] readers) | final public void | cook(String[] optionalFileNames, Reader[] readers) | final public void | cook(String[] strings) Cook tokens from
java.lang.String s. | public static Object | createFastEvaluator(ScriptEvaluator se, String s, String[] parameterNames, Class interfaceToImplement) | public static Object | createFastEvaluator(ScriptEvaluator se, Scanner scanner, String[] parameterNames, Class interfaceToImplement) Create and return an object that implements the exactly one method of the given
interfaceToImplement . | public static Object | createFastScriptEvaluator(String script, Class interfaceToImplement, String[] parameterNames) Simplified version of
ScriptEvaluator.createFastScriptEvaluator(Scanner,Class,String[],ClassLoader) . | public static Object | createFastScriptEvaluator(Scanner scanner, Class interfaceToImplement, String[] parameterNames, ClassLoader optionalParentClassLoader) 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
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) ScriptEvaluator.createFastScriptEvaluator(
new Scanner(null, new StringReader("return a + b;")),
Foo.class,
new String[] { "a", "b" },
(ClassLoader) null // Use current thread's context class loader
);
System.out.println("1 + 2 = " + f.bar(1, 2));
Notice: The interfaceToImplement must either be declared public ,
or with package scope in the root package (i.e. | public static Object | createFastScriptEvaluator(Scanner scanner, String className, Class optionalExtendedType, Class interfaceToImplement, String[] parameterNames, ClassLoader optionalParentClassLoader) Like
ScriptEvaluator.createFastScriptEvaluator(Scanner,Class,String[],ClassLoader) ,
but gives you more control over the generated class (rarely needed in practice). | public static Object | createFastScriptEvaluator(Scanner scanner, String[] optionalDefaultImports, String className, Class optionalExtendedType, Class interfaceToImplement, String[] parameterNames, ClassLoader optionalParentClassLoader) | public Object | evaluate(Object[] parameterValues) Calls the generated method with concrete parameter values. | public Object | evaluate(int idx, Object[] parameterValues) Calls the generated method with concrete parameter values.
Each parameter value must have the same type as specified through
the "parameterTypes" parameter of
ScriptEvaluator.setParameters(String[],Class[]) .
Parameters of primitive type must passed with their wrapper class
objects.
The object returned has the class as specified through
ScriptEvaluator.setReturnType(Class) .
This method is thread-safe.
Parameters: idx - The index of the script (0 ... | protected Class | getDefaultReturnType() | public Method | getMethod() Returns the loaded
java.lang.reflect.Method . | public Method | getMethod(int idx) Returns the loaded
java.lang.reflect.Method .
This method must only be called after
ScriptEvaluator.cook(Scanner) .
This method must not be called for instances of derived classes.
Parameters: idx - The index of the script (0 ... | protected Java.Block | makeBlock(int idx, Scanner scanner) Fill the given block by parsing statements until EOF and adding
them to the block. | protected Java.MethodDeclarator | makeMethodDeclaration(Location location, boolean staticMethod, Class returnType, String methodName, Class[] parameterTypes, String[] parameterNames, Class[] thrownExceptions, Java.Block optionalBody) | public void | setMethodName(String methodName) Define the name of the generated method. | public void | setMethodNames(String[] methodNames) Define the names of the generated methods. | public void | setParameters(String[] parameterNames, Class[] parameterTypes) Define the names and types of the parameters of the generated method. | public void | setParameters(String[][] parameterNames, Class[][] parameterTypes) Define the names and types of the parameters of the generated methods. | public void | setReturnType(Class returnType) Define the return type of the generated method. | public void | setReturnTypes(Class[] returnTypes) Define the return types of the scripts. | public void | setStaticMethod(boolean staticMethod) Define whether the generated method should be STATIC or not. | public void | setStaticMethod(boolean[] staticMethod) Define whether the methods implementing each script should be STATIC or not. | public void | setThrownExceptions(Class[] thrownExceptions) Define the exceptions that the generated method may throw. | public void | setThrownExceptions(Class[][] thrownExceptions) Define the exceptions that the generated methods may throw. |
optionalMethodNames | protected String[] optionalMethodNames(Code) | | |
optionalParameterNames | protected String[][] optionalParameterNames(Code) | | |
optionalParameterTypes | protected Class[][] optionalParameterTypes(Code) | | |
optionalReturnTypes | protected Class[] optionalReturnTypes(Code) | | |
optionalStaticMethod | protected boolean[] optionalStaticMethod(Code) | | |
optionalThrownExceptions | protected Class[][] optionalThrownExceptions(Code) | | |
ScriptEvaluator | public ScriptEvaluator(String optionalFileName, InputStream is, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code) | | Equivalent to
ScriptEvaluator se = new ScriptEvaluator();
se.setReturnType(returnType);
se.setParameters(parameterNames, parameterTypes);
se.setThrownExceptions(thrownExceptions);
se.setParentClassLoader(optionalParentClassLoader);
se.cook(optionalFileName, is);
See Also: ScriptEvaluator.ScriptEvaluator() See Also: ScriptEvaluator.setReturnType(Class) See Also: ScriptEvaluator.setParameters(String[],Class[]) See Also: ScriptEvaluator.setThrownExceptions(Class[]) See Also: SimpleCompiler.setParentClassLoader(ClassLoader) See Also: Cookable.cook(StringInputStream) |
ScriptEvaluator | public ScriptEvaluator(String optionalFileName, Reader reader, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code) | | Equivalent to
ScriptEvaluator se = new ScriptEvaluator();
se.setReturnType(returnType);
se.setParameters(parameterNames, parameterTypes);
se.setThrownExceptions(thrownExceptions);
se.setParentClassLoader(optionalParentClassLoader);
se.cook(reader);
See Also: ScriptEvaluator.ScriptEvaluator() See Also: ScriptEvaluator.setReturnType(Class) See Also: ScriptEvaluator.setParameters(String[],Class[]) See Also: ScriptEvaluator.setThrownExceptions(Class[]) See Also: SimpleCompiler.setParentClassLoader(ClassLoader) See Also: Cookable.cook(StringReader) |
ScriptEvaluator | public ScriptEvaluator(Scanner scanner, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code) | | Equivalent to
ScriptEvaluator se = new ScriptEvaluator();
se.setReturnType(returnType);
se.setParameters(parameterNames, parameterTypes);
se.setThrownExceptions(thrownExceptions);
se.setParentClassLoader(optionalParentClassLoader);
se.cook(scanner);
See Also: ScriptEvaluator.ScriptEvaluator() See Also: ScriptEvaluator.setReturnType(Class) See Also: ScriptEvaluator.setParameters(String[],Class[]) See Also: ScriptEvaluator.setThrownExceptions(Class[]) See Also: SimpleCompiler.setParentClassLoader(ClassLoader) See Also: Cookable.cook(Scanner) |
ScriptEvaluator | public ScriptEvaluator(Scanner scanner, Class optionalExtendedType, Class[] implementedTypes, Class returnType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code) | | Equivalent to
ScriptEvaluator se = new ScriptEvaluator();
se.setExtendedType(optionalExtendedType);
se.setImplementedTypes(implementedTypes);
se.setReturnType(returnType);
se.setParameters(parameterNames, parameterTypes);
se.setThrownExceptions(thrownExceptions);
se.setParentClassLoader(optionalParentClassLoader);
se.cook(scanner);
See Also: ScriptEvaluator.ScriptEvaluator() See Also: ClassBodyEvaluator.setExtendedType(Class) See Also: ClassBodyEvaluator.setImplementedTypes(Class[]) See Also: ScriptEvaluator.setReturnType(Class) See Also: ScriptEvaluator.setParameters(String[],Class[]) See Also: ScriptEvaluator.setThrownExceptions(Class[]) See Also: SimpleCompiler.setParentClassLoader(ClassLoader) See Also: Cookable.cook(Scanner) |
ScriptEvaluator | public ScriptEvaluator(Scanner scanner, String className, Class optionalExtendedType, Class[] implementedTypes, boolean staticMethod, Class returnType, String methodName, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader) throws Scanner.ScanException, Parser.ParseException, CompileException, IOException(Code) | | Equivalent to
ScriptEvaluator se = new ScriptEvaluator();
se.setClassName(className);
se.setExtendedType(optionalExtendedType);
se.setImplementedTypes(implementedTypes);
se.setStaticMethod(staticMethod);
se.setReturnType(returnType);
se.setMethodName(methodName);
se.setParameters(parameterNames, parameterTypes);
se.setThrownExceptions(thrownExceptions);
se.setParentClassLoader(optionalParentClassLoader);
se.cook(scanner);
See Also: ScriptEvaluator.ScriptEvaluator() See Also: ClassBodyEvaluator.setClassName(String) See Also: ClassBodyEvaluator.setExtendedType(Class) See Also: ClassBodyEvaluator.setImplementedTypes(Class[]) See Also: ScriptEvaluator.setStaticMethod(boolean) See Also: ScriptEvaluator.setReturnType(Class) See Also: ScriptEvaluator.setMethodName(String) See Also: ScriptEvaluator.setParameters(String[],Class[]) See Also: ScriptEvaluator.setThrownExceptions(Class[]) See Also: SimpleCompiler.setParentClassLoader(ClassLoader) See Also: Cookable.cook(Scanner) |
ScriptEvaluator | public ScriptEvaluator()(Code) | | |
cook | final public void cook(Scanner[] scanners) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code) | | Like
ScriptEvaluator.cook(Scanner) , 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
optionalFileName argument of
Scanner.Scanner(StringReader) to
distinguish between the individual token sources.
On a 2 GHz Intel Pentium Core Duo under Windows XP with an IBM 1.4.2 JDK, compiling
10000 expressions "a + b" (integer) takes about 4 seconds and 56 MB of main memory.
The generated class file is 639203 bytes large.
The number and the complexity of the scripts is restricted by the
Limitations
of the Java Virtual Machine, where the most limiting factor is the 64K entries limit
of the constant pool. Since every method with a distinct name requires one entry there,
you can define at best 32K (very simple) scripts.
If and only if the number of scanners is one, then that single script may contain leading
IMPORT directives.
throws: IllegalStateException - if any of the preceeding set...() had an array size different from that of scanners |
createFastScriptEvaluator | public static Object createFastScriptEvaluator(Scanner scanner, Class interfaceToImplement, String[] parameterNames, ClassLoader optionalParentClassLoader) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code) | | 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
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) ScriptEvaluator.createFastScriptEvaluator(
new Scanner(null, new StringReader("return a + b;")),
Foo.class,
new String[] { "a", "b" },
(ClassLoader) null // Use current thread's context class loader
);
System.out.println("1 + 2 = " + f.bar(1, 2));
Notice: The interfaceToImplement must either be declared public ,
or with package scope in the root package (i.e. "no" package).
Parameters: scanner - Source of script tokens Parameters: interfaceToImplement - Must declare exactly one method Parameters: parameterNames - Parameters: optionalParentClassLoader - an object that implements the given interface |
createFastScriptEvaluator | public static Object createFastScriptEvaluator(Scanner scanner, String className, Class optionalExtendedType, Class interfaceToImplement, String[] parameterNames, ClassLoader optionalParentClassLoader) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code) | | Like
ScriptEvaluator.createFastScriptEvaluator(Scanner,Class,String[],ClassLoader) ,
but gives you more control over the generated class (rarely needed in practice).
Notice: The interfaceToImplement must either be declared public ,
or with package scope in the same package as className .
Parameters: scanner - Source of script tokens Parameters: className - Name of generated class Parameters: optionalExtendedType - Class to extend Parameters: interfaceToImplement - Must declare exactly the one method that defines the expression's signature Parameters: parameterNames - The expression references the parameters through these names Parameters: optionalParentClassLoader - Used to load referenced classes, defaults to the current thread's "context class loader" an object that implements the given interface and extends the optionalExtendedType |
evaluate | public Object evaluate(int idx, Object[] parameterValues) throws InvocationTargetException(Code) | | Calls the generated method with concrete parameter values.
Each parameter value must have the same type as specified through
the "parameterTypes" parameter of
ScriptEvaluator.setParameters(String[],Class[]) .
Parameters of primitive type must passed with their wrapper class
objects.
The object returned has the class as specified through
ScriptEvaluator.setReturnType(Class) .
This method is thread-safe.
Parameters: idx - The index of the script (0 ... scripts.length - 1 ) Parameters: parameterValues - The concrete parameter values. |
getDefaultReturnType | protected Class getDefaultReturnType()(Code) | | |
makeBlock | protected Java.Block makeBlock(int idx, Scanner scanner) throws ParseException, ScanException, IOException(Code) | | Fill the given block by parsing statements until EOF and adding
them to the block.
|
makeMethodDeclaration | protected Java.MethodDeclarator makeMethodDeclaration(Location location, boolean staticMethod, Class returnType, String methodName, Class[] parameterTypes, String[] parameterNames, Class[] thrownExceptions, Java.Block optionalBody)(Code) | | To the given
Java.ClassDeclaration , add
- A public method declaration with the given return type, name, parameter
names and values and thrown exceptions
- A block
Parameters: returnType - Return type of the declared method |
setMethodName | public void setMethodName(String methodName)(Code) | | Define the name of the generated method. Defaults to an unspecified name.
|
setMethodNames | public void setMethodNames(String[] methodNames)(Code) | | 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
ScriptEvaluator.setParameters(String[][],Class[][]) ).
|
setParameters | public void setParameters(String[] parameterNames, Class[] parameterTypes)(Code) | | Define the names and types of the parameters of the generated method.
|
setParameters | public void setParameters(String[][] parameterNames, Class[][] parameterTypes)(Code) | | Define the names and types of the parameters of the generated methods.
|
setReturnType | public void setReturnType(Class returnType)(Code) | | Define the return type of the generated method. Defaults to void.class .
|
setReturnTypes | public void setReturnTypes(Class[] returnTypes)(Code) | | Define the return types of the scripts. By default all scripts have VOID return type.
|
setStaticMethod | public void setStaticMethod(boolean staticMethod)(Code) | | Define whether the generated method should be STATIC or not. Defaults to true .
|
setStaticMethod | public void setStaticMethod(boolean[] staticMethod)(Code) | | Define whether the methods implementing each script should be STATIC or not. By default
all scripts are compiled into STATIC methods.
|
setThrownExceptions | public void setThrownExceptions(Class[] thrownExceptions)(Code) | | Define the exceptions that the generated method may throw.
|
setThrownExceptions | public void setThrownExceptions(Class[][] thrownExceptions)(Code) | | Define the exceptions that the generated methods may throw.
|
Methods inherited from org.codehaus.janino.ClassBodyEvaluator | protected Java.PackageMemberClassDeclaration addPackageMemberClassDeclaration(Location location, Java.CompilationUnit compilationUnit) throws ParseException(Code)(Java Doc) final protected Class compileToClass(Java.CompilationUnit compilationUnit, EnumeratorSet debuggingInformation, String newClassName) throws CompileException(Code)(Java Doc) public void cook(Scanner scanner) throws CompileException, ParseException, ScanException, IOException(Code)(Java Doc) public static Object createFastClassBodyEvaluator(Scanner scanner, Class optionalBaseType, ClassLoader optionalParentClassLoader) throws CompileException, ParseException, ScanException, IOException(Code)(Java Doc) public static Object createFastClassBodyEvaluator(Scanner scanner, String className, Class optionalExtendedType, Class[] implementedTypes, ClassLoader optionalParentClassLoader) throws CompileException, ParseException, ScanException, IOException(Code)(Java Doc) public Class getClazz()(Code)(Java Doc) final protected Java.CompilationUnit makeCompilationUnit(Scanner optionalScanner) throws ParseException, ScanException, IOException(Code)(Java Doc) public void setClassName(String className)(Code)(Java Doc) public void setDefaultImports(String[] optionalDefaultImports)(Code)(Java Doc) public void setExtendedType(Class optionalExtendedType)(Code)(Java Doc) public void setImplementedTypes(Class[] implementedTypes)(Code)(Java Doc)
|
Methods inherited from org.codehaus.janino.Cookable | abstract public void cook(Scanner scanner) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cook(Reader r) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cook(String optionalFileName, Reader r) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cook(InputStream is) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cook(String optionalFileName, InputStream is) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cook(InputStream is, String optionalEncoding) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cook(String optionalFileName, InputStream is, String optionalEncoding) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cook(String s) throws CompileException, Parser.ParseException, Scanner.ScanException(Code)(Java Doc) final public void cookFile(File file) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cookFile(File file, String optionalEncoding) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cookFile(String fileName) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc) final public void cookFile(String fileName, String optionalEncoding) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException(Code)(Java Doc)
|
|
|