Skip to content

Commit 09e33a9

Browse files
committed
新分支1.2.1
1.重构动态方法调用,现在动态调用对象方法与内置方法调用逻辑基本一致 2.EL实例树增加访问者接口,方便自定义扩展的EL树实例分析
1 parent 96378c3 commit 09e33a9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+826
-361
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<modelVersion>4.0.0</modelVersion>
1010
<groupId>net.fanjr.simplify</groupId>
1111
<artifactId>simplify-el</artifactId>
12-
<version>1.2.0</version>
12+
<version>1.2.1-SNAPSHOT</version>
1313
<packaging>jar</packaging>
1414
<name>Simply Expression Language</name>
1515
<description>

src/main/java/org/fanjr/simplify/el/EL.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,10 @@ default Object invoke(Object ctx, Type type) {
4141
default <T> T invoke(Object ctx, Class<T> type) {
4242
return ElUtils.cast(invoke(ctx), type);
4343
}
44+
45+
46+
default void accept(ELVisitor visitor) {
47+
// 默认只访问自身,不访问子节点
48+
visitor.visit(this);
49+
}
4450
}

src/main/java/org/fanjr/simplify/el/ELExecutor.java

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import org.fanjr.simplify.el.invoker.*;
77
import org.fanjr.simplify.el.invoker.calculate.*;
88
import org.fanjr.simplify.el.invoker.node.*;
9-
import org.fanjr.simplify.utils.ELMethodInvokeUtils;
9+
import org.fanjr.simplify.el.reflect.ELFunctionInvokeUtils;
1010
import org.fanjr.simplify.utils.ElUtils;
1111
import org.fanjr.simplify.utils.Pair;
1212

@@ -405,17 +405,16 @@ public static ELInvoker resolve(char[] chars, int start, int end) {
405405
start = nextDot + 1;
406406
} while (start < end);
407407
} else {
408-
409408
// 判断是否包含自定义函数 eg : XX.fun(...)
410409
int nextFunctionToken = findNextCharToken(chars, '(', start, end, false);
411410
if (nextFunctionToken > 0) {
412411
int nextFunctionEnd = findNextCharToken(chars, ')', nextFunctionToken + 1, end, true);
413412
// 是方法,需要判断是否为自定义函数
414-
int[] dots = countCharToken(chars, '.', start, nextFunctionToken);
413+
int[] dots = findAllCharToken(chars, '.', start, nextFunctionToken);
415414
if (dots.length == 1) {
416415
// 已判断形式为XX.fun(...)形式,进一步判断是否为注册的function
417416
String functionUtilsName = String.valueOf(chars, start, dots[0] - start);
418-
if (ELMethodInvokeUtils.hasUtils(functionUtilsName)){
417+
if (ELFunctionInvokeUtils.hasUtils(functionUtilsName)){
419418
String methodName = String.valueOf(chars, dots[0] + 1, nextFunctionToken - dots[0] - 1);
420419
parent = FunctionMethodNodeInvoker.newInstance(functionUtilsName, methodName, resolveList(chars, nextFunctionToken, nextFunctionEnd + 1));
421420
// 位移到方法后
@@ -663,33 +662,6 @@ private static NodeInvoker doCompileNode(char[] chars, int start, int end) {
663662
}
664663
}
665664

666-
private static int findChar(char[] chars, char c, int start, int end) {
667-
for (int i = start; i < end; i++) {
668-
if (c == chars[i]) {
669-
return i;
670-
}
671-
}
672-
return -1;
673-
}
674-
675-
/**
676-
* 用于寻找 ${ 或者 #{
677-
*
678-
* @return $ 或者 # 的index
679-
*/
680-
private static int findElStart(char[] chars, int start, int end) {
681-
// 通过下一个花括号位置来判断是否存在 ${ 或者 #{
682-
int nextCurly = findChar(chars, '{', start, end);
683-
if (nextCurly == -1) {
684-
return -1;
685-
} else {
686-
if (nextCurly > start && nextCurly < end && ('$' == chars[nextCurly - 1] || '#' == chars[nextCurly - 1])) {
687-
return nextCurly - 1;
688-
} else {
689-
return findElStart(chars, nextCurly + 2, end);
690-
}
691-
}
692-
}
693665

694666
private static void pushNotBuild(LinkedList<Supplier<ELInvoker>> builderStack, ELInvoker invoker) {
695667
if (null == invoker) {

src/main/java/org/fanjr/simplify/el/ELInvoker.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ public interface ELInvoker {
88

99
Object invoke(Object ctx);
1010

11+
void accept(ELVisitor visitor);
1112
}

src/main/java/org/fanjr/simplify/el/ELMethod.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
int order() default -1;
1717

1818
/**
19-
* 注册的方法名称,若为空值,则以实际方法名为准
19+
* 注册的方法名称,若为空值,则以实际方法名为准,可以是多个,这样会将多个名称都映射指向到这个方法
2020
*/
21-
String functionName() default "";
21+
String[] functionName() default {};
2222

2323
/**
2424
* 用于跳过不想注册成function的方法

src/main/java/org/fanjr/simplify/el/ELTokenUtils.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ public static int findNextCharToken(char[] chars, char c, int start, int end) {
140140
* @param end 结束index(不包括)
141141
*/
142142
public static void checkEL(char[] chars, int start, int end) {
143-
for (int i = 0; i < 3; i++) {
144-
char c = ")]}".charAt(i);
143+
for (char c : ")]}".toCharArray()) {
145144
int index = findNextCharToken(chars, c, start, end, false);
146145
if (-1 != index) {
147146
throw new ElException("解析表达式【" + String.valueOf(chars) + "】发生异常,存在多余的【" + c + "】");
@@ -237,7 +236,7 @@ public static int findLastCharToken(char[] chars, char c, int start, int end, bo
237236
}
238237
}
239238

240-
public static int[] countCharToken(char[] chars, char c, int start, int end) {
239+
public static int[] findAllCharToken(char[] chars, char c, int start, int end) {
241240
IntStream.Builder builder = IntStream.builder();
242241
for (int i = start; i < end; i++) {
243242
if (chars[i] == c) {
@@ -424,4 +423,35 @@ public static int findEndSpace(char[] chars, int start, int end) {
424423
return s;
425424
}
426425

426+
/**
427+
* 用于寻找 ${ 或者 #{
428+
*
429+
* @return $ 或者 # 的index
430+
*/
431+
public static int findElStart(char[] chars, int start, int end) {
432+
// 通过下一个花括号位置来判断是否存在 ${ 或者 #{
433+
int nextCurly = findChar(chars, '{', start, end);
434+
if (nextCurly == -1) {
435+
return -1;
436+
} else {
437+
if (nextCurly > start && nextCurly < end && ('$' == chars[nextCurly - 1] || '#' == chars[nextCurly - 1])) {
438+
return nextCurly - 1;
439+
} else {
440+
return findElStart(chars, nextCurly + 2, end);
441+
}
442+
}
443+
}
444+
445+
/**
446+
* 直接找某个字符串,非token标准
447+
*/
448+
public static int findChar(char[] chars, char c, int start, int end) {
449+
for (int i = start; i < end; i++) {
450+
if (c == chars[i]) {
451+
return i;
452+
}
453+
}
454+
return -1;
455+
}
456+
427457
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.fanjr.simplify.el;
2+
3+
import org.fanjr.simplify.el.invoker.node.Node;
4+
5+
/**
6+
* 表达式节点树访问者
7+
*/
8+
public interface ELVisitor {
9+
10+
/**
11+
* @return 是否继续向下访问,返回false时不再向下访问
12+
*/
13+
boolean visit(EL el);
14+
15+
/**
16+
* @return 是否继续向下访问,返回false时不再向下访问
17+
*/
18+
boolean visit(ELInvoker invoker);
19+
20+
}

src/main/java/org/fanjr/simplify/el/NullEL.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ public Object invoke(Object ctx) {
1515
return null;
1616
}
1717

18+
@Override
19+
public void accept(ELVisitor visitor) {
20+
// 访问自身
21+
visitor.visit(this);
22+
}
1823
}

src/main/java/org/fanjr/simplify/el/SimpleEL.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
/**
44
* 简易EL表达式
5+
*
56
* @author fanjr@vip.qq.com
67
* @since 2021/6/28 下午4:08
78
*/
@@ -17,4 +18,13 @@ public SimpleEL(ELInvoker invoker) {
1718
public Object invoke(Object ctx) {
1819
return invoker.invoke(ctx);
1920
}
21+
22+
@Override
23+
public void accept(ELVisitor visitor) {
24+
// 访问自身
25+
if (visitor.visit(this)) {
26+
// 访问子节点
27+
invoker.accept(visitor);
28+
}
29+
}
2030
}

src/main/java/org/fanjr/simplify/el/SpliceEL.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,15 @@ public Object invoke(Object ctx) {
3131
}
3232
return sb.toString();
3333
}
34+
35+
@Override
36+
public void accept(ELVisitor visitor) {
37+
// 访问自身
38+
if (visitor.visit(this)) {
39+
for (ELInvoker invoker : invokers) {
40+
// 访问子节点
41+
invoker.accept(visitor);
42+
}
43+
}
44+
}
3445
}

0 commit comments

Comments
 (0)