Interface IExpressionEvaluator
-
- All Superinterfaces:
ICookable,IMultiCookable
- All Known Implementing Classes:
ExpressionEvaluator,ExpressionEvaluator
public interface IExpressionEvaluator extends ICookable, IMultiCookable
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
IExpressionEvaluatorobject, proceed as follows:- Create an
IExpressionEvaluator-derived class - Configure the
IExpressionEvaluatorby calling any of the following methods: setExpressionType(Class)setParameters(String[], Class[])setThrownExceptions(Class[])setParentClassLoader(ClassLoader)setDefaultImports(String[])-
Call any of the
ICookable.cook(String, java.io.Reader)methods to scan, parse, compile and load the expression into the JVM.
After the
IExpressionEvaluatorobject is set up, the expression can be evaluated as often with different parameter values (seeevaluate(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
ClassLoaderthat 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
IExpressionEvaluatorby using the following methods:setMethodNames(String[])setParameters(String[][], Class[][])setExpressionTypes(Class[])setStaticMethod(boolean[])setThrownExceptions(Class[][])IMultiCookable.cook(String[], Reader[])evaluate(int, Object[])
Notice that these methods have array parameters in contrast to their one-expression brethren.
Notice that for functionally identical
IExpressionEvaluators,Object.equals(java.lang.Object)will returntrue. 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
Fields Modifier and Type Field Description static Class<?>ANY_TYPEDeprecated.Since autoboxing was introduced in JANINO, this feature is no longer necessary because you can use expression typeObject.classstatic StringDEFAULT_CLASS_NAMEThe fully qualified name of the generated class, iff not reconfigured bysetClassName(String).static Class<?>DEFAULT_EXPRESSION_TYPEThe type of all expressions that were not reconfigured withsetExpressionTypes(Class[]).
-
Method Summary
All Methods Instance Methods Abstract Methods Deprecated Methods Modifier and Type Method Description <T> TcreateFastEvaluator(Reader reader, Class<? extends T> interfaceToImplement, String... parameterNames)<T> TcreateFastEvaluator(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 throughcreateFastEvaluator(String, Class, String[]).Objectevaluate(int idx, Object... arguments)Nullarguments is equivalent withnew Object[0].Objectevaluate(Object... arguments)Evaluates the expression with concrete parameter values.Class<?>getClazz()Class<?>getDefaultExpressionType()String[]getDefaultImports()MethodgetMethod()MethodgetMethod(int idx)Method[]getResult()voidsetClassName(String className)voidsetCompileErrorHandler(ErrorHandler compileErrorHandler)By default,CompileExceptions are thrown on compile errors, but an application my install its ownErrorHandler.voidsetDebuggingInformation(boolean debugSource, boolean debugLines, boolean debugVars)Determines what kind of debugging information is included in the generates classes.voidsetDefaultExpressionType(Class<?> defaultExpressionType)Reconfigures the "default expression type"; if no expression type is configured for an expression, then, when cooking thisIExpressionEvaluator, the "default expression type" is used for the expressionvoidsetDefaultImports(String... defaultImports)voidsetExpressionType(Class<?> expressionType)Defines the type of the expression.voidsetExpressionTypes(Class<?>[] expressionTypes)Configures the types of the expressions.voidsetExtendedClass(Class<?> extendedType)voidsetImplementedInterfaces(Class<?>[] implementedTypes)Configures the interfaces that the generated class implements.voidsetMethodName(String methodName)voidsetMethodNames(String[] methodNames)voidsetOverrideMethod(boolean overrideMethod)voidsetOverrideMethod(boolean[] overrideMethod)voidsetParameters(String[][] parameterNames, Class<?>[][] parameterTypes)voidsetParameters(String[] parameterNames, Class<?>[] parameterTypes)voidsetParentClassLoader(ClassLoader parentClassLoader)The "parent class loader" is used to load referenced classes.voidsetReturnType(Class<?> returnType)Deprecated.UsesetExpressionType(Class)insteadvoidsetStaticMethod(boolean staticMethod)voidsetStaticMethod(boolean[] staticMethod)voidsetThrownExceptions(Class<?>[] thrownExceptions)voidsetThrownExceptions(Class<?>[][] thrownExceptions)voidsetWarningHandler(WarningHandler warningHandler)By default, warnings are discarded, but an application my install a customWarningHandler.
-
-
-
Field Detail
-
DEFAULT_CLASS_NAME
static final String DEFAULT_CLASS_NAME
The fully qualified name of the generated class, iff not reconfigured bysetClassName(String).- See Also:
- Constant Field Values
-
DEFAULT_EXPRESSION_TYPE
static final Class<?> DEFAULT_EXPRESSION_TYPE
The type of all expressions that were not reconfigured withsetExpressionTypes(Class[]).
-
ANY_TYPE
@Deprecated static final Class<?> ANY_TYPE
Deprecated.Since autoboxing was introduced in JANINO, this feature is no longer necessary because you can use expression typeObject.classSpecial value forsetExpressionType(Class)that indicates that the expression may have any type.
-
-
Method Detail
-
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()ornullThe class loader effective for the invoking thread ClassLoaders.BOOTCLASSPATH_CLASS_LOADERThe 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)
By default,CompileExceptions are thrown on compile errors, but an application my install its ownErrorHandler.Be aware that a single problem during compilation often causes a bunch of compile errors, so a good
ErrorHandlercounts errors and throws aCompileExceptionwhen a limit is reached.If the given
ErrorHandlerthrowsCompileExceptions, then the compilation is terminated and the exception is propagated.If the given
ErrorHandlerdoes not throwCompileExceptions, then the compiler may or may not continue compilation, but must eventually throw aCompileException.In other words: The
ErrorHandlermay throw aCompileExceptionor not, but the compiler must definitely throw aCompileExceptionif one or more compile errors have occurred.- Parameters:
compileErrorHandler-nullto restore the default behavior (throwing aCompileException
-
setWarningHandler
void setWarningHandler(@Nullable WarningHandler warningHandler)
By default, warnings are discarded, but an application my install a customWarningHandler.- Parameters:
warningHandler-nullto indicate that no warnings be issued
-
evaluate
@Nullable Object evaluate(@Nullable 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.
Nullarguments is equivalent withnew Object[0].- Parameters:
arguments- The actual parameter values- Throws:
InvocationTargetException
-
setDefaultExpressionType
void setDefaultExpressionType(Class<?> defaultExpressionType)
Reconfigures the "default expression type"; if no expression type is configured for an expression, then, when cooking thisIExpressionEvaluator, the "default expression type" is used for the expression
-
getDefaultExpressionType
Class<?> getDefaultExpressionType()
- Returns:
- The currently configured "default expression type"
- See Also:
setDefaultExpressionType(Class)
-
setImplementedInterfaces
void setImplementedInterfaces(Class<?>[] implementedTypes)
Configures the interfaces that the generated class implements.
-
setReturnType
@Deprecated void setReturnType(@Deprecated Class<?> returnType)
Deprecated.UsesetExpressionType(Class)instead
-
setExpressionType
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
expressionTypeisvoid.class, then the expression must be an invocation of avoidmethod.
-
setExpressionTypes
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 avoidmethod.
-
setOverrideMethod
void setOverrideMethod(boolean overrideMethod)
-
setOverrideMethod
void setOverrideMethod(boolean[] overrideMethod)
-
setClassName
void setClassName(String className)
- See Also:
IClassBodyEvaluator.setClassName(String)
-
setExtendedClass
void setExtendedClass(Class<?> extendedType)
-
setDefaultImports
void setDefaultImports(String... defaultImports)
-
getDefaultImports
String[] getDefaultImports()
- See Also:
IClassBodyEvaluator.getDefaultImports()
-
setStaticMethod
void setStaticMethod(boolean staticMethod)
-
setStaticMethod
void setStaticMethod(boolean[] staticMethod)
-
setMethodName
void setMethodName(String methodName)
- See Also:
IScriptEvaluator.setMethodName(String)
-
setMethodNames
void setMethodNames(String[] methodNames)
-
setThrownExceptions
void setThrownExceptions(Class<?>[] thrownExceptions)
-
setThrownExceptions
void setThrownExceptions(Class<?>[][] thrownExceptions)
-
evaluate
@Nullable Object evaluate(int idx, @Nullable Object... arguments) throws InvocationTargetException
Nullarguments is equivalent withnew Object[0].- Throws:
InvocationTargetException
-
createFastEvaluator
<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 throughcreateFastEvaluator(String, Class, String[]). Expression evaluation is faster than throughevaluate(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 expressionAll other configuration (implemented type, static method, return type, method name, parameter names and types, thrown exceptions) are predetermined by the interfaceToImplement.
Notice: The
interfaceToImplementmust be accessible by the compiled class, i.e. either be declaredpublic, or withprotectedor default access in the package of the compiled class (seesetClassName(String).- Throws:
CompileException
-
createFastEvaluator
<T> T createFastEvaluator(Reader reader, Class<? extends T> interfaceToImplement, String... parameterNames) throws CompileException, IOException
- Throws:
CompileExceptionIOException- See Also:
createFastEvaluator(String, Class, String[])
-
getMethod
Method getMethod()
- See Also:
IScriptEvaluator.getMethod()
-
getMethod
Method getMethod(int idx)
- See Also:
IScriptEvaluator.getMethod(int)
-
getClazz
Class<?> getClazz()
- See Also:
IClassBodyEvaluator.getClazz()
-
getResult
Method[] getResult()
- See Also:
IScriptEvaluator.getResult()
-
-