Class JexlEngine
Creates and evaluates Expression and Script objects. Determines the behavior of Expressions & Scripts during their evaluation with respect to:
- Introspection, see
Uberspect
- Arithmetic & comparison, see
JexlArithmetic
- Error reporting
- Logging
The setSilent
and setLenient
methods allow to fine-tune an engine instance behavior
according to various error control needs. The lenient/strict flag tells the engine when and if null as operand is
considered an error, the silent/verbose flag tells the engine what to do with the error
(log as warning or throw exception).
- When "silent" & "lenient":
0 & null should be indicators of "default" values so that even in an case of error, something meaningfull can still be inferred; may be convenient for configurations.
- When "silent" & "strict":
One should probably consider using null as an error case - ie, every object manipulated by JEXL should be valued; the ternary operator, especially the '?:' form can be used to workaround exceptional cases. Use case could be configuration with no implicit values or defaults.
- When "verbose" & "lenient":
The error control grain is roughly on par with JEXL 1.0
- When "verbose" & "strict":
The finest error control grain is obtained; it is the closest to Java code - still augmented by "script" capabilities regarding automated conversions & type matching.
Note that methods that evaluate expressions may throw unchecked exceptions;
The JexlException
are thrown in "non-silent" mode but since these are
RuntimeException, user-code should catch them wherever most appropriate.
- Since:
- 2.0
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic final class
A call frame, created from a scope, stores the arguments and local variables as "registers".static final class
A script scope, stores the declaration of parameters and local variables.protected class
A soft reference on cache. -
Field Summary
Modifier and TypeFieldDescriptionprotected final JexlArithmetic
The JexlArithmetic instance.protected JexlEngine.SoftCache<String,
ASTJexlScript> The expression cache.protected boolean
Whether error messages will carry debugging information.static final JexlContext
An empty/static/non-mutable JexlContext used instead of null context.The map of 'prefix:function' to object implementing the functions.protected final Log
The Log to which all JexlEngine messages will be logged.protected final Parser
The singleton ExpressionFactory also holds a single instance ofParser
.protected boolean
Whether expressions evaluated by this engine will throw exceptions (false) or return null (true) on errors.protected final Uberspect
The Uberspect instance. -
Constructor Summary
ConstructorDescriptionCreates an engine with default arguments.JexlEngine
(Uberspect anUberspect, JexlArithmetic anArithmetic, Map<String, Object> theFunctions, Log log) Creates a JEXL engine using the providedUberspect
, (@link JexlArithmetic), a function map and logger. -
Method Summary
Modifier and TypeMethodDescriptionstatic String
Trims the expression from front & ending spaces.void
Clears the expression cache.protected <K,
V> Map<K, V> createCache
(int cacheSize) Creates a cache.protected Expression
createExpression
(ASTJexlScript tree, String text) An overridable through covariant return Expression creator.createExpression
(String expression) Creates an Expression from a String containing valid JEXL syntax.createExpression
(String expression, JexlInfo info) Creates an Expression from a String containing valid JEXL syntax.protected JexlInfo
createInfo
(String fn, int l, int c) Creates a JexlInfo instance.protected Interpreter
createInterpreter
(JexlContext context) Creates an interpreter.protected Interpreter
createInterpreter
(JexlContext context, boolean strictFlag, boolean silentFlag) Creates an interpreter.protected Script
createScript
(ASTJexlScript tree, String text) An overridable through covariant return Script creator.createScript
(File scriptFile) Creates a Script from aFile
containing valid JEXL syntax.createScript
(String scriptText) Creates a Script from a String containing valid JEXL syntax.createScript
(String scriptText, JexlInfo info) Deprecated.createScript
(String scriptText, JexlInfo info, String[] names) Creates a Script from a String containing valid JEXL syntax.createScript
(String scriptText, String... names) Creates a Script from a String containing valid JEXL syntax.createScript
(URL scriptUrl) Creates a Script from aURL
containing valid JEXL syntax.protected JexlInfo
Creates and fills up debugging information.protected Object
doCreateInstance
(Object clazz, Object... args) Creates a new instance of an object using the most appropriate constructor based on the arguments.Gets this engine underlying arithmetic.Retrieves the map of function namespaces.protected String[]
getLocalVariables
(Script script) Gets the array of local variable from a script.protected String[]
getParameters
(Script script) Gets the array of parameters from a script.getProperty
(JexlContext context, Object bean, String expr) Accesses properties of a bean using an expression.getProperty
(Object bean, String expr) Accesses properties of a bean using an expression.Gets this engine underlying uberspect.static Uberspect
getUberspect
(Log logger) Gets the default instance of Uberspect.protected void
Fills up the list of variables accessed by a node.getVariables
(Script script) Gets the list of variables accessed by a script.invokeMethod
(Object obj, String meth, Object... args) Invokes an object's method by name and arguments.boolean
isDebug()
Checks whether this engine is in debug mode.boolean
Checks whether this engine considers unknown variables, methods and constructors as errors.boolean
isSilent()
Checks whether this engine throws JexlException during evaluation.final boolean
isStrict()
Checks whether this engine behaves in strict or lenient mode.<T> T
newInstance
(Class<? extends T> clazz, Object... args) Creates a new instance of an object using the most appropriate constructor based on the arguments.newInstance
(String clazz, Object... args) Creates a new instance of an object using the most appropriate constructor based on the arguments.protected ASTJexlScript
parse
(CharSequence expression, JexlInfo info) Deprecated.Useparse(CharSequence, JexlInfo, Scope)
insteadprotected ASTJexlScript
parse
(CharSequence expression, JexlInfo info, JexlEngine.Scope frame) Parses an expression.static String
readerToString
(Reader scriptReader) Read from a reader into a local buffer and return a String with the contents of the reader.void
setCache
(int size) Sets a cache for expressions of the defined size.void
setClassLoader
(ClassLoader loader) Sets the class loader used to discover classes in 'new' expressions.void
setDebug
(boolean flag) Sets whether this engine reports debugging information when error occurs.void
setFunctions
(Map<String, Object> funcs) Sets the map of function namespaces.void
setLenient
(boolean flag) Sets whether this engine considers unknown variables, methods and constructors as errors or evaluates them as null or zero.void
setProperty
(JexlContext context, Object bean, String expr, Object value) Assign properties of a bean using an expression.void
setProperty
(Object bean, String expr, Object value) Assign properties of a bean using an expression.void
setSilent
(boolean flag) Sets whether this engine throws JexlException during evaluation when an error is triggered.final void
setStrict
(boolean flag) Sets whether this engine behaves in strict or lenient mode.
-
Field Details
-
EMPTY_CONTEXT
An empty/static/non-mutable JexlContext used instead of null context. -
uberspect
The Uberspect instance. -
arithmetic
The JexlArithmetic instance. -
logger
The Log to which all JexlEngine messages will be logged. -
parser
The singleton ExpressionFactory also holds a single instance ofParser
. When parsing expressions, ExpressionFactory synchronizes on Parser. -
silent
protected volatile boolean silentWhether expressions evaluated by this engine will throw exceptions (false) or return null (true) on errors. Default is false. -
debug
protected volatile boolean debugWhether error messages will carry debugging information. -
functions
The map of 'prefix:function' to object implementing the functions. -
cache
The expression cache.
-
-
Constructor Details
-
JexlEngine
public JexlEngine()Creates an engine with default arguments. -
JexlEngine
public JexlEngine(Uberspect anUberspect, JexlArithmetic anArithmetic, Map<String, Object> theFunctions, Log log) Creates a JEXL engine using the providedUberspect
, (@link JexlArithmetic), a function map and logger.- Parameters:
anUberspect
- to allow different introspection behaviouranArithmetic
- to allow different arithmetic behaviourtheFunctions
- an optional map of functions (@link setFunctions)log
- the logger for various messages
-
-
Method Details
-
getUberspect
Gets the default instance of Uberspect.This is lazily initialized to avoid building a default instance if there is no use for it. The main reason for not using the default Uberspect instance is to be able to use a (low level) introspector created with a given logger instead of the default one.
- Parameters:
logger
- the logger to use for the underlying Uberspect- Returns:
- Uberspect the default uberspector instance.
-
getUberspect
Gets this engine underlying uberspect.- Returns:
- the uberspect
-
getArithmetic
Gets this engine underlying arithmetic.- Returns:
- the arithmetic
- Since:
- 2.1
-
setDebug
public void setDebug(boolean flag) Sets whether this engine reports debugging information when error occurs.This method is not thread safe; it should be called as an optional step of the JexlEngine initialization code before expression creation & evaluation.
- Parameters:
flag
- true implies debug is on, false implies debug is off.- See Also:
-
isDebug
public boolean isDebug()Checks whether this engine is in debug mode.- Returns:
- true if debug is on, false otherwise
-
setSilent
public void setSilent(boolean flag) Sets whether this engine throws JexlException during evaluation when an error is triggered.This method is not thread safe; it should be called as an optional step of the JexlEngine initialization code before expression creation & evaluation.
- Parameters:
flag
- true means no JexlException will occur, false allows them- See Also:
-
isSilent
public boolean isSilent()Checks whether this engine throws JexlException during evaluation.- Returns:
- true if silent, false (default) otherwise
-
setLenient
public void setLenient(boolean flag) Sets whether this engine considers unknown variables, methods and constructors as errors or evaluates them as null or zero.This method is not thread safe; it should be called as an optional step of the JexlEngine initialization code before expression creation & evaluation.
As of 2.1, you can use a JexlThreadedArithmetic instance to allow the JexlArithmetic leniency behavior to be independently specified per thread, whilst still using a single engine.
- Parameters:
flag
- true means no JexlException will occur, false allows them- See Also:
-
isLenient
public boolean isLenient()Checks whether this engine considers unknown variables, methods and constructors as errors.- Returns:
- true if lenient, false if strict
-
setStrict
public final void setStrict(boolean flag) Sets whether this engine behaves in strict or lenient mode. Equivalent to setLenient(!flag).This method is not thread safe; it should be called as an optional step of the JexlEngine initialization code before expression creation & evaluation.
- Parameters:
flag
- true for strict, false for lenient- Since:
- 2.1
-
isStrict
public final boolean isStrict()Checks whether this engine behaves in strict or lenient mode. Equivalent to !isLenient().- Returns:
- true for strict, false for lenient
- Since:
- 2.1
-
setClassLoader
Sets the class loader used to discover classes in 'new' expressions.This method should be called as an optional step of the JexlEngine initialization code before expression creation & evaluation.
- Parameters:
loader
- the class loader to use
-
setCache
public void setCache(int size) Sets a cache for expressions of the defined size.The cache will contain at most
size
expressions. Note that all JEXL caches are held through SoftReferences and may be garbage-collected.- Parameters:
size
- if not strictly positive, no cache is used.
-
setFunctions
Sets the map of function namespaces.This method is not thread safe; it should be called as an optional step of the JexlEngine initialization code before expression creation & evaluation.
Each entry key is used as a prefix, each entry value used as a bean implementing methods; an expression like 'nsx:method(123)' will thus be solved by looking at a registered bean named 'nsx' that implements method 'method' in that map. If all methods are static, you may use the bean class instead of an instance as value.
If the entry value is a class that has one contructor taking a JexlContext as argument, an instance of the namespace will be created at evaluation time. It might be a good idea to derive a JexlContext to carry the information used by the namespace to avoid variable space pollution and strongly type the constructor with this specialized JexlContext.
The key or prefix allows to retrieve the bean that plays the role of the namespace. If the prefix is null, the namespace is the top-level namespace allowing to define top-level user defined functions ( ie: myfunc(...) )
Note that the JexlContext is also used to try to solve top-level functions. This allows ObjectContext derived instances to call methods on the wrapped object.
- Parameters:
funcs
- the map of functions that should not mutate after the call; if null is passed, the empty collection is used.
-
getFunctions
Retrieves the map of function namespaces.- Returns:
- the map passed in setFunctions or the empty map if the original was null.
-
createExpression
An overridable through covariant return Expression creator.- Parameters:
text
- the script texttree
- the parse AST tree- Returns:
- the script instance
-
createExpression
Creates an Expression from a String containing valid JEXL syntax. This method parses the expression which must contain either a reference or an expression.- Parameters:
expression
- A String containing valid JEXL syntax- Returns:
- An Expression object which can be evaluated with a JexlContext
- Throws:
JexlException
- An exception can be thrown if there is a problem parsing this expression, or if the expression is neither an expression nor a reference.
-
createExpression
Creates an Expression from a String containing valid JEXL syntax. This method parses the expression which must contain either a reference or an expression.- Parameters:
expression
- A String containing valid JEXL syntaxinfo
- An info structure to carry debugging information if needed- Returns:
- An Expression object which can be evaluated with a JexlContext
- Throws:
JexlException
- An exception can be thrown if there is a problem parsing this expression, or if the expression is neither an expression or a reference.
-
createScript
Creates a Script from a String containing valid JEXL syntax. This method parses the script which validates the syntax.- Parameters:
scriptText
- A String containing valid JEXL syntax- Returns:
- A
Script
which can be executed using aJexlContext
. - Throws:
JexlException
- if there is a problem parsing the script.
-
createScript
Deprecated.Creates a Script from a String containing valid JEXL syntax. This method parses the script which validates the syntax.- Parameters:
scriptText
- A String containing valid JEXL syntaxinfo
- An info structure to carry debugging information if needed- Returns:
- A
Script
which can be executed using aJexlContext
. - Throws:
JexlException
- if there is a problem parsing the script.
-
createScript
Creates a Script from a String containing valid JEXL syntax. This method parses the script which validates the syntax.- Parameters:
scriptText
- A String containing valid JEXL syntaxnames
- the script parameter names- Returns:
- A
Script
which can be executed using aJexlContext
. - Throws:
JexlException
- if there is a problem parsing the script.
-
createScript
Creates a Script from a String containing valid JEXL syntax. This method parses the script which validates the syntax. It uses an array of parameter names that will be resolved during parsing; a corresponding array of arguments containing values should be used during evaluation.- Parameters:
scriptText
- A String containing valid JEXL syntaxinfo
- An info structure to carry debugging information if needednames
- the script parameter names- Returns:
- A
Script
which can be executed using aJexlContext
. - Throws:
JexlException
- if there is a problem parsing the script.- Since:
- 2.1
-
createScript
An overridable through covariant return Script creator.- Parameters:
text
- the script texttree
- the parse AST tree- Returns:
- the script instance
-
createScript
Creates a Script from aFile
containing valid JEXL syntax. This method parses the script and validates the syntax.- Parameters:
scriptFile
- AFile
containing valid JEXL syntax. Must not be null. Must be a readable file.- Returns:
- A
Script
which can be executed with aJexlContext
. - Throws:
IOException
- if there is a problem reading the script.JexlException
- if there is a problem parsing the script.
-
createScript
Creates a Script from aURL
containing valid JEXL syntax. This method parses the script and validates the syntax.- Parameters:
scriptUrl
- AURL
containing valid JEXL syntax. Must not be null. Must be a readable file.- Returns:
- A
Script
which can be executed with aJexlContext
. - Throws:
IOException
- if there is a problem reading the script.JexlException
- if there is a problem parsing the script.
-
getProperty
Accesses properties of a bean using an expression.jexl.get(myobject, "foo.bar"); should equate to myobject.getFoo().getBar(); (or myobject.getFoo().get("bar"))
If the JEXL engine is silent, errors will be logged through its logger as warning.
- Parameters:
bean
- the bean to get properties fromexpr
- the property expression- Returns:
- the value of the property
- Throws:
JexlException
- if there is an error parsing the expression or during evaluation
-
getProperty
Accesses properties of a bean using an expression.If the JEXL engine is silent, errors will be logged through its logger as warning.
- Parameters:
context
- the evaluation contextbean
- the bean to get properties fromexpr
- the property expression- Returns:
- the value of the property
- Throws:
JexlException
- if there is an error parsing the expression or during evaluation
-
setProperty
Assign properties of a bean using an expression.jexl.set(myobject, "foo.bar", 10); should equate to myobject.getFoo().setBar(10); (or myobject.getFoo().put("bar", 10) )
If the JEXL engine is silent, errors will be logged through its logger as warning.
- Parameters:
bean
- the bean to set properties inexpr
- the property expressionvalue
- the value of the property- Throws:
JexlException
- if there is an error parsing the expression or during evaluation
-
setProperty
Assign properties of a bean using an expression.If the JEXL engine is silent, errors will be logged through its logger as warning.
- Parameters:
context
- the evaluation contextbean
- the bean to set properties inexpr
- the property expressionvalue
- the value of the property- Throws:
JexlException
- if there is an error parsing the expression or during evaluation
-
invokeMethod
Invokes an object's method by name and arguments.- Parameters:
obj
- the method's invoker objectmeth
- the method's nameargs
- the method's arguments- Returns:
- the method returned value or null if it failed and engine is silent
- Throws:
JexlException
- if method could not be found or failed and engine is not silent
-
newInstance
Creates a new instance of an object using the most appropriate constructor based on the arguments.- Type Parameters:
T
- the type of object- Parameters:
clazz
- the class to instantiateargs
- the constructor arguments- Returns:
- the created object instance or null on failure when silent
-
newInstance
Creates a new instance of an object using the most appropriate constructor based on the arguments.- Parameters:
clazz
- the name of the class to instantiate resolved through this engine's class loaderargs
- the constructor arguments- Returns:
- the created object instance or null on failure when silent
-
doCreateInstance
Creates a new instance of an object using the most appropriate constructor based on the arguments.- Parameters:
clazz
- the class to instantiateargs
- the constructor arguments- Returns:
- the created object instance or null on failure when silent
-
createInterpreter
Creates an interpreter.- Parameters:
context
- a JexlContext; if null, the EMPTY_CONTEXT is used instead.- Returns:
- an Interpreter
-
createInterpreter
protected Interpreter createInterpreter(JexlContext context, boolean strictFlag, boolean silentFlag) Creates an interpreter.- Parameters:
context
- a JexlContext; if null, the EMPTY_CONTEXT is used instead.strictFlag
- whether the interpreter runs in strict modesilentFlag
- whether the interpreter runs in silent mode- Returns:
- an Interpreter
- Since:
- 2.1
-
createCache
Creates a cache.- Type Parameters:
K
- the key typeV
- the value type- Parameters:
cacheSize
- the cache size, must be > 0- Returns:
- a Map usable as a cache bounded to the given size
-
clearCache
public void clearCache()Clears the expression cache.- Since:
- 2.1
-
getVariables
Gets the list of variables accessed by a script.This method will visit all nodes of a script and extract all variables whether they are written in 'dot' or 'bracketed' notation. (a.b is equivalent to a['b']).
- Parameters:
script
- the script- Returns:
- the set of variables, each as a list of strings (ant-ish variables use more than 1 string) or the empty set if no variables are used
- Since:
- 2.1
-
getVariables
Fills up the list of variables accessed by a node.- Parameters:
node
- the noderefs
- the set of variable being filledref
- the current variable being filled- Since:
- 2.1
-
getParameters
Gets the array of parameters from a script.- Parameters:
script
- the script- Returns:
- the parameters which may be empty (but not null) if no parameters were defined
- Since:
- 2.1
-
getLocalVariables
Gets the array of local variable from a script.- Parameters:
script
- the script- Returns:
- the local variables array which may be empty (but not null) if no local variables were defined
- Since:
- 2.1
-
parse
Deprecated.Useparse(CharSequence, JexlInfo, Scope)
insteadParses an expression.- Parameters:
expression
- the expression to parseinfo
- debug information structure- Returns:
- the parsed tree
- Throws:
JexlException
- if any error occured during parsing
-
parse
Parses an expression.- Parameters:
expression
- the expression to parseinfo
- debug information structureframe
- the script frame to use- Returns:
- the parsed tree
- Throws:
JexlException
- if any error occured during parsing
-
createInfo
Creates a JexlInfo instance.- Parameters:
fn
- url/file namel
- line numberc
- column number- Returns:
- a JexlInfo instance
-
debugInfo
Creates and fills up debugging information.This gathers the class, method and line number of the first calling method not owned by JexlEngine, UnifiedJEXL or {Script,Expression}Factory.
- Returns:
- an Info if debug is set, null otherwise
-
cleanExpression
Trims the expression from front & ending spaces.- Parameters:
str
- expression to clean- Returns:
- trimmed expression ending in a semi-colon
-
readerToString
Read from a reader into a local buffer and return a String with the contents of the reader.- Parameters:
scriptReader
- to be read.- Returns:
- the contents of the reader as a String.
- Throws:
IOException
- on any error reading the reader.
-
createScript(String, JexlInfo, String[])