mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-10-31 10:57:15 +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