Expression Factory
To start using the EL, you need an instance of javax.el.ExpressionFactory. The expression factory is used to create expressions of various types.
JUEL's expression factory implementation is de.odysseus.el.ExpressionFactoryImpl. The easiest way to obtain an expression factory instance is
javax.el.ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
An expression factory is thread-safe and can create an unlimited number of expressions. The expression factory provides operations to
- perform type coercions,
- create tree value expressions,
- create object value expressions,
- create tree method expressions.
Expression Cache
Each factory instance uses its own expression cache. Caching expressions can be an important issue, because parsing is relative expensive. An expression cache maps expression strings to their parsed representations (trees).
JUEL provides a caching interface which allows applications to use their own caching mechanism. However, in most scenarios, JUEL's default implementation should be fine. It uses two maps as follows:
- The primary map is implemented by a java.util.LinkedHashMap. If the maximum cache size has been reached and another element should be added, the least recently used (lru) entry is removed from the primary map and added to the secondary map.
- The secondary map is implemented by a java.util.WeakHashMap. Entries are guaranteed to stay as long as there are any strong references to their expression strings. No more referenced, the corresponding map entry may be removed by the garbage collector.
The default constructor uses a maximum cache size of 1000. You may specify a different value - say 5000 - by specifying the javax.el.cacheSize property.
java.util.Properties properties = new java.util.Properties(); properties.put("javax.el.cacheSize", "5000"); javax.el.ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl(properties);
Using your own caching mechanism is covered in the Advanced Topics secion.
Type Conversions
Type conversions are performed at several points while evaluating expressions.
- Operands are coerced when performing arithmetic or logical operations
- Value expression results are coerced to the expected type specified at creation time
- For literal method expressions the text is coerced to the type specified at creation time
- For non-literal method expressions the last property is coerced to a method name
- Composite expression coerce their sub-expressions to strings before concatenating them
All these coercions are done following the same rules. The specification describes these coercion rules in detail. It supports converting between string, character, boolean, enumeration and number types. Additionally, the conversion of strings to other types is supported by the use of (Java Beans) property editors. The EL makes the coercion rules available to client applications via the expression factory method
ExpressionFactoryImpl.coerceToType(Object, Class<?>)
whose return type is Object.
Factory Configuration
The factory may be configured via property files. The mechanism described here is used when an expression factory is created using the default constructor. The lookup procedure for properties is as follows:
- JAVA_HOME/lib/el.properties - If this file contains property javax.el.ExpressionFactory whose value is de.odysseus.el.ExpressionFactoryImpl, its properties are loaded and taken as default properties.
- el.properties anywhere on your classpath - These properties may override the properties from JAVA_HOME/lib/el.properties.
Having this, the following properties are read:
- javax.el.cacheSize - expression cache size (default is 1000)
- javax.el.methodInvocations - set to true to allow method invocations. Please refer to the Advanced Topics section for more on this.
- javax.el.nullProperties - set to true to resolve null properties. Please refer to the Advanced Topics section for more on this.