4

Does anyone have any simple JEXL examples using a loop. I am looking to iterate around a simple object arraylist to output various string values?

user1816880
  • 49
  • 1
  • 1
  • 2

4 Answers4

6

A full example with input for 452' is here :

public static void testSimpleList() {

        List<String> list = new ArrayList<String>();
        list.add("one");
        list.add("two");


        JexlContext jexlContext = new MapContext();
        jexlContext.set("list", list);;

        Map<String, Object> functions1 = new HashMap<String, Object>();
        functions1.put("system", System.out);


        JexlEngine jexl = new JexlEngine();
        jexl.setFunctions(functions1);
        Expression expression = jexl.createExpression("for(item : list) { system:println(item) }");


        expression.evaluate(jexlContext);


    }

Output :

one
two
3

Looks like it requires one to use script instead of expression.

This fails with error "parsing error in 'for'"

e = new org.apache.commons.jexl3.JexlBuilder().create();
c = new org.apache.commons.jexl3.MapContext();
c.set("a", Arrays.asList(1,2,3));
e.createExpression("for(x : a) { b=x }").evaluate(c)

This, however, works

e.createScript("for(x : a) { b=x }").evaluate(c)
mvmn
  • 3,717
  • 27
  • 30
2

Loop through items of an Array, Collection, Map, Iterator or Enumeration, e.g.

for(item : list) {
    x = x + item; 
}

Where item and list are variables. The JEXL 1.1 syntax using foreach(item in list) is now deprecated.

http://commons.apache.org/proper/commons-jexl/reference/syntax.html

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.jexl2.Expression;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.JexlEngine;
import org.apache.commons.jexl2.MapContext;

public class Main {

    public static void main(String[] args) {
        JexlContext jexlContext = new MapContext();
        Map<String, Object> functions = new HashMap<String, Object>();
        functions.put("system", System.out);
        JexlEngine jexl = new JexlEngine();
        jexl.setFunctions(functions);
        Expression expression = jexl.createExpression("for(item : list) { system:println(item) }");
        expression.evaluate(jexlContext);
    }

}

pom.xml

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-jexl</artifactId>
    <version>2.1.1</version>
</dependency>
452
  • 396
  • 4
  • 9
  • 24
0

First and foremost thing, you should use Script evaluator, instead of Expression evaluator. Expression evaluators do not support complex looping syntax. Refer here

JexlScript

These allow you to use multiple statements and you can use variable assignments, loops, calculations, etc. More or less what can be achieved in Shell or JavaScript at its basic level. The result from the last command is returned from the script.

JxltEngine.Expression

These are ideal to produce "one-liner" text, like a 'toString()' on steroids. To get a calculation you use the EL-like syntax as in ${someVariable}. The expression that goes between the brackets behaves like a JexlScript, not an expression. You can use semi-colons to execute multiple commands and the result from the last command is returned from the script. You also have the ability to use a 2-pass evaluation using the #{someScript} syntax.

Try this instead,

JexlScript jexlExpression = jexl.createScript("var x='';for(item:[1,2,3]){ x=x+item;}");

jexlExpression.evaluate(jexlContext);

Once this will work for you, you can use your own Array as well.

Pratik
  • 908
  • 2
  • 11
  • 34