精华帖 (1) :: 良好帖 (8) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-04-22
最后修改:2011-04-22
这是一个性能极致、扩展性良好的表达式解析引擎。图示http://code.alibabatech.com/wiki/download/attachments/1966084/simple_el.png?version=2&modificationDate=1302249958000 目前SimpleEL有三种实现,缺省实现,TinyEL,QL,其中TinyEL在下一个版本中将会替换为缺省实现,QL是一种类SQL的表达式语言,它试图创造一种对象查询语言。 Slider : http://code.alibabatech.com/svn/SimpleEL/trunk/doc/SimpleEL.pptx SVN:http://code.alibabatech.com/svn/simpleel JIRA:http://code.alibabatech.com/jira/browse/simpleel WIKI:http://code.alibabatech.com/wiki/display/simpleel/Home Download: http://code.alibabatech.com/wiki/display/SimpleEL/Download Maven Repository: <repository> <id>opensesame</id> <name>Alibaba OpenSource Repsoitory</name> <url>http://code.alibabatech.com/mvn/releases/</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <dependency> <groupId>com.alibaba</groupId> <artifactId>SimpleEL</artifactId> <version>0.1</version> </dependency> import com.alibaba.simpleEL.eval.DefaultExpressEvalService; import com.alibaba.simpleEL.preprocess.DefaultVariantResolver.Type; DefaultExpressEvalService service = new DefaultExpressEvalService(); service.regsiterVariant(int.class, "a", "b"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(7, service.eval(ctx, "@a + @b")); DefaultExpressEvalService service = new DefaultExpressEvalService(); service.regsiterVariant(int.class, "a", "b"); service.setAllowMultiStatement(true); //support multi-statement Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(1, service.eval(ctx, "if (@a > @b) { return @a - @b; } else {return @b - @a; }")); TinyEL是SimpleEL中的一种实现,和SimpleEL的缺省实现不同的是,它的预处理不是简单的替换变量,而是经过语法分析之后生成Java Source。变量名称不需要使用@标识。 TinyEL在下一个版本中,可能会升级为SimpleEL的缺省实现。 使用示例: 调用方法 import com.alibaba.simpleEL.dialect.tiny.TinyELEvalService; TinyELEvalService service = new TinyELEvalService(); service.regsiterVariant(String.class, "name"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("name", "abc"); Assert.assertEquals(5, service.eval(ctx, "('aa' + name).length()")); * 调用静态方法 TinyELEvalService service = new TinyELEvalService(); service.regsiterVariant(int.class, "a", "b"); //注册a和b两个变量为int类型 Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(4, service.eval(ctx, "java.lang.Math.max(a, b)")); * 构造对象 TinyELEvalService service = new TinyELEvalService(); service.regsiterVariant(long.class, "millis"); long millis = System.currentTimeMillis(); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("millis", millis); Assert.assertEquals(new java.util.Date(millis), service.eval(ctx, "new java.util.Date(millis)")); * 三元表达式 TinyELEvalService service = new TinyELEvalService(); service.regsiterVariant(int.class, "a", "b"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(4, service.eval(ctx, "a > b ? a : b")); Assert.assertEquals(true, service.eval(ctx, "a instanceof Number")); * 数组访问 TinyELEvalService service = new TinyELEvalService(); service.regsiterVariant(int.class, "a", "b"); service.regsiterVariant(int[].class, "c"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); ctx.put("c", new int[] { 1, 2 }); Assert.assertEquals(4, service.eval(ctx, "Math.max(c[0], c[1]) + 2")); * 注册函数 TinyELEvalService service = new TinyELEvalService(); service.regsiterVariant(int.class, "a", "b"); service.registerFunction("max", Math.class.getMethod("max", new Class<?>[] { int.class, int.class })); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(7, service.eval(ctx, "a + b")); Assert.assertEquals(true, service.eval(ctx, "a < b")); Assert.assertEquals(4, service.eval(ctx, "max(a, b)")); * 各种运算符 TinyELEvalService service = new TinyELEvalService(); service.regsiterVariant(int.class, "a", "b"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(3, service.eval(ctx, "a++")); Assert.assertEquals(4, ctx.get("a")); Assert.assertEquals(5, service.eval(ctx, "++a")); Assert.assertEquals(5, ctx.get("a")); Assert.assertEquals(4, service.eval(ctx, "--a")); Assert.assertEquals(4, ctx.get("a")); Assert.assertEquals(true, service.eval(ctx, "a > b || b > a || a == b")); Assert.assertEquals(false, service.eval(ctx, "a > b && b > a && a == b")); Assert.assertEquals(false, service.eval(ctx, "a != b")); * 使用if语句 TinyELEvalService service = new TinyELEvalService(); service.setAllowMultiStatement(true); service.regsiterVariant(int.class, "a", "b"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(1, service.eval(ctx, "if (a > b) { return a - b; } else {return b - a; }")); * 声明本地变量 TinyELEvalService service = new TinyELEvalService(); service.setAllowMultiStatement(true); service.regsiterVariant(int.class, "a", "b"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(70, service.eval(ctx, "int i = 10; return a * i + b * i;")); * 使用While TinyELEvalService service = new TinyELEvalService(); service.setAllowMultiStatement(true); service.regsiterVariant(int.class, "a", "b"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(48, service.eval(ctx, "int i = 0; while (i < 10) { a += i++; } return a;")); Assert.assertEquals(48, ctx.get("a")); Assert.assertEquals(4, ctx.get("b")); * 使用For TinyELEvalService service = new TinyELEvalService(); service.setAllowMultiStatement(true); service.regsiterVariant(int.class, "a", "b"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", 3); ctx.put("b", 4); Assert.assertEquals(52, service.eval(ctx, "for (int i = 0; i < 10; ++i) { a += i; } return a + b;")); Assert.assertEquals(48, ctx.get("a")); Assert.assertEquals(4, ctx.get("b")); * 使用ForEach TinyELEvalService service = new TinyELEvalService(); service.setAllowMultiStatement(true); service.regsiterVariant(int[].class, "a"); Map<String, Object> ctx = new HashMap<String, Object>(); ctx.put("a", new int[] {1, 2, 3, 4, 5}); Assert.assertEquals(15, service.eval(ctx, "int sum = 0; for (int i : a) { sum += i; } return sum;")); 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-04-22
QL是SimpleEL中的一种实现,其语法类似于SQL,目标是创造一种对象查询语言。QL的实现目前正在开发中,还不够完善。
public static class Person { private int age; private String name; public Person(int age, String name) { this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age;} public String getName() {return name;} public void setName(String name) {this.name = name;} } public void test_0 () throws Exception { QLEvalService service = new QLEvalService(); List<Person> srcCollection = new ArrayList<Person>(); srcCollection.add(new Person(18, "吴能")); srcCollection.add(new Person(27, "刘芒")); srcCollection.add(new Person(40, "黄警")); srcCollection.add(new Person(50, "夏留")); srcCollection.add(new Person(60, "刘晶")); srcCollection.add(new Person(33, "石榴姐")); srcCollection.add(new Person(90, "松下太郎")); List<Person> destCollection = new ArrayList<Person>(); Map<String, Object> context = new HashMap<String, Object>(); context.put("min", 30); context.put("max", 70); service.select(Person.class, srcCollection, destCollection, "WHERE age >= @min AND age <= @max ORDER BY age desc LIMIT 1, 2", context); Assert.assertEquals(2, destCollection.size()); Assert.assertEquals("夏留", destCollection.get(0).getName()); Assert.assertEquals("黄警", destCollection.get(1).getName()); } |
|
返回顶楼 | |
发表时间:2011-04-22
阿里受益于开源领域,现在开始对开源做出贡献。愿国内的互联网软件公司都愿意这样做。
|
|
返回顶楼 | |
发表时间:2011-04-22
支持开源,功能越来越强大了,现在支不支持在脚本中定义class呢?
|
|
返回顶楼 | |
发表时间:2011-04-22
有点意思,和以前玩过的一个开源beanshell很像,抽空做个测试玩玩。
|
|
返回顶楼 | |
发表时间:2011-04-22
温绍锦 ?
|
|
返回顶楼 | |
发表时间:2011-04-22
能不能把那个@去掉呢?
|
|
返回顶楼 | |
发表时间:2011-04-22
很好很强大,下下代码来慢慢学
|
|
返回顶楼 | |
发表时间:2011-04-22
freish 写道 能不能把那个@去掉呢?
TinyELEvalService的实现是不需要使用@的,看例子! |
|
返回顶楼 | |
发表时间:2011-04-23
温少,贴一下性能对比吧,EL解析的工具很多,估计大家对性能会比较感兴趣。
|
|
返回顶楼 | |