mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-12 14:57:10 +08:00
feat(core): 新增表达式解析工具类
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.core.util.expression;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 表达式解析器
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class ExpressionEvaluator implements Function<Object, Object> {
|
||||
|
||||
private final Function<Object, Object> evaluator;
|
||||
|
||||
public ExpressionEvaluator(String script, Method defineMethod) {
|
||||
this.evaluator = new SpelEvaluator(script, defineMethod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(Object rootObject) {
|
||||
return evaluator.apply(rootObject);
|
||||
}
|
||||
|
||||
Function<Object, Object> getEvaluator() {
|
||||
return evaluator;
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.core.util.expression;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 表达式上下文
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class ExpressionInvokeContext {
|
||||
|
||||
/**
|
||||
* 目标方法
|
||||
*/
|
||||
private Method method;
|
||||
|
||||
/**
|
||||
* 方法参数
|
||||
*/
|
||||
private Object[] args;
|
||||
|
||||
/**
|
||||
* 目标对象
|
||||
*/
|
||||
private Object target;
|
||||
|
||||
public ExpressionInvokeContext(Method method, Object[] args, Object target) {
|
||||
this.method = method;
|
||||
this.args = args;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(Method method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public void setArgs(Object[] args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public Object[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(Object target) {
|
||||
this.target = target;
|
||||
}
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.core.util.expression;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 表达式解析工具类
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class ExpressionUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ExpressionUtils.class);
|
||||
|
||||
private ExpressionUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析
|
||||
*
|
||||
* @param script 表达式
|
||||
* @param target 目标对象
|
||||
* @param method 目标方法
|
||||
* @param args 方法参数
|
||||
* @return 解析结果
|
||||
*/
|
||||
public static Object eval(String script, Object target, Method method, Object... args) {
|
||||
try {
|
||||
if (CharSequenceUtil.isBlank(script)) {
|
||||
return null;
|
||||
}
|
||||
ExpressionEvaluator expressionEvaluator = new ExpressionEvaluator(script, method);
|
||||
ExpressionInvokeContext invokeContext = new ExpressionInvokeContext(method, args, target);
|
||||
return expressionEvaluator.apply(invokeContext);
|
||||
} catch (Exception e) {
|
||||
log.error("Error occurs when eval script \"{}\" in {} : {}", script, method, e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.core.util.expression;
|
||||
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Spring EL 表达式解析器
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class SpelEvaluator implements Function<Object, Object> {
|
||||
|
||||
private static final ExpressionParser PARSER;
|
||||
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER;
|
||||
|
||||
static {
|
||||
PARSER = new SpelExpressionParser();
|
||||
PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
|
||||
}
|
||||
|
||||
private final Expression expression;
|
||||
private String[] parameterNames;
|
||||
|
||||
public SpelEvaluator(String script, Method defineMethod) {
|
||||
expression = PARSER.parseExpression(script);
|
||||
if (defineMethod.getParameterCount() > 0) {
|
||||
parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(defineMethod);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object apply(Object rootObject) {
|
||||
EvaluationContext context = new StandardEvaluationContext(rootObject);
|
||||
ExpressionInvokeContext invokeContext = (ExpressionInvokeContext)rootObject;
|
||||
if (parameterNames != null) {
|
||||
for (int i = 0; i < parameterNames.length; i++) {
|
||||
context.setVariable(parameterNames[i], invokeContext.getArgs()[i]);
|
||||
}
|
||||
}
|
||||
return expression.getValue(context);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user