diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6dfc15dac..983da7d72 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@
* 【core 】 HexUtil增加format方法(issue#I245NF@Gitee)
* 【poi 】 ExcelWriter增加setCurrentRowToEnd方法(issue#I24A2R@Gitee)
* 【core 】 ExcelWriter增加setCurrentRowToEnd方法(issue#I24A2R@Gitee)
+* 【extra 】 增加表达式引擎封装(ExpressionUtil)(pr#1203@Github)
### Bug修复
* 【core 】 修复DateUtil.current使用System.nanoTime的问题(issue#1198@Github)
diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml
index 49c308cb6..9a55f12f1 100644
--- a/hutool-extra/pom.xml
+++ b/hutool-extra/pom.xml
@@ -277,5 +277,40 @@
1.2.3
test
+
+ com.googlecode.aviator
+ aviator
+ 5.1.4
+ compile
+ true
+
+
+ org.apache.commons
+ commons-jexl3
+ 3.1
+ compile
+ true
+
+
+ org.mvel
+ mvel2
+ 2.4.10.Final
+ compile
+ true
+
+
+ com.jfirer
+ jfireEl
+ 1.0
+ compile
+ true
+
+
+ org.springframework
+ spring-expression
+ 5.3.0
+ compile
+ true
+
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionEngine.java
new file mode 100644
index 000000000..d8b6a2caa
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionEngine.java
@@ -0,0 +1,20 @@
+package cn.hutool.extra.expression;
+
+import java.util.Map;
+
+/**
+ * 表达式引擎API接口,通过实现此接口,完成表达式的解析和执行
+ *
+ * @author looll,independenter
+ * @since 5.5.0
+ */
+public interface ExpressionEngine {
+
+ /**
+ * 执行表达式
+ * @param expression 表达式
+ * @param context 表达式上下文,用于存储表达式中所需的变量值等
+ * @return 执行结果
+ */
+ Object eval(String expression, Map context);
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionException.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionException.java
new file mode 100644
index 000000000..33f4b7252
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionException.java
@@ -0,0 +1,33 @@
+package cn.hutool.extra.expression;
+
+import cn.hutool.core.exceptions.ExceptionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 表达式语言异常
+ *
+ * @author Looly
+ */
+public class ExpressionException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public ExpressionException(Throwable e) {
+ super(ExceptionUtil.getMessage(e), e);
+ }
+
+ public ExpressionException(String message) {
+ super(message);
+ }
+
+ public ExpressionException(String messageTemplate, Object... params) {
+ super(StrUtil.format(messageTemplate, params));
+ }
+
+ public ExpressionException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+
+ public ExpressionException(Throwable throwable, String messageTemplate, Object... params) {
+ super(StrUtil.format(messageTemplate, params), throwable);
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionUtil.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionUtil.java
new file mode 100644
index 000000000..4574a4e20
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionUtil.java
@@ -0,0 +1,34 @@
+package cn.hutool.extra.expression;
+
+import cn.hutool.extra.expression.engine.ExpressionFactory;
+
+import java.util.Map;
+
+/**
+ * 表达式引擎工具类
+ *
+ * @author looly
+ * @since 5.5.0
+ */
+public class ExpressionUtil {
+
+ /**
+ * 获得全局单例的表达式引擎
+ *
+ * @return 全局单例的表达式引擎
+ */
+ public static ExpressionEngine getEngine() {
+ return ExpressionFactory.get();
+ }
+
+ /**
+ * 执行表达式
+ *
+ * @param expression 表达式
+ * @param context 表达式上下文,用于存储表达式中所需的变量值等
+ * @return 执行结果
+ */
+ public static Object eval(String expression, Map context) {
+ return getEngine().eval(expression, context);
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/ExpressionFactory.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/ExpressionFactory.java
new file mode 100644
index 000000000..5b45b8ae3
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/ExpressionFactory.java
@@ -0,0 +1,54 @@
+package cn.hutool.extra.expression.engine;
+
+import cn.hutool.core.lang.Singleton;
+import cn.hutool.core.util.ServiceLoaderUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.log.StaticLog;
+
+import cn.hutool.extra.expression.ExpressionEngine;
+import cn.hutool.extra.expression.ExpressionException;
+
+/**
+ * 表达式语言引擎工厂类,,用于根据用户引入的表达式jar,自动创建对应的引擎对象
+ *
+ * @since 5.5.0
+ * @author looly
+ */
+public class ExpressionFactory {
+
+ /**
+ * 获得单例的{@link ExpressionEngine}
+ *
+ * @return 单例的{@link ExpressionEngine}
+ */
+ public static ExpressionEngine get(){
+ return Singleton.get(ExpressionEngine.class.getName(), ExpressionFactory::create);
+ }
+
+ /**
+ * 根据用户引入的表达式引擎jar,自动创建对应的拼音引擎对象
+ * 推荐创建的引擎单例使用,此方法每次调用会返回新的引擎
+ *
+ * @return {@link ExpressionEngine}
+ */
+ public static ExpressionEngine create() {
+ final ExpressionEngine engine = doCreate();
+ StaticLog.debug("Use [{}] Engine As Default.", StrUtil.removeSuffix(engine.getClass().getSimpleName(), "Engine"));
+ return engine;
+ }
+
+ /**
+ * 根据用户引入的拼音引擎jar,自动创建对应的拼音引擎对象
+ * 推荐创建的引擎单例使用,此方法每次调用会返回新的引擎
+ *
+ * @return {@link ExpressionEngine}
+ */
+ private static ExpressionEngine doCreate() {
+ final ExpressionEngine engine = ServiceLoaderUtil.loadFirstAvailable(ExpressionEngine.class);
+ if(null != engine){
+ return engine;
+ }
+
+ throw new ExpressionException("No expression jar found ! Please add one of it to your project !");
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/aviator/AviatorEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/aviator/AviatorEngine.java
new file mode 100644
index 000000000..31c88b7e1
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/aviator/AviatorEngine.java
@@ -0,0 +1,40 @@
+package cn.hutool.extra.expression.engine.aviator;
+
+import cn.hutool.extra.expression.ExpressionEngine;
+import com.googlecode.aviator.AviatorEvaluator;
+import com.googlecode.aviator.AviatorEvaluatorInstance;
+
+import java.util.Map;
+
+/**
+ * Aviator引擎封装
+ * 见:https://github.com/killme2008/aviatorscript
+ *
+ * @author looly
+ * @since 5.5.0
+ */
+public class AviatorEngine implements ExpressionEngine {
+
+ private final AviatorEvaluatorInstance engine;
+
+ /**
+ * 构造
+ */
+ public AviatorEngine() {
+ engine = AviatorEvaluator.getInstance();
+ }
+
+ @Override
+ public Object eval(String expression, Map context) {
+ return engine.execute(expression, context);
+ }
+
+ /**
+ * 获取{@link AviatorEvaluatorInstance}
+ *
+ * @return {@link AviatorEvaluatorInstance}
+ */
+ public AviatorEvaluatorInstance getEngine() {
+ return this.engine;
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/aviator/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/aviator/package-info.java
new file mode 100644
index 000000000..366b6e797
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/aviator/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Aviator引擎封装,见:https://github.com/killme2008/aviatorscript
+ *
+ * @author looly
+ *
+ */
+package cn.hutool.extra.expression.engine.aviator;
\ No newline at end of file
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jexl/JexlEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jexl/JexlEngine.java
new file mode 100644
index 000000000..fb428cb94
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jexl/JexlEngine.java
@@ -0,0 +1,37 @@
+package cn.hutool.extra.expression.engine.jexl;
+
+import cn.hutool.extra.expression.ExpressionEngine;
+import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.MapContext;
+
+import java.util.Map;
+
+/**
+ * Jexl3引擎封装
+ * 见:https://github.com/apache/commons-jexl
+ *
+ * @since 5.5.0
+ * @author looly
+ */
+public class JexlEngine implements ExpressionEngine {
+
+ private final org.apache.commons.jexl3.JexlEngine engine;
+
+ public JexlEngine(){
+ engine = (new JexlBuilder()).cache(512).strict(true).silent(false).create();
+ }
+
+ @Override
+ public Object eval(String expression, Map context) {
+ return engine.createExpression(expression).evaluate(new MapContext(context));
+ }
+
+ /**
+ * 获取{@link org.apache.commons.jexl3.JexlEngine}
+ *
+ * @return {@link org.apache.commons.jexl3.JexlEngine}
+ */
+ public org.apache.commons.jexl3.JexlEngine getEngine() {
+ return this.engine;
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jexl/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jexl/package-info.java
new file mode 100644
index 000000000..173415620
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jexl/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Jexl3引擎封装,见:https://github.com/apache/commons-jexl
+ *
+ * @author looly
+ */
+package cn.hutool.extra.expression.engine.jexl;
\ No newline at end of file
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jfireel/JfireELEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jfireel/JfireELEngine.java
new file mode 100644
index 000000000..8ae89f808
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jfireel/JfireELEngine.java
@@ -0,0 +1,27 @@
+package cn.hutool.extra.expression.engine.jfireel;
+
+import cn.hutool.extra.expression.ExpressionEngine;
+import com.jfirer.jfireel.expression.Expression;
+
+import java.util.Map;
+
+/**
+ * JfireEL引擎封装
+ * 见:https://gitee.com/eric_ds/jfireEL
+ *
+ * @since 5.5.0
+ * @author looly
+ */
+public class JfireELEngine implements ExpressionEngine {
+
+ /**
+ * 构造
+ */
+ public JfireELEngine(){
+ }
+
+ @Override
+ public Object eval(String expression, Map context) {
+ return Expression.parse(expression).calculate(context);
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jfireel/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jfireel/package-info.java
new file mode 100644
index 000000000..015597929
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jfireel/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * JfireEL引擎封装
+ * 见:https://gitee.com/eric_ds/jfireEL
+ *
+ * @author looly
+ */
+package cn.hutool.extra.expression.engine.jfireel;
\ No newline at end of file
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/MvelEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/MvelEngine.java
new file mode 100644
index 000000000..1a1f69881
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/MvelEngine.java
@@ -0,0 +1,27 @@
+package cn.hutool.extra.expression.engine.mvel;
+
+import cn.hutool.extra.expression.ExpressionEngine;
+import org.mvel2.MVEL;
+
+import java.util.Map;
+
+/**
+ * MVEL (MVFLEX Expression Language)引擎封装
+ * 见:https://github.com/mvel/mvel
+ *
+ * @since 5.5.0
+ * @author looly
+ */
+public class MvelEngine implements ExpressionEngine {
+
+ /**
+ * 构造
+ */
+ public MvelEngine(){
+ }
+
+ @Override
+ public Object eval(String expression, Map context) {
+ return MVEL.eval(expression, context);
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/package-info.java
new file mode 100644
index 000000000..9040ae64d
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * MVEL (MVFLEX Expression Language)引擎封装
+ * 见:https://github.com/mvel/mvel
+ *
+ * @author looly
+ */
+package cn.hutool.extra.expression.engine.mvel;
\ No newline at end of file
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/package-info.java
new file mode 100644
index 000000000..8e2d503d9
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 表达式语言引擎封装
+ *
+ * @author looly
+ *
+ */
+package cn.hutool.extra.expression.engine;
\ No newline at end of file
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/SpELEngine.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/SpELEngine.java
new file mode 100644
index 000000000..301f736bf
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/SpELEngine.java
@@ -0,0 +1,35 @@
+package cn.hutool.extra.expression.engine.spel;
+
+import cn.hutool.extra.expression.ExpressionEngine;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+
+import java.util.Map;
+
+/**
+ * Spring-Expression引擎封装
+ * 见:https://github.com/spring-projects/spring-framework/tree/master/spring-expression
+ *
+ * @since 5.5.0
+ * @author looly
+ */
+public class SpELEngine implements ExpressionEngine {
+
+ private final ExpressionParser parser;
+
+ /**
+ * 构造
+ */
+ public SpELEngine(){
+ parser = new SpelExpressionParser();
+ }
+
+ @Override
+ public Object eval(String expression, Map context) {
+ final EvaluationContext evaluationContext = new StandardEvaluationContext();
+ context.forEach(evaluationContext::setVariable);
+ return parser.parseExpression(expression).getValue(evaluationContext);
+ }
+}
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/package-info.java
new file mode 100644
index 000000000..b9b9bd9bb
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Spring-Expression引擎封装
+ * 见:https://github.com/spring-projects/spring-framework/tree/master/spring-expression
+ *
+ * @author looly
+ */
+package cn.hutool.extra.expression.engine.spel;
\ No newline at end of file
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/expression/package-info.java b/hutool-extra/src/main/java/cn/hutool/extra/expression/package-info.java
new file mode 100644
index 000000000..25e2198ce
--- /dev/null
+++ b/hutool-extra/src/main/java/cn/hutool/extra/expression/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 表达式语言引擎封装
+ *
+ * @author looly
+ *
+ */
+package cn.hutool.extra.expression;
\ No newline at end of file
diff --git a/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/PinyinFactory.java b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/PinyinFactory.java
index cef4a5fd0..ed94921ad 100644
--- a/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/PinyinFactory.java
+++ b/hutool-extra/src/main/java/cn/hutool/extra/pinyin/engine/PinyinFactory.java
@@ -3,10 +3,11 @@ package cn.hutool.extra.pinyin.engine;
import cn.hutool.core.lang.Singleton;
import cn.hutool.core.util.ServiceLoaderUtil;
import cn.hutool.core.util.StrUtil;
-import cn.hutool.extra.pinyin.PinyinEngine;
-import cn.hutool.extra.template.TemplateException;
import cn.hutool.log.StaticLog;
+import cn.hutool.extra.pinyin.PinyinEngine;
+import cn.hutool.extra.pinyin.PinyinException;
+
/**
* 简单拼音引擎工厂,用于根据用户引入的拼音库jar,自动创建对应的拼音引擎对象
*
@@ -47,6 +48,6 @@ public class PinyinFactory {
return engine;
}
- throw new TemplateException("No pinyin jar found ! Please add one of it to your project !");
+ throw new PinyinException("No pinyin jar found ! Please add one of it to your project !");
}
}
diff --git a/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.expression.ExpressionEngine b/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.expression.ExpressionEngine
new file mode 100644
index 000000000..98ae64b5b
--- /dev/null
+++ b/hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.expression.ExpressionEngine
@@ -0,0 +1,5 @@
+cn.hutool.extra.expression.engine.aviator.AviatorEngine
+cn.hutool.extra.expression.engine.jexl.JexlEngine
+cn.hutool.extra.expression.engine.mvel.MvelEngine
+cn.hutool.extra.expression.engine.jfireel.JfireELEngine
+cn.hutool.extra.expression.engine.spel.SpELEngine
\ No newline at end of file
diff --git a/hutool-extra/src/test/java/cn/hutool/extra/expression/AviatorTest.java b/hutool-extra/src/test/java/cn/hutool/extra/expression/AviatorTest.java
new file mode 100644
index 000000000..26dc2034a
--- /dev/null
+++ b/hutool-extra/src/test/java/cn/hutool/extra/expression/AviatorTest.java
@@ -0,0 +1,62 @@
+package cn.hutool.extra.expression;
+
+import cn.hutool.core.lang.Console;
+import cn.hutool.core.lang.Dict;
+import cn.hutool.extra.expression.engine.aviator.AviatorEngine;
+import lombok.Data;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Date;
+
+/**
+ * Aviator引擎单元测试,来自https://github.com/looly/hutool/pull/1203
+ */
+public class AviatorTest {
+
+ @Test
+ public void simpleTest(){
+ Foo foo = new Foo(100, 3.14f, new Date());
+ ExpressionEngine engine = new AviatorEngine();
+ String exp =
+ "\"[foo i=\"+ foo.i + \", f=\" + foo.f + \", date.year=\" + (foo.date.year+1900) + \", date.month=\" + foo.date.month + \", bars[0].name=\" + #foo.bars[0].name + \"]\"";
+ String result = (String) engine.eval(exp, Dict.create().set("foo", foo));
+ Assert.assertEquals("[foo i=100, f=3.14, date.year=2020, date.month=10, bars[0].name=bar]", result);
+
+ // Assignment.
+ exp = "#foo.bars[0].name='hello aviator' ; #foo.bars[0].name";
+ result = (String) engine.eval(exp, Dict.create().set("foo", foo));
+ Assert.assertEquals("hello aviator", result);
+ Assert.assertEquals("hello aviator", foo.bars[0].getName());
+
+ exp = "foo.bars[0] = nil ; foo.bars[0]";
+ result = (String) engine.eval(exp, Dict.create().set("foo", foo));
+ Console.log("Execute expression: " + exp);
+ Assert.assertNull(result);
+ Assert.assertNull(foo.bars[0]);
+ }
+
+ @Data
+ public static class Bar {
+ public Bar() {
+ this.name = "bar";
+ }
+ private String name;
+ }
+
+ @Data
+ public static class Foo {
+ int i;
+ float f;
+ Date date;
+ Bar[] bars = new Bar[1];
+
+ public Foo(final int i, final float f, final Date date) {
+ super();
+ this.i = i;
+ this.f = f;
+ this.date = date;
+ this.bars[0] = new Bar();
+ }
+ }
+}
diff --git a/hutool-extra/src/test/java/cn/hutool/extra/expression/ExpressionUtilTest.java b/hutool-extra/src/test/java/cn/hutool/extra/expression/ExpressionUtilTest.java
new file mode 100644
index 000000000..fe68ea7b8
--- /dev/null
+++ b/hutool-extra/src/test/java/cn/hutool/extra/expression/ExpressionUtilTest.java
@@ -0,0 +1,70 @@
+package cn.hutool.extra.expression;
+
+import cn.hutool.core.lang.Dict;
+import cn.hutool.extra.expression.engine.jexl.JexlEngine;
+import cn.hutool.extra.expression.engine.jfireel.JfireELEngine;
+import cn.hutool.extra.expression.engine.mvel.MvelEngine;
+import cn.hutool.extra.expression.engine.spel.SpELEngine;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ExpressionUtilTest {
+
+ @Test
+ public void evalTest(){
+ final Dict dict = Dict.create()
+ .set("a", 100.3)
+ .set("b", 45)
+ .set("c", -199.100);
+ final Object eval = ExpressionUtil.eval("a-(b-c)", dict);
+ Assert.assertEquals(-143.8, (double)eval, 2);
+ }
+
+ @Test
+ public void jexlTest(){
+ ExpressionEngine engine = new JexlEngine();
+
+ final Dict dict = Dict.create()
+ .set("a", 100.3)
+ .set("b", 45)
+ .set("c", -199.100);
+ final Object eval = engine.eval("a-(b-c)", dict);
+ Assert.assertEquals(-143.8, (double)eval, 2);
+ }
+
+ @Test
+ public void mvelTest(){
+ ExpressionEngine engine = new MvelEngine();
+
+ final Dict dict = Dict.create()
+ .set("a", 100.3)
+ .set("b", 45)
+ .set("c", -199.100);
+ final Object eval = engine.eval("a-(b-c)", dict);
+ Assert.assertEquals(-143.8, (double)eval, 2);
+ }
+
+ @Test
+ public void jfireELTest(){
+ ExpressionEngine engine = new JfireELEngine();
+
+ final Dict dict = Dict.create()
+ .set("a", 100.3)
+ .set("b", 45)
+ .set("c", -199.100);
+ final Object eval = engine.eval("a-(b-c)", dict);
+ Assert.assertEquals(-143.8, (double)eval, 2);
+ }
+
+ @Test
+ public void spELTest(){
+ ExpressionEngine engine = new SpELEngine();
+
+ final Dict dict = Dict.create()
+ .set("a", 100.3)
+ .set("b", 45)
+ .set("c", -199.100);
+ final Object eval = engine.eval("#a-(#b-#c)", dict);
+ Assert.assertEquals(-143.8, (double)eval, 2);
+ }
+}