Skip to content

Commit

Permalink
更新Fastjson到2.0.20,支持通过size()方法取数组类型长度
Browse files Browse the repository at this point in the history
  • Loading branch information
FanJiaRui committed Feb 2, 2023
1 parent a70391a commit daf696e
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 49 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.fanjr.simplify</groupId>
<artifactId>simplify-el</artifactId>
<version>1.0.3</version>
<version>1.0.4-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Simply Expression Language</name>
<description>
Expand Down Expand Up @@ -47,7 +47,7 @@
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.15</version>
<version>2.0.20</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
Expand All @@ -25,9 +26,18 @@ public class MethodNodeInvoker extends NodeInvoker {

private static final Map<String, Supplier<Method>> METHOD_POOL = new ConcurrentHashMap<>();

private static final Method ARRAY_LENGTH_METHOD;

static {
try {
ARRAY_LENGTH_METHOD = Array.class.getMethod("getLength", Object.class);
} catch (NoSuchMethodException e) {
throw new ElException("获取数组长度方法不存在!", e);
}
}

//用于获取方法参数的EL,返回结果必须是数组
private final ArrayInvoker parameterEl;

private final String methodName;

private MethodNodeInvoker(String nodeName, String methodName, ArrayInvoker parameterEl) {
Expand All @@ -40,10 +50,64 @@ public static MethodNodeInvoker newInstance(String nodeName, String methodName,
return new MethodNodeInvoker(nodeName, methodName, parameterEl);
}

@Override
Object getValueByParent(Object ctx, NodeHolder parentNode) {
if (null == parentNode) {
return null;
}
Object parentValue = parentNode.getValue();
if (null == parentValue) {
return null;
}

try {
Object[] parameters = parameterEl.invoke(ctx).toArray();
Class<?> type;
if (parentValue instanceof Class) {
type = (Class<?>) parentValue;
} else {
type = parentValue.getClass();
}
Method method = findMethod(type, methodName, parameters.length);
if (parameters.length == 0) {
if (ARRAY_LENGTH_METHOD == method) {
// 计算数组长度
return Array.getLength(parentValue);
} else {
return method.invoke(parentValue);
}
} else {
Type[] types = method.getGenericParameterTypes();
for (int i = 0; i < parameters.length; i++) {
parameters[i] = ElUtils.cast(parameters[i], types[i]);
}
return method.invoke(parentValue, parameters);
}
} catch (Exception e) {
throw new ElException(methodName + "执行失败!", e);
}
}

@Override
void removeValueByParent(NodeHolder parentNode, int index) {
// skip
logger.info("移除【{}】操作无效,无需移除!", this);
}

@Override
void setValueByParent(NodeHolder parentNode, Object value, int index) {
throw new ElException("不可对【" + this + "】方法执行结果重新赋值!");
}

private static Method findMethod(Class<?> type, String methodName, int argNum) {
String key = type.getName() + '#' + methodName + '@' + argNum;
return METHOD_POOL.computeIfAbsent(key, k -> {
try {
if (type.isArray() && "size".equals(methodName) && argNum == 0) {
// 特殊情况,支持size方法获取数组长度
return () -> ARRAY_LENGTH_METHOD;
}

if (0 == argNum) {
Method method = type.getMethod(methodName);
method.setAccessible(true);
Expand Down Expand Up @@ -94,48 +158,4 @@ private static Method findMethod(Class<?> type, String methodName, int argNum) {
}).get();
}

@Override
void setValueByParent(NodeHolder parentNode, Object value, int index) {
throw new ElException("不可对【" + this.toString() + "】方法执行结果重新赋值!");
}

@Override
Object getValueByParent(Object ctx, NodeHolder parentNode) {
if (null == parentNode) {
return null;
}
Object parentValue = parentNode.getValue();
if (null == parentValue) {
return null;
}

try {
Object[] parameters = parameterEl.invoke(ctx).toArray();
Class<?> type;
if (parentValue instanceof Class) {
type = (Class<?>) parentValue;
} else {
type = parentValue.getClass();
}
Method method = findMethod(type, methodName, parameters.length);
if (parameters.length == 0) {
return method.invoke(parentValue);
} else {
Type[] types = method.getGenericParameterTypes();
for (int i = 0; i < parameters.length; i++) {
parameters[i] = ElUtils.cast(parameters[i], types[i]);
}
return method.invoke(parentValue, parameters);
}
} catch (Exception e) {
throw new ElException(methodName + "执行失败!", e);
}
}

@Override
void removeValueByParent(NodeHolder parentNode, int index) {
// skip
logger.info("移除【{}】操作无效,无需移除!", this.toString());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private static Constructor<?> findConstructor(String className, int argNum) {

@Override
public void setValueByParent(NodeHolder parentNode, Object value, int index) {
throw new ElException("不可对【" + this.toString() + "】执行结果重新赋值!");
throw new ElException("不可对【" + this + "】执行结果重新赋值!");
}

@Override
Expand All @@ -91,6 +91,6 @@ public Object getValueByParent(Object ctx, NodeHolder parentNode) {
@Override
void removeValueByParent(NodeHolder parentNode, int index) {
// skip
logger.info("移除【{}】操作无效,无需移除!", this.toString());
logger.info("移除【{}】操作无效,无需移除!", this);
}
}
3 changes: 3 additions & 0 deletions src/test/java/unit/ElTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ public void baseTest() {
Assertions.assertEquals("123456", ELExecutor.eval("pojo.abc=123456;pojo.abc", context, String.class));
Assertions.assertEquals("123", ELExecutor.eval("p.pojo.abc=123;pojo.abc", context, String.class));
Assertions.assertEquals("1234", ELExecutor.eval("pojo.abc=pojo.abc=1234;p.pojo.abc", context, String.class));

ELExecutor.putNode(context, "arr", new String[]{"1", null, "3"});
Assertions.assertEquals("3", ELExecutor.eval("arr.size()", context, String.class));
}

@Test
Expand Down

0 comments on commit daf696e

Please sign in to comment.