Skip to content

Commit

Permalink
update ExpressionUtil utils
Browse files Browse the repository at this point in the history
  • Loading branch information
weihubeats committed Sep 14, 2024
1 parent 3166db3 commit 2fa10e8
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.nebula.web.common.utils;

import com.nebula.base.utils.DataUtils;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Map;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
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;
Expand All @@ -31,35 +32,127 @@
* @description:
*/
public class ExpressionUtil {


private static final ExpressionParser parser = new SpelExpressionParser();

private static final LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();

/**
* el表达式解析
* 解析EL表达式
*
* @param expressionString 解析值
* @param expressionString 表达式字符串
* @param method 方法
* @param args 参数
* @return
* @return 解析结果
*/
public static Object parse(String expressionString, Method method, Object[] args) {
if (DataUtils.isEmpty(expressionString)) {
if (isEmpty(expressionString)) {
return null;
}
// 获取被拦截方法参数名列表
LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
String[] paramNameArr = discoverer.getParameterNames(method);
// SPEL解析
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < Objects.requireNonNull(paramNameArr).length; i++) {
context.setVariable(paramNameArr[i], args[i]);
EvaluationContext context = createEvaluationContext(method, args);
return parseExpression(expressionString, context);
}

/**
* 解析EL表达式
*
* @param expressionString 表达式字符串
* @param rootObject 根对象
* @return 解析结果
*/
public static Object parse(String expressionString, Object rootObject) {
if (isEmpty(expressionString)) {
return null;
}
return parser.parseExpression(expressionString).getValue(context);
return parseExpression(expressionString, rootObject);
}


/**
* 解析EL表达式
*
* @param expressionString 表达式字符串
* @param variables 变量Map
* @return 解析结果
*/
public static Object parse(String expressionString, Map<String, Object> variables) {
if (isEmpty(expressionString)) {
return null;
}
EvaluationContext context = createEvaluationContext(variables);
return parseExpression(expressionString, context);
}

/**
* 判断是否为EL表达式
*
* @param param 待判断的字符串
* @return 是否为EL表达式
*/
public static boolean isEl(String param) {
if (DataUtils.isEmpty(param)) {
return false;
return !isEmpty(param) && param.startsWith("#");
}

/**
* 创建EvaluationContext
*
* @param method 方法
* @param args 参数
* @return EvaluationContext
*/
private static EvaluationContext createEvaluationContext(Method method, Object[] args) {
String[] paramNames = discoverer.getParameterNames(method);
EvaluationContext context = new StandardEvaluationContext();
if (paramNames != null) {
for (int i = 0; i < paramNames.length; i++) {
context.setVariable(paramNames[i], args[i]);
}
}
return Objects.equals(param.substring(0, 1), "#");
return context;
}

/**
* 创建EvaluationContext
*
* @param variables 变量Map
* @return EvaluationContext
*/
private static EvaluationContext createEvaluationContext(Map<String, Object> variables) {
EvaluationContext context = new StandardEvaluationContext();
variables.forEach(context::setVariable);
return context;
}

/**
* 解析表达式
*
* @param expressionString 表达式字符串
* @param context EvaluationContext
* @return 解析结果
*/
private static Object parseExpression(String expressionString, EvaluationContext context) {
Expression expression = parser.parseExpression(expressionString);
return expression.getValue(context);
}

/**
* 解析表达式
*
* @param expressionString 表达式字符串
* @param rootObject 根对象
* @return 解析结果
*/
private static Object parseExpression(String expressionString, Object rootObject) {
Expression expression = parser.parseExpression(expressionString);
return expression.getValue(rootObject);
}

/**
* 判断字符串是否为空
*
* @param str 待判断的字符串
* @return 是否为空
*/
private static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.nebula.web.common.utils;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.expression.spel.SpelParseException;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
* @author : wh
* @date : 2024/9/13 16:19
* @description:
*/
public class ExpressionUtilTest {

@Test
void testParseWithMethodAndArgs() throws NoSuchMethodException {
Method method = TestClass.class.getDeclaredMethod("testMethod", String.class, int.class);
Object[] args = {"Hello", 5};

assertEquals("Hello", ExpressionUtil.parse("#param1", method, args));
assertEquals(5, ExpressionUtil.parse("#param2", method, args));
assertEquals("Hello5", ExpressionUtil.parse("#param1 + #param2", method, args));
}

@Test
void testParseWithRootObject() {
TestClass testObj = new TestClass("World", 10);

assertEquals("World", ExpressionUtil.parse("name", testObj));
assertEquals(10, ExpressionUtil.parse("age", testObj));
assertEquals("World is 10 years old", ExpressionUtil.parse("name + ' is ' + age + ' years old'", testObj));
}

@Test
void testParseWithVariables() {
Map<String, Object> variables = new HashMap<>();
variables.put("x", 10);
variables.put("y", 20);

assertEquals(30, ExpressionUtil.parse("#x + #y", variables));
assertEquals(200, ExpressionUtil.parse("#x * #y", variables));
}

@Test
void testIsEl() {
assertTrue(ExpressionUtil.isEl("#expression"));
assertFalse(ExpressionUtil.isEl("normalString"));
assertFalse(ExpressionUtil.isEl(""));
assertFalse(ExpressionUtil.isEl(null));
}

@Test
void testParseWithInvalidExpression() {
assertThrows(SpelParseException.class, () -> ExpressionUtil.parse("invalid#expression", new Object()));
}

@Test
void testParseWithEmptyExpression() {
assertNull(ExpressionUtil.parse("", new Object()));
assertNull(ExpressionUtil.parse(null, new Object()));
}

// 用于测试的内部类
private static class TestClass {
private String name;
private int age;

public TestClass(String name, int age) {
this.name = name;
this.age = age;
}

public void testMethod(String param1, int param2) {
// 方法体为空,仅用于测试
}

// Getters and setters
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

}

0 comments on commit 2fa10e8

Please sign in to comment.