ひがやすを技術ブログ

電通国際情報サービスのプログラマ

式言語を気軽に使おう

Javaの開発者にとって、式言語として最も身近なのは、JSPのELでしょう。

${aaa}

みたいにして、JSPの中に埋め込んでいる式のことです。上記の場合、aaaは変数になります。このELをプログラムの中から自由に呼び出せるといろんなことができるようになりますよね。


commons-elを使うとELを簡単に呼び出せるようになります。
キーとなるクラスは、ELParser。ELParser#ExpressionString(String expression)を呼び出すことにより、文字列をコンパイルします。
コンパイルした結果は、${}で囲まれている場合Expression型、そうでないばあいにはStringがそのまま返されます。


Expressionで重要なのは、Expression#evaluate(VariableResolver, FunctionMapper, Logger)のメソッド。VariableResolverを使って、式の中の変数を解決します。JSPのファンクションを解決するのが、FunctionMapperです。JSPのファンクションといっても実態は、public staticな任意のメソッドを呼び出すことができます。


http://svn.slim3.org/browse/trunk/slim3/slim3-commons/src/main/java/org/slim3/commons/el/Slim3のEL実装があります。Mavenをお使いの方は、slim3-commonsのpom.xmlが参考になるでしょう。
それでは、S3VariableResolverを使ってみましょう。S3VariableResolverのコンストラクタの引数は、変数名と値を関連付けるMapです。

ELParser parser = new ELParser(new StringReader("${aaa}"));
Object exp = parser.ExpressionString();
Map<String, Object> map = new HashMap<String, Object>();
map.put("aaa", "111");
System.out.println(((Expression) exp).evaluate(new S3VariableResolver(map), null, null);

の結果は、111と表示されます。


FunctionMapperの使い方はこんな感じ。

public static int add(int arg1, int arg2) {
    return arg1 + arg2;
}

public void testEvaluateFunction() throws Exception {
    S3FunctionMapper functionMapper = new S3FunctionMapper();
    Method function = getClass().getDeclaredMethod("add", int.class, int.class);
    functionMapper.addFunction("f", "add", function);
    ELParser parser = new ELParser(new StringReader("${f:add(1,2)}"));
    Expression exp = (Expression) parser.EvaluateString();
    assertEquals(3, exp.evaluate(null, functionMapper, null));
}

S3FunctionMapper#addFunction()の最初の引数はprefix、二番目の引数はlocalNameです。ここで登録したメソッドを${prefix:localName(...)}のような感じで呼び出します。


ねっ、簡単でしょ。