java 自定义表达式_Java中使用Groovy实现自定义表达式解析

Groovy作为一种JVM-Based语言,目前普及程度正在提高。本文演示一下在Java类中,通过继承GDK的groovy.lang.Script类如何支持自定义表达式解析功能。

输入:

表示一行数据的某个map结构。在实际应用中,产生这种结构的最常见场景可能是通过JDBC访问数据库、通过调用WebService服务得到的某行结果集等。

目标设定:

假设我们希望对输入数据进行某个运算。此处示例中,我们模拟oracle中最常用的nvl函数。

处理过程:

首先,通过继承groovy.lang.Script,定义自己的表达式解析类:

public class MyBasicScript extends Script

在该类中实现具体的解析方法:

public static Object nvl(Object str,Object val){

return str==null ||"".equals(str)?val:str;

}

其次,基于上述自定义类,实例化一个CompilerConfiguration对象。

CompilerConfiguration cfg = new CompilerConfiguration();

cfg.setScriptBaseClass(MyBasicScript.class.getName());

以此CompilerConfiguration实例为参数,实例化一个GroovyShell对象

shell = new GroovyShell(cfg);

通过shell对象,解析并运行表达式。在运行前,可以通过bingding对象绑定脚本运行时的上下文数据:

Binding binding = new Binding(map);

Script script = shell.parse(expr);

script.setBinding(binding);

script.run();

附完整的代码示例(共两个类,分别是自定义脚本实现类、调用及测试类)

package jg.groovy;

import groovy.lang.Script;

import java.lang.reflect.Method;

public class MyBasicScript extends Script {

@Override

public Object run() {

//show usage

Method[] methods = MyBasicScript.class.getDeclaredMethods();

StringBuilder sb=new StringBuilder();

for (Method method : methods) {

sb.append(method);

}

return sb.substring(0, sb.length()-1);

}

public static Object nvl(Object str, Object val) {

return str == null || "".equals(str) ? val : str;

}

}

package jg.groovy;

import groovy.lang.Binding;

import groovy.lang.GroovyShell;

import groovy.lang.Script;

import java.util.HashMap;

import java.util.Hashtable;

import java.util.Map;

import org.codehaus.groovy.control.CompilerConfiguration;

public class ExprSupport {

private static final Object lock = new Object();

private static final GroovyShell shell;

private static Hashtable cache = new Hashtable();

static {

CompilerConfiguration cfg = new CompilerConfiguration();

cfg.setScriptBaseClass(MyBasicScript.class.getName());

shell = new GroovyShell(cfg);

}

public static Object parseExpr(String expr) {

Script s = getScriptFromCache(expr);

return s.run();

}

public static Object parseExpr(String expr, Map, ?> map) {

Binding binding = new Binding(map);

Script script = getScriptFromCache(expr);

script.setBinding(binding);

return script.run();

}

private static Script getScriptFromCache(String expr) {

if (cache.contains(expr)) {

return cache.get(expr);

}

synchronized (lock) {

if (cache.contains(expr)) {

return cache.get(expr);

}

Script script = shell.parse(expr);

cache.put(expr, script);

return script;

}

}

/**

* @param args

*/

public static void main(String[] args) {

// eg. get one row from db

Map row = new HashMap();

row.put("id", 42);

row.put("name", "");

//带绑定数据参数的调用方式

System.out.println(ExprSupport.parseExpr("nvl(id,0)", row));

System.out.println(ExprSupport.parseExpr("nvl(name,‘anonymous‘)", row));

//不带绑定数据参数的调用方式,这个是groovy的内置能力

System.out.println(ExprSupport.parseExpr("1+2"));

}

}

输出:

42

anonymous

3

总结:结合groovy对表达式的内置支持能力与自定义脚本能力,可以实现功能强大的表达式解析能力。

原文:http://www.cnblogs.com/ora11g/p/4473544.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值