org.apache.commons.jexl3
Class JexlEngine

java.lang.Object
  extended by org.apache.commons.jexl3.JexlEngine

public class JexlEngine
extends Object

Creates and evaluates Expression and Script objects. Determines the behavior of Expressions & Scripts during their evaluation with respect to:

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).

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
static class JexlEngine.Frame
          A call frame, created from a scope, stores the arguments and local variables as "registers".
static class JexlEngine.Scope
          A script scope, stores the declaration of parameters and local variables.
protected  class JexlEngine.SoftCache<K,V>
          A soft reference on cache.
 
Field Summary
protected  JexlArithmetic arithmetic
          The JexlArithmetic instance.
protected  JexlEngine.SoftCache<String,ASTJexlScript> cache
          The expression cache.
protected  boolean debug
          Whether error messages will carry debugging information.
static JexlContext EMPTY_CONTEXT
          An empty/static/non-mutable JexlContext used instead of null context.
protected  Map<String,Object> functions
          The map of 'prefix:function' to object implementing the functions.
protected  org.apache.commons.logging.Log logger
          The Log to which all JexlEngine messages will be logged.
protected  Parser parser
          The singleton ExpressionFactory also holds a single instance of Parser.
protected  boolean silent
          Whether expressions evaluated by this engine will throw exceptions (false) or return null (true) on errors.
protected  Boolean strict
          Whether this engine is in lenient or strict mode; if unspecified, use the arithmetic lenient property.
protected  Uberspect uberspect
          The Uberspect instance.
 
Constructor Summary
JexlEngine()
          Creates an engine with default arguments.
JexlEngine(Uberspect anUberspect, JexlArithmetic anArithmetic, Map<String,Object> theFunctions, org.apache.commons.logging.Log log)
          Creates a JEXL engine using the provided Uberspect, (@link JexlArithmetic), a function map and logger.
 
Method Summary
static String cleanExpression(CharSequence str)
          Trims the expression from front & ending spaces.
 void clearCache()
          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.
 Expression createExpression(String expression)
          Creates an Expression from a String containing valid JEXL syntax.
 Expression 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  JexlScript createScript(ASTJexlScript tree, String text)
          An overridable through covariant return Script creator.
 Script createScript(File scriptFile)
          Creates a Script from a File containing valid JEXL syntax.
 JexlScript createScript(String scriptText)
          Creates a Script from a String containing valid JEXL syntax.
 JexlScript createScript(String scriptText, JexlInfo info, String[] names)
          Creates a Script from a String containing valid JEXL syntax.
 JexlScript createScript(String scriptText, String... names)
          Creates a Script from a String containing valid JEXL syntax.
 Script createScript(URL scriptUrl)
          Creates a Script from a URL containing valid JEXL syntax.
protected  Object doCreateInstance(Object clazz, Object... args)
          Creates a new instance of an object using the most appropriate constructor based on the arguments.
 JexlArithmetic getArithmetic()
          Gets this engine underlying arithmetic.
 Map<String,Object> getFunctions()
          Retrieves the map of function namespaces.
protected  String[] getLocalVariables(JexlScript script)
          Gets the array of local variable from a script.
protected  String[] getParameters(JexlScript script)
          Gets the array of parameters from a script.
 Object getProperty(JexlContext context, Object bean, String expr)
          Accesses properties of a bean using an expression.
 Object getProperty(Object bean, String expr)
          Accesses properties of a bean using an expression.
 Uberspect getUberspect()
          Gets this engine underlying uberspect.
static Uberspect getUberspect(org.apache.commons.logging.Log logger)
          Gets the default instance of Uberspect.
protected  Set<List<String>> getVariables(JexlNode script)
          Gets the list of variables accessed by a script.
protected  void getVariables(JexlNode node, Set<List<String>> refs, List<String> ref)
          Fills up the list of variables accessed by a node.
 Object 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 isLenient()
          Checks whether this engine considers unknown variables, methods and constructors as errors.
 boolean isSilent()
          Checks whether this engine throws JexlException during evaluation.
 boolean isStrict()
          Checks whether this engine behaves in strict or lenient mode.
protected  JexlInfo jexlInfo()
          Creates and fills up debugging information.
<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.
 Object 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, 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.
 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.
 void setStrict(boolean flag)
          Sets whether this engine behaves in strict or lenient mode.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

EMPTY_CONTEXT

public static final JexlContext EMPTY_CONTEXT
An empty/static/non-mutable JexlContext used instead of null context.


uberspect

protected final Uberspect uberspect
The Uberspect instance.


arithmetic

protected final JexlArithmetic arithmetic
The JexlArithmetic instance.


logger

protected final org.apache.commons.logging.Log logger
The Log to which all JexlEngine messages will be logged.


parser

protected final Parser parser
The singleton ExpressionFactory also holds a single instance of Parser. When parsing expressions, ExpressionFactory synchronizes on Parser.


silent

protected boolean silent
Whether expressions evaluated by this engine will throw exceptions (false) or return null (true) on errors. Default is false.


strict

protected Boolean strict
Whether this engine is in lenient or strict mode; if unspecified, use the arithmetic lenient property.


debug

protected boolean debug
Whether error messages will carry debugging information.


functions

protected Map<String,Object> functions
The map of 'prefix:function' to object implementing the functions.


cache

protected JexlEngine.SoftCache<String,ASTJexlScript> cache
The expression cache.

Constructor Detail

JexlEngine

public JexlEngine()
Creates an engine with default arguments.


JexlEngine

public JexlEngine(Uberspect anUberspect,
                  JexlArithmetic anArithmetic,
                  Map<String,Object> theFunctions,
                  org.apache.commons.logging.Log log)
Creates a JEXL engine using the provided Uberspect, (@link JexlArithmetic), a function map and logger.

Parameters:
anUberspect - to allow different introspection behaviour
anArithmetic - to allow different arithmetic behaviour
theFunctions - an optional map of functions (@link setFunctions)
log - the logger for various messages
Method Detail

getUberspect

public static Uberspect getUberspect(org.apache.commons.logging.Log logger)
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

public Uberspect getUberspect()
Gets this engine underlying uberspect.

Returns:
the uberspect

getArithmetic

public JexlArithmetic getArithmetic()
Gets this engine underlying arithmetic.

Returns:
the arithmetic

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:
setSilent(boolean), setLenient(boolean)

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:
setDebug(boolean), setLenient(boolean)

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.

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 3.0, you need a JexlThreadedArithmetic instance for this call to also modify the JexlArithmetic leniency behavior.

Parameters:
flag - true means no JexlException will occur, false allows them
See Also:
setSilent(boolean), setDebug(boolean)

isLenient

public boolean isLenient()
Checks whether this engine considers unknown variables, methods and constructors as errors.

If not explicitly set, the arithmetic leniency value applies.

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).

Parameters:
flag - true for strict, false for lenient

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

setClassLoader

public void setClassLoader(ClassLoader loader)
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

public void setFunctions(Map<String,Object> funcs)
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

public Map<String,Object> getFunctions()
Retrieves the map of function namespaces.

Returns:
the map passed in setFunctions or the empty map if the original was null.

createExpression

protected Expression createExpression(ASTJexlScript tree,
                                      String text)
An overridable through covariant return Expression creator.

Parameters:
text - the script text
tree - the parse AST tree
Returns:
the script instance

createExpression

public Expression createExpression(String expression)
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

public Expression createExpression(String expression,
                                   JexlInfo info)
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
info - 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

public JexlScript createScript(String scriptText)
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 a JexlContext.
Throws:
JexlException - if there is a problem parsing the script.

createScript

public JexlScript createScript(String scriptText,
                               String... names)
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
names - the script parameter names
Returns:
A Script which can be executed using a JexlContext.
Throws:
JexlException - if there is a problem parsing the script.

createScript

public JexlScript createScript(String scriptText,
                               JexlInfo info,
                               String[] names)
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 syntax
info - An info structure to carry debugging information if needed
names - the script parameter names
Returns:
A Script which can be executed using a JexlContext.
Throws:
JexlException - if there is a problem parsing the script.

createScript

protected JexlScript createScript(ASTJexlScript tree,
                                  String text)
An overridable through covariant return Script creator.

Parameters:
text - the script text
tree - the parse AST tree
Returns:
the script instance

createScript

public Script createScript(File scriptFile)
                    throws IOException
Creates a Script from a File containing valid JEXL syntax. This method parses the script and validates the syntax.

Parameters:
scriptFile - A File containing valid JEXL syntax. Must not be null. Must be a readable file.
Returns:
A Script which can be executed with a JexlContext.
Throws:
IOException - if there is a problem reading the script.
JexlException - if there is a problem parsing the script.

createScript

public Script createScript(URL scriptUrl)
                    throws IOException
Creates a Script from a URL containing valid JEXL syntax. This method parses the script and validates the syntax.

Parameters:
scriptUrl - A URL containing valid JEXL syntax. Must not be null. Must be a readable file.
Returns:
A Script which can be executed with a JexlContext.
Throws:
IOException - if there is a problem reading the script.
JexlException - if there is a problem parsing the script.

getProperty

public Object getProperty(Object bean,
                          String expr)
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 from
expr - the property expression
Returns:
the value of the property
Throws:
JexlException - if there is an error parsing the expression or during evaluation

getProperty

public Object getProperty(JexlContext context,
                          Object bean,
                          String expr)
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 context
bean - the bean to get properties from
expr - the property expression
Returns:
the value of the property
Throws:
JexlException - if there is an error parsing the expression or during evaluation

setProperty

public void setProperty(Object bean,
                        String expr,
                        Object value)
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 in
expr - the property expression
value - the value of the property
Throws:
JexlException - if there is an error parsing the expression or during evaluation

setProperty

public void setProperty(JexlContext context,
                        Object bean,
                        String expr,
                        Object value)
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 context
bean - the bean to set properties in
expr - the property expression
value - the value of the property
Throws:
JexlException - if there is an error parsing the expression or during evaluation

invokeMethod

public Object invokeMethod(Object obj,
                           String meth,
                           Object... args)
Invokes an object's method by name and arguments.

Parameters:
obj - the method's invoker object
meth - the method's name
args - 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

public <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.

Type Parameters:
T - the type of object
Parameters:
clazz - the class to instantiate
args - the constructor arguments
Returns:
the created object instance or null on failure when silent

newInstance

public Object newInstance(String clazz,
                          Object... args)
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 loader
args - the constructor arguments
Returns:
the created object instance or null on failure when silent

doCreateInstance

protected Object doCreateInstance(Object clazz,
                                  Object... args)
Creates a new instance of an object using the most appropriate constructor based on the arguments.

Parameters:
clazz - the class to instantiate
args - the constructor arguments
Returns:
the created object instance or null on failure when silent

createInterpreter

protected Interpreter createInterpreter(JexlContext context)
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 mode
silentFlag - whether the interpreter runs in silent mode
Returns:
an Interpreter

createCache

protected <K,V> Map<K,V> createCache(int cacheSize)
Creates a cache.

Type Parameters:
K - the key type
V - 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.


getVariables

protected Set<List<String>> getVariables(JexlNode script)
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

getVariables

protected void getVariables(JexlNode node,
                            Set<List<String>> refs,
                            List<String> ref)
Fills up the list of variables accessed by a node.

Parameters:
node - the node
refs - the set of variable being filled
ref - the current variable being filled

getParameters

protected String[] getParameters(JexlScript script)
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:
3.0

getLocalVariables

protected String[] getLocalVariables(JexlScript script)
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:
3.0

parse

protected ASTJexlScript parse(CharSequence expression,
                              JexlInfo info,
                              JexlEngine.Scope frame)
Parses an expression.

Parameters:
expression - the expression to parse
info - debug information structure
frame - the script frame to use
Returns:
the parsed tree
Throws:
JexlException - if any error occured during parsing

createInfo

protected JexlInfo createInfo(String fn,
                              int l,
                              int c)
Creates a JexlInfo instance.

Parameters:
fn - url/file name
l - line number
c - column number
Returns:
a JexlInfo instance

jexlInfo

protected JexlInfo jexlInfo()
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

public static String cleanExpression(CharSequence str)
Trims the expression from front & ending spaces.

Parameters:
str - expression to clean
Returns:
trimmed expression ending in a semi-colon

readerToString

public static String readerToString(Reader scriptReader)
                             throws IOException
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.


Copyright © 2001-2011 The Apache Software Foundation. All Rights Reserved.