From 09d00f9fdf999a7d7dd6c4936313a05de48591ea Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 10 Nov 2020 14:36:45 +0800 Subject: [PATCH] add ExpressionUtil --- CHANGELOG.md | 1 + hutool-extra/pom.xml | 35 ++++++++++ .../extra/expression/ExpressionEngine.java | 20 ++++++ .../extra/expression/ExpressionException.java | 33 +++++++++ .../extra/expression/ExpressionUtil.java | 34 +++++++++ .../expression/engine/ExpressionFactory.java | 54 ++++++++++++++ .../engine/aviator/AviatorEngine.java | 40 +++++++++++ .../engine/aviator/package-info.java | 7 ++ .../expression/engine/jexl/JexlEngine.java | 37 ++++++++++ .../expression/engine/jexl/package-info.java | 6 ++ .../engine/jfireel/JfireELEngine.java | 27 +++++++ .../engine/jfireel/package-info.java | 7 ++ .../expression/engine/mvel/MvelEngine.java | 27 +++++++ .../expression/engine/mvel/package-info.java | 7 ++ .../extra/expression/engine/package-info.java | 7 ++ .../expression/engine/spel/SpELEngine.java | 35 ++++++++++ .../expression/engine/spel/package-info.java | 7 ++ .../hutool/extra/expression/package-info.java | 7 ++ .../extra/pinyin/engine/PinyinFactory.java | 7 +- ...n.hutool.extra.expression.ExpressionEngine | 5 ++ .../hutool/extra/expression/AviatorTest.java | 62 ++++++++++++++++ .../extra/expression/ExpressionUtilTest.java | 70 +++++++++++++++++++ 22 files changed, 532 insertions(+), 3 deletions(-) create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionEngine.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionException.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/ExpressionUtil.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/ExpressionFactory.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/aviator/AviatorEngine.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/aviator/package-info.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jexl/JexlEngine.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jexl/package-info.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jfireel/JfireELEngine.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/jfireel/package-info.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/MvelEngine.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/mvel/package-info.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/package-info.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/SpELEngine.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/engine/spel/package-info.java create mode 100644 hutool-extra/src/main/java/cn/hutool/extra/expression/package-info.java create mode 100644 hutool-extra/src/main/resources/META-INF/services/cn.hutool.extra.expression.ExpressionEngine create mode 100644 hutool-extra/src/test/java/cn/hutool/extra/expression/AviatorTest.java create mode 100644 hutool-extra/src/test/java/cn/hutool/extra/expression/ExpressionUtilTest.java 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); + } +}