OGNL / JEXL

OGNL: http://www.ognl.org/ ( syntax )
JEXL: http://jakarta.apache.org/commons/jexl/ ( syntax )


書いておかないとすぐ忘れるのでメモ。
Wrapperこさえる場合には、OGNLには context の変数マップだけじゃなく、root objectという概念もあるので、そこら辺の扱いが課題。変数マップをroot objectとしてしまうと、変数の最初に '#' つけなくても良くなり、JEXLとパッと見の見た目は近くなるが。。


つか、夕方くらいからずっと Jakartaのサイト からJEXLのソースやらが 403 Forbidden で落とせなくなってるんだけど、何かあったのかな? jarファイル単体が ここ から落とせるのでとりあえず動作させることはできる。

code sample

import java.util.*;
import ognl.*;
import org.apache.commons.jexl.*;

public class ELTest
{
  public static void main(String[] args) throws Exception
  {
    // OGNL: root object
    {
      System.out.println("[!]OGNL - root object");
      Map values = createValues();
      ognl("string", values);
      ognl("array[1]", values);
      ognl("map['string']", values);
      ognl("bean.name", values);
      
      ognl("map.size()", values);
      ognl("map.put('aaa',string)", values);
      ognl("map", values);
    }

    // OGNL: context values
    {
      System.out.println("[!]OGNL - context values");
      Map values = createValues();
      ognl("#string", values);
      ognl("#array[1]", values);
      ognl("#map['string']", values);
      ognl("#bean.name", values);
      
      ognl("#map.size()", values);
      ognl("#map.put('aaa',#string)", values);
      ognl("#map", values);
    }

    // JEXL: context values
    {
      System.out.println("[!]JEXL - context values");
      Map values = createValues();
      jexl("string", values);
      jexl("array[1]", values);
      jexl("map['string']", values);
      jexl("bean.name", values);
      
      jexl("map.size()", values);
      jexl("map.put('aaa',string)", values);
      jexl("map", values);
    }
  }
  public static void ognl(String expr, Map values) throws OgnlException
  {
    Object expression = Ognl.parseExpression(expr);
    OgnlContext context = new OgnlContext(values);
    // value is root object
    System.out.println( Ognl.getValue(expression, context, values) );
  }
  public static void jexl(String expr, Map values) throws Exception
  {
    Expression expression = ExpressionFactory.createExpression(expr);
    JexlContext context = JexlHelper.createContext();
    context.setVars(values);
    System.out.println( expression.evaluate(context) );
  }

  public static Map createValues()
  {
    Map values = new HashMap();
    values.put("string", "value-string");
    values.put("array", new String[]{ "aa", "bb", "cc"});
    values.put("map", values );
    values.put("bean", new TestBean());
    return values;
  }
  public static class TestBean
  {
    private int id = 99;
    private String name = "hoge";
    
    public int getId(){ return id; }
    public void setId(int id){ this.id = id; }
    public String getName(){ return name; }
    public void setName(String name){ this.name = name; }
  }
}

実行結果

[!]OGNL - root object
value-string
bb
value-string
hoge
4
null
{string=value-string, aaa=value-string, map=(this Map), bean=ELTest$TestBean@8a0d5d, array=[Ljava.lang.String;@173831b}
[!]OGNL - context values
value-string
bb
value-string
hoge
4
null
{string=value-string, aaa=value-string, map=(this Map), bean=ELTest$TestBean@a470b8, array=[Ljava.lang.String;@1e4457d}
[!]JEXL - context values
value-string
bb
value-string
hoge
4
null
{string=value-string, aaa=value-string, map=(this Map), bean=ELTest$TestBean@1749757, array=[Ljava.lang.String;@17bd6a1}