| What's JEX | 
               
                |  
                    JEX is a universal set of APIs for expression 
                      languages. Individual expression languages function as plug-ins. 
                      You use the same set of APIs to invoke any of them.
 | 
               
                | Supported Expression 
                  Languages | 
               
                |  
                    Out of the box JEX supports the following 
                      languages:  
                      javascriptJex uses Rhino 
                        Mozilla implementation of JavaScript (aka ECMA-Script) 
                        for Java. In order to use Jex with JavaScript, you will 
                        need to download the js.jar file from www.mozilla.org.
 
bexlThis is a made-up name for the expression language implicitly 
                        introduced by Jakarta 
                        Commons BeanUtils. See PropertyUtil 
                        for the definition of the language.
 
 
 jxpathAn implementation of the XPath expression language that 
                        applies XPath expressions to graphs of Java Objects. See 
                        JXPath 
                        Home Page on Jakarta Commons.
 {Other candidates: Jexl, XPath via Jaxen, 
                      SPEL, Jpath}
 | 
               
                | Context | 
               
                |  
                    Expressions are evaluated in a Context. 
                      A context holds various pieces of data that are used by 
                      expression language processors: 
                      VariablesAll expression languages that support the notion of a variable 
                      can manipulate and share this set of variables.
 
 
  LocaleLanguages that support internationalization can take advantage 
                        of this piece of configuration.
 
Expression LanguageExpressions evaluated in this context are expressed in 
                        this language.
 
PropertiesExpression language processors can be configured with 
                        properties specified using this language-independant mechanism.
 {Other potential pieces of context: extension 
                      functions, type converters}
 | 
               
                | Types of Expressions | 
               
                |  
                    There are three types of expressions: 
                      Value expressionThese expressions are used compute values. For example, 
                         "xpath:2+2" 
                        and "bexl:address[1].zipCode" 
                        are value expressions.
 
Iteration expressionThe evaluation of an iteration expression produces an 
                         Iterator. 
                        For example, "xpath:/address/zipCode" 
                        produces an iteration over all zipCodes.
 
Variable expressionVariable expressions are used to modify values. Think 
                        of them as the left-hand side of an assignment. For example, 
                        "bexl:address[1].zipCode" 
                        is a valid variable expression.
 The same string can be a valid expression 
                      of more than one type. 
 | 
               
                | Multilingual 
                  Mode | 
               
                |  
                    A Jex Context is by default configured to 
                      be multilingual. What this means is that an expression can 
                      start with a "lang:" 
                      prefix, where lang 
                      identifies the expression language of the expression. Jex 
                      will then locate and use the appropriate language processor. If the Context is multilingual and also 
                      has an expression language specified, that language is used 
                      as the default for the cases when the prefix is missing 
                      or does not correspond to a known language.
 | 
               
                | Compilers and 
                  Interpreters | 
               
                |  
                    Jex supports both interpreted and compiled 
                      languages. An interpreter computes 
                      the value of the expression as it parses it. A compiler 
                      parses the expression into an internal executable form first 
                      and then uses the internal representation for the actual 
                      computation. The internal representation can be cached and 
                      used for faster re-evaluation of the same expression. Some languages better lend themselves to 
                      compilation, some - to interpretation. For example, JXPath, 
                      which has relatively sophisticated syntax, uses a compiler, 
                      while Bexl is so simple that a separate compilation step 
                      would not speed it up by much and perhaps would even slow 
                      it down. Jex supports both types of language processors 
                      equally well. Better yet, if needed, Jex allows an interpreter 
                      to be invoked like a compiler and a compiler like an interpreter. 
                      This flexibility lets the user choose the mode, compilation 
                      or interpretation, that best suits the application's needs 
                      and not worry whether the actual expression languages are 
                      compiled or interpreted.
 | 
               
                | How to Add a 
                  New Compiler or Interpreters | 
               
                |  
                    To add a new Compiler, create a class called 
                      com.plotnix.jex.language.Compiler 
                      that extends the com.plotnix.jex.Compiler 
                      abstract class. Jex will find it by name. Similarly, to add a new Interpreter, create 
                      a class named com.plotnix.jex.language.Interpreter 
                      that extends the com.plotnix.jex.Interpreter 
                      abstract class.
 | 
               
                | Examples | 
               
                |  
                    In all following examples, we will assume 
                      that we have an object graph constructed like this: 
                       
                        | public class AddressBook {
   private Vector addresses = new Vector();
   public Vector getAddresses(){ 
       return addresses; 
   }
}
public class Address {
    private String zipCode;
    public String getZipCode(){
        return zipCode;
    }
    public void setZipCode(){
        this.zipCode = zipCode;
    }
}
 
// Create an address book with two entries
 
AddressBook book = new AddressBook();
Address addr1 = new Address();
add1.setZipCode("90210");
Address addr2 = new Address();
add2.setZipCode("20191");
book.getAddresses().add(addr1);
book.getAddresses().add(addr2);
// Create a Jex context 
Context context = new Context();
 
 |  | 
               
                |  | Example 1: Interpreting an 
                  Expression | 
               
                |  |  
                    In the following example, we invoke an interpreter 
                      to process a Bexl expression: 
                       
                        | 
context.setExpressionLanguage("bexl");
            
String zipCode = (String)context.
    evaluate("addresses[1].zipCode", new Object[]{book});
 |  | 
               
                |  | Example 2: Interpreting 
                  an Expression, Multilingual Mode | 
               
                |  |  
                    Here we are using the multilingual capabilities 
                      of Jex: 
                       
                        | // Use Bexl
String zipCode = (String)context.
    evaluate("bexl:addresses[1].zipCode", new Object[]{book});
// Same with JXPath
zipCode = (String)context.
    evaluate("jxpath:addresses[2]/zipCode", new Object[]{book});
 |  | 
               
                |  | Example 3: Compiling 
                  an Expression | 
               
                |  |  
                    Here we use the compiler and cache the compiled 
                      expression: 
                       
                        | context.setExpressionLanguage("bexl");
Expression expr = context.getCompiler().
     compileExpression("addresses[1].zipCode");
...
// Later, when we need to compute the expression, 
// use the compiled form
String zipCode = (String)expr.evaluate(context, new Object[]{bean});
 |  | 
               
                |  | Example 4: Compiling 
                  an Expression, Multilingual Mode | 
               
                |  |  
                 
                    In this example, we compile an expression 
                      in the multilingual mode: 
                       
                        | Expression expr = context.getCompiler().
     compileExpression("bexl:addresses[1].zipCode");
...
String zipCode = (String)expr.evaluate(context, new Object[]{bean});
 |  | 
               
                |  | Example 5: Using 
                  an Iteration Expression | 
               
                |  |  
                    An iteration expression produces an Iterator. 
                       
                        | context.setExpressionLanguage("jxpath");
            
Iterator iter = context.iterate("addresses", new Object[]{book});
while (iter.hasNext()){
    Address address = (Address)iter.next();
    ...
}
 |  An iteration expression can also be used 
                      in both interpreted and compiled modes.
 | 
               
                |  | Example 6: Using 
                  a Variable Expression | 
               
                |  |  
                    A variable expression is used to modify 
                      a value: 
                       
                        |            
context.assign("jxpath:addresses[1].zipCode", 
               "22190", new Object[]{book});
 |  | 
               
                |  | Example 7: Using 
                  a Variable | 
               
                |  |  
                    
                    The notion of a variable is common for many 
                      expression languages. With Jex they all share the same pool 
                      of variables. 
                       
                        | // Set a variable first
context.getVariables().declareVariable("i", new Integer(2));
 
// Now we can use the variable
String zipCode = (String)context.
    evaluate("jxpath:addresses[$i]/zipCode", new Object[]{book});
 
// Same with JavaScript
zipCode = (String)context.
    evaluate("javascript:addresses[i].zipCode", new Object[]{book});
 |  | 
               
                |  | Example 8: Declaring 
                  a JavaScript Variable | 
               
                |  |  
                    By default Jex requires that all variables 
                      be declared explicitly. However, if you are using JavaScript, 
                      you can configure Jex to allow automatic declaration of 
                      variables.  
                       
                        | // Allow automatic declaration of variables
context.setProperty("javascript.autodeclare", "true");
 
// Let's declare a new variable
context.assign("javascript:company", "PLOTNIX", null);
 |  | 
               
                |  |