add ExpressionUtil

This commit is contained in:
Looly
2020-11-10 14:36:45 +08:00
parent 7817599cb6
commit 09d00f9fdf
22 changed files with 532 additions and 3 deletions

View File

@@ -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<String, Object> context);
}

View File

@@ -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);
}
}

View File

@@ -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<String, Object> context) {
return getEngine().eval(expression, context);
}
}

View File

@@ -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自动创建对应的拼音引擎对象<br>
* 推荐创建的引擎单例使用,此方法每次调用会返回新的引擎
*
* @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自动创建对应的拼音引擎对象<br>
* 推荐创建的引擎单例使用,此方法每次调用会返回新的引擎
*
* @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 !");
}
}

View File

@@ -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引擎封装<br>
* 见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<String, Object> context) {
return engine.execute(expression, context);
}
/**
* 获取{@link AviatorEvaluatorInstance}
*
* @return {@link AviatorEvaluatorInstance}
*/
public AviatorEvaluatorInstance getEngine() {
return this.engine;
}
}

View File

@@ -0,0 +1,7 @@
/**
* Aviator引擎封装https://github.com/killme2008/aviatorscript
*
* @author looly
*
*/
package cn.hutool.extra.expression.engine.aviator;

View File

@@ -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引擎封装<br>
* 见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<String, Object> 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;
}
}

View File

@@ -0,0 +1,6 @@
/**
* Jexl3引擎封装,见https://github.com/apache/commons-jexl
*
* @author looly
*/
package cn.hutool.extra.expression.engine.jexl;

View File

@@ -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引擎封装<br>
* 见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<String, Object> context) {
return Expression.parse(expression).calculate(context);
}
}

View File

@@ -0,0 +1,7 @@
/**
* JfireEL引擎封装<br>
* 见https://gitee.com/eric_ds/jfireEL
*
* @author looly
*/
package cn.hutool.extra.expression.engine.jfireel;

View File

@@ -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)引擎封装<br>
* 见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<String, Object> context) {
return MVEL.eval(expression, context);
}
}

View File

@@ -0,0 +1,7 @@
/**
* MVEL (MVFLEX Expression Language)引擎封装<br>
* 见https://github.com/mvel/mvel
*
* @author looly
*/
package cn.hutool.extra.expression.engine.mvel;

View File

@@ -0,0 +1,7 @@
/**
* 表达式语言引擎封装
*
* @author looly
*
*/
package cn.hutool.extra.expression.engine;

View File

@@ -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引擎封装<br>
* 见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<String, Object> context) {
final EvaluationContext evaluationContext = new StandardEvaluationContext();
context.forEach(evaluationContext::setVariable);
return parser.parseExpression(expression).getValue(evaluationContext);
}
}

View File

@@ -0,0 +1,7 @@
/**
* Spring-Expression引擎封装<br>
* 见https://github.com/spring-projects/spring-framework/tree/master/spring-expression
*
* @author looly
*/
package cn.hutool.extra.expression.engine.spel;

View File

@@ -0,0 +1,7 @@
/**
* 表达式语言引擎封装
*
* @author looly
*
*/
package cn.hutool.extra.expression;

View File

@@ -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 !");
}
}

View File

@@ -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