Author: henrib Date: Thu Nov 12 17:11:24 2009 New Revision: 835449 URL: http://svn.apache.org/viewvc?rev=835449&view=rev Log: Updated package documentation Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl/package.html Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl/package.html URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl/package.html?rev=835449&r1=835448&r2=835449&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl/package.html (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl/package.html Thu Nov 12 17:11:24 2009 @@ -1,80 +1,276 @@ - - - Package Documentation for org.apache.commons.jexl Package - - - Provides a framework for evaluating JEXL expressions. -

-

-

-

-

Introduction

-

- Java Expression Language (JEXL) is an expression language engine which can be - embedded in applications and frameworks. JEXL is inspired by Jakarta Velocity - and the Expression Language defined in the JavaServer Pages Standard Tag Library - version 1.1 (JSTL) and JavaServer Pages version 2.0 (JSP). -

-

- JEXL attempts to bring some of the lessons learned by the Velocity - community about expression languages in templating to a wider audience. - Commons Jelly needed - Velocity-ish method access, it just had to have it. -

-

- It must be noted that JEXL is not a compatibile implementation of EL as defined - in JSTL 1.1 (JSR-052) or JSP 2.0 (JSR-152). For a compatible implementation of - these specifications, see the - Commons EL project. -

- -

A Brief Example

- -

- When evaluating expressions, JEXL merges an - Expression - with a - JexlContext. - An Expression is created using - ExpressionFactory.createExpression(), - passing a String containing valid JEXL syntax. A JexlContext is created using - JexlHelper.createContext(), - and variables are put into a map exposed through the - getVars() - method on JexlContext. The following example, takes a variable named foo, and - invokes the bar() method on the property innerFoo: -

-
-    // Create an expression object
-    String jexlExp = "foo.innerFoo.bar()";
-    Expression e = ExpressionFactory.createExpression( jexlExp );
-
-    // Create a context and add data
-    JexlContext jc = JexlHelper.createContext();
-    jc.getVars().put("foo", new Foo() );
-
-    // Now evaluate the expression, getting the result
-    Object o = e.evaluate(jc);
-  
- - + + + Package Documentation for org.apache.commons.jexl Package + + + Provides a framework for evaluating JEXL expressions. +

+ + +

Introduction

+

+ JEXL is a library intended to facilitate the implementation of dynamic and scripting features in applications + and frameworks. + It enables coding configuration, module/component loose-coupling dependencies or simple template capabilities using a + small footprint API. + Its name itself stands for Java EXpression Language, a simple expression language inspired by Jakarta Velocity + and the Expression Language defined in the JavaServer Pages Standard Tag Library version 1.1 (JSTL) and + JavaServer Pages version 2.0 (JSP). + The API and the expression language exploit Java-beans naming patterns through + introspection to expose property getters and setters. +

+

+ JEXL attempts to bring some of the lessons learned by the Velocity + community about expression languages in templating to a wider audience. + Commons Jelly needed + Velocity-ish method access, it just had to have it. +

+

+ It must be noted that JEXL is not a compatibile implementation of EL as defined + in JSTL 1.1 (JSR-052) or JSP 2.0 (JSR-152). For a compatible implementation of + these specifications, see the + Commons EL project. +

+ +

A Brief Example

+

+ When evaluating expressions, JEXL merges an + {@link org.apache.commons.jexl.Expression} + with a + {@link org.apache.commons.jexl.JexlContext}. + An Expression is created using + {@link org.apache.commons.jexl.JexlEngine#createExpression(java.lang.String)}, + passing a String containing valid JEXL syntax. A JexlContext is created using + {@link org.apache.commons.jexl.JexlHelper#createContext()}, + and variables are put into a map exposed through the + {@link org.apache.commons.jexl.JexlContext#getVars()} + method on JexlContext. The following example, takes a variable named foo, and + invokes the bar() method on the property innerFoo: +

+
+            // Create a JexlEngine (could reuse one instead)
+            JexlEngine jexl = new JexlEngine();
+            // Create an expression object
+            String jexlExp = "foo.innerFoo.bar()";
+            Expression e = jexl.createExpression( jexlExp );
+
+            // Create a context and add data
+            JexlContext jc = JexlHelper.createContext();
+            jc.getVars().put("foo", new Foo() );
+
+            // Now evaluate the expression, getting the result
+            Object o = e.evaluate(jc);
+        
+ +

Using JEXL

+ The API is composed of three levels addressing different functional needs: + + +

Dynamic invocation

+

+ These functionalities are close to the core level utilities found in + BeanUtils. + For basic dynamic property manipulations and method invocation, you can use the following + set of methods: +

+ + The following example illustrate their usage: +
+            // test outer class
+            public static class Froboz {
+                int value;
+                public Froboz(int v) { value = v; }
+                public void setValue(int v) { value = v; }
+                public int getValue() { return value; }
+            }
+            // test inner class
+            public static class Quux {
+                String str;
+                Froboz froboz;
+                public Quux(String str, int fro) {
+                    this.str = str;
+                    froboz = new Froboz(fro);
+                }
+                public Froboz getFroboz() { return froboz; }
+                public void setFroboz(Froboz froboz) { this.froboz = froboz; }
+                public String getStr() { return str; }
+                public void setStr(String str) { this.str = str; }
+            }
+            // test API
+            JexlEngine jexl = nex JexlEngine();
+            Quux quux = jexl.newInstance(Quux.class, "xuuq", 100);
+            jexl.setProperty(quux, "froboz.value", Integer.valueOf(100));
+            Object o = jexl.getProperty(quux, "froboz.value");
+            assertEquals("Result is not 100", new Integer(100), o);
+            jexl.setProperty(quux, "['froboz'].value", Integer.valueOf(1000));
+            o = jexl.getProperty(quux, "['froboz']['value']");
+            assertEquals("Result is not 1000", new Integer(1000), o);
+        
+ +

JEXL script expression

+

+ If your needs require simple expression evaluation capabilities, the core JEXL features + will most likely fit. + The main methods are: +

+ + The following example illustrates their usage: +
+            JexlEngine jexl = nex JexlEngine();
+
+            JexlContext jc = JexlHelper.createContext();
+            jc.getVars().put("quuxClass", quux.class);
+
+            Expression create = jexl.createExpression("quux = new(quuxClass, 'xuuq', 100)");
+            Expression assign = jexl.createExpression("quux.froboz.value = 10");
+            Expression check = jexl.createExpression("quux[\"froboz\"].value");
+            Quux quux = (Quux) create.evaluate(jc);
+            Object o = assign.evaluate(jc);
+            assertEquals("Result is not 10", new Integer(10), o);
+            o = check.evaluate(jc);
+            assertEquals("Result is not 10", new Integer(10), o);
+        
+ +

UnifiedJEXL script expressions

+

+ If you are looking for JSP-EL like and basic templating features, you can + use UnifiedJEXL. +

+ The main methods are: + + The following example illustrates their usage: +
+            JexlEngine jexl = new JexlEngine();
+            UnifiedJEXL ujexl = new UnifiedJEXL(jexl);
+            UnifiedJEXL.Expression expr = ujexl.parse("Hello ${user}");
+            String hello = expr.evaluate(context, expr);
+        
+ +

JEXL Configuration

+

+ The JexlEngine can be configured through a few parameters that will drive how it reacts + in case of errors. These configuration methods are best called at JEXL engine initialization time; it + is recommended to derive from JexlEngine to call those in a constructor. +

+

+ {@link org.apache.commons.jexl.JexlEngine#setLenient} configures when JEXL considers 'null' as an error or not in various situations; + when facing an unreferenceable variable, using null as an argument to an arithmetic operator or failing to call + a method or constructor. The lenient mode is close to JEXL-1.1 behavior. +

+

+ {@link org.apache.commons.jexl.JexlEngine#setSilent} configures how JEXL reacts to errors; if silent, the engine will not throw exceptions + but will warn through loggers and return null in case of errors. Note that when non-silent, JEXL throws + JexlException which are unchecked exception. +

+

+ {@link org.apache.commons.jexl.JexlEngine#setDebug} makes stacktraces carried by JExlException more meaningfull; in particular, these + traces will carry the exact caller location the Expression was created from. +

+

+ {@link org.apache.commons.jexl.JexlEngine#setClassLoader} indicates to a JexlEngine which class loader to use to solve a class name; this affects + how JexlEngine.newInstance and the 'new' script method operates. This is mostly usefull in cases where + you rely on JEXL to dynamically load and call plugins for your application. + This +

+

+ JexlEngine and UnifiedJEXL expression caches can be configured as well. If you intend to use JEXL + repeatedly in your application, these are worth configuring since expression parsing is quite heavy. + Note that all caches created by JEXL are held through SoftReference; under high memory pressure, the GC will be able + to reclaim those caches and JEXL will rebuild them if needed. By default, a JexlEngine does not create a cache + whilst UnifiedJEXL does. +

+

Both JexlEngine and UnifiedJEXL are thread-safe; the same instance can be shared between different + threads and proper synchronization is enforced in critical areas.

+

{@link org.apache.commons.jexl.JexlEngine#setCache} will set how many expressions can be simultaneously cached by the + JEXL engine. UnifiedJEXL allows to define the cache size through its constructor.

+

+ {@link org.apache.commons.jexl.JexlEngine#setFunctions} extend JEXL scripting by registering functions in + namespaces. +

+ This can be used as in: +

+            public static MyMath {
+                public double cos(double x) {
+                    return Math.cos(x);
+                }
+            }
+            Map<String, Object> funcs = new HashMap<String, Object>();
+            funcs.put("math", new MyMath());
+            JexlEngine jexl = new JexlEngine();
+            jexl.setFunctions(funcs);
+
+            JexlContext jc = JexlHelper.createContext();
+            jc.getVars().put("pi", Math.PI);
+
+            e = JEXL.createExpression("math:cos(pi)");
+            o = e.evaluate(jc);
+            assertEquals(Double.valueOf(-1),o);
+        
+ +

JEXL Customization

+ If you need to make JEXL treat some objects in a specialized manner or tweak how it + reacts to some settings, you can derive most of its inner-workings. +

+ {@link org.apache.commons.jexl.JexlEngine} is meant to be + extended and let you capture your own configuration defaults wrt cache sizes and various flags. + Implementing your own cache - instead of the basic LinkedHashMap based one - would be + another possible extension. +

+

+ {@link org.apache.commons.jexl.JexlArithmetic} + is the class to derive if you need to change how operators behave. For example, this would + be the case if you wanted '+' to operate on arrays; you'd need to derive JexlArithmetic and + implement your own version of Add. +

+

+ {@link org.apache.commons.jexl.Interpreter} + is the class to derive if you need to add more features to the evaluation + itself; for instance, you want pre- and post- resolvers for variables or nested scopes for + for variable contexts or add factory based support to the 'new' operator. +

+

+ {@link org.apache.commons.jexl.util.introspection.UberspectImpl} + is the class to derive if you need to add introspection or reflection capabilities for some objects. + For instance, being able to expose and manipulate public fields instead of Java-beans conventions. +

+