4
4
import java .util .List ;
5
5
import java .util .Map ;
6
6
import java .util .Stack ;
7
+ import java .util .regex .Matcher ;
8
+ import java .util .regex .Pattern ;
7
9
10
+ import com .ql .util .express .instruction .op .*;
8
11
import com .ql .util .express .parse .*;
12
+ import com .ql .util .express .rule .Condition ;
13
+ import com .ql .util .express .rule .Rule ;
14
+ import com .ql .util .express .rule .RuleManager ;
15
+ import com .ql .util .express .rule .RuleResult ;
9
16
import org .apache .commons .logging .Log ;
10
17
import org .apache .commons .logging .LogFactory ;
11
18
12
19
import com .ql .util .express .instruction .ForRelBreakContinue ;
13
20
import com .ql .util .express .instruction .IOperateDataCache ;
14
21
import com .ql .util .express .instruction .InstructionFactory ;
15
22
import com .ql .util .express .instruction .OperateDataCacheImpl ;
16
- import com .ql .util .express .instruction .op .OperatorBase ;
17
- import com .ql .util .express .instruction .op .OperatorFactory ;
18
- import com .ql .util .express .instruction .op .OperatorMinMax ;
19
- import com .ql .util .express .instruction .op .OperatorPrint ;
20
- import com .ql .util .express .instruction .op .OperatorPrintln ;
21
- import com .ql .util .express .instruction .op .OperatorRound ;
22
- import com .ql .util .express .instruction .op .OperatorSelfDefineClassFunction ;
23
- import com .ql .util .express .instruction .op .OperatorSelfDefineServiceFunction ;
24
23
25
24
/**
26
25
* 语法分析和计算的入口类
@@ -35,22 +34,27 @@ public class ExpressRunner {
35
34
* 是否输出所有的跟踪信息,同时还需要log级别是DEBUG级别
36
35
*/
37
36
private boolean isTrace = false ;
38
-
37
+
39
38
/**
40
39
* 是否使用逻辑短路特性增强质量的效率
41
40
*/
42
41
private boolean isShortCircuit = true ;
43
-
42
+
44
43
/**
45
44
* 是否需要高精度计算
46
45
*/
47
46
private boolean isPrecise = false ;
48
-
47
+
49
48
/**
50
49
* 一段文本对应的指令集的缓存
51
50
*/
52
51
private Map <String ,InstructionSet > expressInstructionSetCache = new HashMap <String , InstructionSet >();
53
-
52
+
53
+ /**
54
+ * 一段文本对应的规则的缓存
55
+ */
56
+ private Map <String ,Rule > ruleCache = new HashMap <String , Rule >();
57
+
54
58
private ExpressLoader loader ;
55
59
private IExpressResourceLoader expressResourceLoader ;
56
60
/**
@@ -64,8 +68,8 @@ public class ExpressRunner {
64
68
/**
65
69
* 语法分析器
66
70
*/
67
- private ExpressParse parse ;
68
-
71
+ private ExpressParse parse ;
72
+
69
73
/**
70
74
* 缺省的Class查找的包管理器
71
75
*/
@@ -82,7 +86,7 @@ public AppendingClassFieldManager getAppendingClassFieldManager() {
82
86
}
83
87
84
88
private AppendingClassFieldManager appendingClassFieldManager ;
85
-
89
+
86
90
private ThreadLocal <IOperateDataCache > m_OperateDataObjectCache = new ThreadLocal <IOperateDataCache >(){
87
91
protected IOperateDataCache initialValue () {
88
92
return new OperateDataCacheImpl (30 );
@@ -91,12 +95,12 @@ protected IOperateDataCache initialValue() {
91
95
public IOperateDataCache getOperateDataCache (){
92
96
return this .m_OperateDataObjectCache .get ();
93
97
}
94
-
98
+
95
99
public ExpressRunner (){
96
100
this (false ,false );
97
101
}
98
102
/**
99
- *
103
+ *
100
104
* @param aIsPrecise 是否需要高精度计算支持
101
105
* @param aIstrace 是否跟踪执行指令的过程
102
106
*/
@@ -107,7 +111,7 @@ public ExpressRunner(boolean aIsPrecise,boolean aIstrace,NodeTypeManager aManage
107
111
this (aIsPrecise ,aIstrace ,new DefaultExpressResourceLoader (),aManager );
108
112
}
109
113
/**
110
- *
114
+ *
111
115
* @param aIsPrecise 是否需要高精度计算支持
112
116
* @param aIstrace 是否跟踪执行指令的过程
113
117
* @param aExpressResourceLoader 表达式的资源装载器
@@ -127,10 +131,20 @@ public ExpressRunner(boolean aIsPrecise,boolean aIstrace,IExpressResourceLoader
127
131
rootExpressPackage .addPackage ("java.lang" );
128
132
rootExpressPackage .addPackage ("java.util" );
129
133
this .addSystemFunctions ();
130
- }
131
- public void addSystemFunctions (){
132
- this .addFunction ("max" , new OperatorMinMax ("max" ));
133
- this .addFunction ("min" , new OperatorMinMax ("min" ));
134
+ this .addSystemOperators ();
135
+ }
136
+
137
+ private void addSystemOperators () {
138
+ try {
139
+ this .addOperator ("instanceof" , new OperatorInstanceOf ("instanceof" ));
140
+ }catch (Exception e ){
141
+ throw new RuntimeException (e );
142
+ }
143
+ }
144
+
145
+ public void addSystemFunctions (){
146
+ this .addFunction ("max" , new OperatorMinMax ("max" ));
147
+ this .addFunction ("min" , new OperatorMinMax ("min" ));
134
148
this .addFunction ("round" , new OperatorRound ("round" ));
135
149
this .addFunction ("print" , new OperatorPrint ("print" ));
136
150
this .addFunction ("println" , new OperatorPrintln ("println" ));
@@ -157,23 +171,23 @@ public IExpressResourceLoader getExpressResourceLoader(){
157
171
* 添加宏定义 例如: macro 玄难 { abc(userinfo.userId);}
158
172
* @param macroName:玄难
159
173
* @param express :abc(userinfo.userId);
160
- * @throws Exception
174
+ * @throws Exception
161
175
*/
162
- public void addMacro (String macroName ,String express ) throws Exception {
176
+ public void addMacro (String macroName ,String express ) throws Exception {
163
177
String macroExpress = "macro " + macroName +" {" + express + "}" ;
164
178
this .loader .parseInstructionSet (GLOBAL_DEFINE_NAME ,macroExpress );
165
179
}
166
-
180
+
167
181
/**
168
182
* 装载表达式,但不执行,例如一些宏定义,或者自定义函数
169
183
* @param groupName
170
184
* @param express
171
185
* @throws Exception
172
186
*/
173
- public void loadMutilExpress (String groupName ,String express ) throws Exception {
187
+ public void loadMutilExpress (String groupName ,String express ) throws Exception {
174
188
if (groupName == null || groupName .trim ().length () ==0 ){
175
189
groupName = GLOBAL_DEFINE_NAME ;
176
- }
190
+ }
177
191
this .loader .parseInstructionSet (groupName ,express );
178
192
}
179
193
/**
@@ -267,15 +281,15 @@ public void addFunctionOfClassMethod(String name, String aClassName,
267
281
String errorInfo ) throws Exception {
268
282
this .addFunction (name , new OperatorSelfDefineClassFunction (name ,
269
283
aClassName , aFunctionName , aParameterClassTypes ,null ,null , errorInfo ));
270
-
284
+
271
285
}
272
286
/**
273
287
* 添加一个类的函数定义,例如:Math.abs(double) 映射为表达式中的 "取绝对值(-5.0)"
274
288
* @param name 函数名称
275
289
* @param aClassName 类名称
276
290
* @param aFunctionName 类中的方法名称
277
291
* @param aParameterClassTypes 方法的参数类型名称
278
- * @param aParameterDesc 方法的参数说明
292
+ * @param aParameterDesc 方法的参数说明
279
293
* @param aParameterAnnotation 方法的参数注解
280
294
* @param errorInfo 如果函数执行的结果是false,需要输出的错误信息
281
295
* @throws Exception
@@ -301,15 +315,15 @@ public void addFunctionOfClassMethod(String name, String aClassName,
301
315
String aFunctionName , String [] aParameterTypes , String errorInfo )
302
316
throws Exception {
303
317
this .addFunction (name , new OperatorSelfDefineClassFunction (name ,
304
- aClassName , aFunctionName , aParameterTypes , null ,null ,errorInfo ));
318
+ aClassName , aFunctionName , aParameterTypes , null ,null ,errorInfo ));
305
319
}
306
320
/**
307
321
* 添加一个类的函数定义,例如:Math.abs(double) 映射为表达式中的 "取绝对值(-5.0)"
308
322
* @param name 函数名称
309
323
* @param aClassName 类名称
310
324
* @param aFunctionName 类中的方法名称
311
325
* @param aParameterTypes 方法的参数类型名称
312
- * @param aParameterDesc 方法的参数说明
326
+ * @param aParameterDesc 方法的参数说明
313
327
* @param aParameterAnnotation 方法的参数注解
314
328
* @param errorInfo 如果函数执行的结果是false,需要输出的错误信息
315
329
* @throws Exception
@@ -320,8 +334,8 @@ public void addFunctionOfClassMethod(String name, String aClassName,
320
334
String errorInfo )
321
335
throws Exception {
322
336
this .addFunction (name , new OperatorSelfDefineClassFunction (name ,
323
- aClassName , aFunctionName , aParameterTypes , aParameterDesc ,aParameterAnnotation ,errorInfo ));
324
-
337
+ aClassName , aFunctionName , aParameterTypes , aParameterDesc ,aParameterAnnotation ,errorInfo ));
338
+
325
339
}
326
340
/**
327
341
* 用于将一个用户自己定义的对象(例如Spring对象)方法转换为一个表达式计算的函数
@@ -337,19 +351,19 @@ public void addFunctionOfServiceMethod(String name, Object aServiceObject,
337
351
String errorInfo ) throws Exception {
338
352
this .addFunction (name , new OperatorSelfDefineServiceFunction (name ,
339
353
aServiceObject , aFunctionName , aParameterClassTypes ,null ,null , errorInfo ));
340
-
354
+
341
355
}
342
356
/**
343
357
* 用于将一个用户自己定义的对象(例如Spring对象)方法转换为一个表达式计算的函数
344
358
* @param name
345
359
* @param aServiceObject
346
360
* @param aFunctionName
347
361
* @param aParameterClassTypes
348
- * @param aParameterDesc 方法的参数说明
362
+ * @param aParameterDesc 方法的参数说明
349
363
* @param aParameterAnnotation 方法的参数注解
350
364
* @param errorInfo
351
365
* @throws Exception
352
- */
366
+ */
353
367
public void addFunctionOfServiceMethod (String name , Object aServiceObject ,
354
368
String aFunctionName , Class <?>[] aParameterClassTypes ,
355
369
String [] aParameterDesc ,String [] aParameterAnnotation ,
@@ -369,7 +383,7 @@ public void addFunctionOfServiceMethod(String name, Object aServiceObject,
369
383
*/
370
384
public void addFunctionOfServiceMethod (String name , Object aServiceObject ,
371
385
String aFunctionName , String [] aParameterTypes , String errorInfo )
372
- throws Exception {
386
+ throws Exception {
373
387
this .addFunction (name , new OperatorSelfDefineServiceFunction (name ,
374
388
aServiceObject , aFunctionName , aParameterTypes ,null ,null , errorInfo ));
375
389
@@ -387,7 +401,7 @@ public void addFunctionOfServiceMethod(String name, Object aServiceObject,
387
401
* 添加操作符号,此操作符号的优先级与 "*"相同,语法形式也是 data name data
388
402
* @param name
389
403
* @param op
390
- * @throws Exception
404
+ * @throws Exception
391
405
*/
392
406
public void addOperator (String name ,Operator op ) throws Exception {
393
407
this .addOperator (name , "*" , op );
@@ -397,7 +411,7 @@ public void addOperator(String name,Operator op) throws Exception {
397
411
* @param name 操作符号名称
398
412
* @param aRefOpername 参照的操作符号,例如 "+","--"等
399
413
* @param op
400
- * @throws Exception
414
+ * @throws Exception
401
415
*/
402
416
public void addOperator (String name ,String aRefOpername ,Operator op ) throws Exception {
403
417
this .manager .addOperatorWithLevelOfReference (name , aRefOpername );
@@ -425,7 +439,7 @@ public void addOperatorWithAlias(String keyWordName, String realKeyWordName,
425
439
}
426
440
NodeType realNodeType = this .manager .findNodeType (realKeyWordName );
427
441
if (realNodeType == null ){
428
- throw new Exception ("关键字:" + realKeyWordName +"不存在" );
442
+ throw new Exception ("关键字:" + realKeyWordName +"不存在" );
429
443
}
430
444
boolean isExist = this .operatorManager .isExistOperator (realNodeType .getName ());
431
445
if (isExist == false && errorInfo != null ){
@@ -435,7 +449,7 @@ public void addOperatorWithAlias(String keyWordName, String realKeyWordName,
435
449
//不需要新增操作符号,只需要建立一个关键子即可
436
450
this .manager .addOperatorWithRealNodeType (keyWordName , realNodeType .getName ());
437
451
}else {
438
- this .manager .addOperatorWithLevelOfReference (keyWordName , realNodeType .getName ());
452
+ this .manager .addOperatorWithLevelOfReference (keyWordName , realNodeType .getName ());
439
453
this .operatorManager .addOperatorWithAlias (keyWordName , realNodeType .getName (), errorInfo );
440
454
}
441
455
}
@@ -446,7 +460,7 @@ public void addOperatorWithAlias(String keyWordName, String realKeyWordName,
446
460
public OperatorBase replaceOperator (String name ,OperatorBase op ){
447
461
return this .operatorManager .replaceOperator (name , op );
448
462
}
449
-
463
+
450
464
public ExpressPackage getRootExpressPackage (){
451
465
return this .rootExpressPackage ;
452
466
}
@@ -492,7 +506,7 @@ public Object execute(InstructionSet[] instructionSets,IExpressContext<String,Ob
492
506
return InstructionSetRunner .executeOuter (this ,instructionSets [0 ],this .loader ,context , errorList ,
493
507
isTrace ,isCatchException ,aLog ,false );
494
508
}
495
-
509
+
496
510
/**
497
511
* 执行指令集
498
512
* @param instructionSets
@@ -557,6 +571,73 @@ public Object execute(String expressString, IExpressContext<String,Object> conte
557
571
isTrace ,false ,aLog ,false );
558
572
}
559
573
574
+ public RuleResult executeRule (String expressString , IExpressContext <String ,Object > context , boolean isCache , boolean isTrace )
575
+ throws Exception {
576
+ Rule rule = null ;
577
+ if (isCache == true ) {
578
+ rule = ruleCache .get (expressString );
579
+ if (rule == null ) {
580
+ synchronized (ruleCache ) {
581
+ rule = ruleCache .get (expressString );
582
+ if (rule == null ) {
583
+ rule = this .parseRule (expressString );
584
+ ruleCache .put (expressString ,
585
+ rule );
586
+ }
587
+ }
588
+ }
589
+ } else {
590
+ rule = this .parseRule (expressString );
591
+ }
592
+ return RuleManager .executeRule (this ,rule ,context ,isCache ,isTrace );
593
+ }
594
+
595
+ static Pattern patternRule = Pattern .compile ("rule[\\ s]+'([^']+)'[\\ s]+name[\\ s]+'([^']+)'[\\ s]+" );
596
+
597
+ public Rule parseRule (String text )
598
+ throws Exception {
599
+ String ruleName = null ;
600
+ String ruleCode = null ;
601
+ Matcher matcher = patternRule .matcher (text );
602
+ if (matcher .find ()) {
603
+ ruleCode = matcher .group (1 );
604
+ ruleName = matcher .group (2 );
605
+ text = text .substring (matcher .end ());
606
+ }
607
+
608
+ Map <String ,String > selfDefineClass = new HashMap <String ,String > ();
609
+ for (ExportItem item : this .loader .getExportInfo ()){
610
+ if (item .getType ().equals (InstructionSet .TYPE_CLASS )){
611
+ selfDefineClass .put (item .getName (), item .getName ());
612
+ }
613
+ }
614
+
615
+ // 分成两句话执行,用来保存中间的words结果
616
+ // ExpressNode root = this.parse.parse(this.rootExpressPackage,text, isTrace,selfDefineClass);
617
+
618
+ Word [] words = this .parse .splitWords (rootExpressPackage ,text ,isTrace ,selfDefineClass );
619
+ ExpressNode root = this .parse .parse (rootExpressPackage ,words ,text ,isTrace ,selfDefineClass );
620
+ Rule rule = RuleManager .createRule (root ,words );
621
+ rule .setCode (ruleCode );
622
+ rule .setName (ruleName );
623
+ return rule ;
624
+ }
625
+
626
+ public Condition parseContition (String text )
627
+ throws Exception {
628
+
629
+ Map <String ,String > selfDefineClass = new HashMap <String ,String > ();
630
+ for (ExportItem item : this .loader .getExportInfo ()){
631
+ if (item .getType ().equals (InstructionSet .TYPE_CLASS )){
632
+ selfDefineClass .put (item .getName (), item .getName ());
633
+ }
634
+ }
635
+
636
+ Word [] words = this .parse .splitWords (rootExpressPackage ,text ,isTrace ,selfDefineClass );
637
+ ExpressNode root = this .parse .parse (rootExpressPackage ,words ,text ,isTrace ,selfDefineClass );
638
+ return RuleManager .createCondition (root ,words );
639
+ }
640
+
560
641
/**
561
642
* 解析一段文本,生成指令集合
562
643
* @param text
@@ -571,7 +652,7 @@ public InstructionSet parseInstructionSet(String text)
571
652
selfDefineClass .put (item .getName (), item .getName ());
572
653
}
573
654
}
574
-
655
+
575
656
ExpressNode root = this .parse .parse (this .rootExpressPackage ,text , isTrace ,selfDefineClass );
576
657
InstructionSet result = createInstructionSet (root , "main" );
577
658
if (this .isTrace && log .isDebugEnabled ()) {
@@ -586,7 +667,7 @@ public InstructionSet parseInstructionSet(String text)
586
667
public ExportItem [] getExportInfo (){
587
668
return this .loader .getExportInfo ();
588
669
}
589
-
670
+
590
671
/**
591
672
* 优先从本地指令集缓存获取指令集,没有的话生成并且缓存在本地
592
673
* @param expressString
@@ -637,7 +718,7 @@ public boolean createInstructionSetPrivate(InstructionSet result,
637
718
* 获取一个表达式需要的外部变量名称列表
638
719
* @param express
639
720
* @return
640
- * @throws Exception
721
+ * @throws Exception
641
722
*/
642
723
public String [] getOutVarNames (String express ) throws Exception {
643
724
return this .parseInstructionSet (express ).getOutAttrNames ();
0 commit comments