├── README.md
├── config
└── rule.xml
├── deploy
└── lib
│ ├── commons-beanutils-1.8.2.jar
│ ├── commons-lang-2.4.jar
│ └── commons-logging-1.1.1.jar
├── pom.xml
└── src
└── main
└── java
└── com
└── ql
└── util
└── express
├── CacheObject.java
├── CallResult.java
├── DefaultContext.java
├── DefaultExpressResourceLoader.java
├── ExportItem.java
├── ExpressClassLoader.java
├── ExpressLoader.java
├── ExpressRemoteCacheRunner.java
├── ExpressRunner.java
├── ExpressUtil.java
├── IExpressContext.java
├── IExpressResourceLoader.java
├── InstructionSet.java
├── InstructionSetContext.java
├── InstructionSetRunner.java
├── LocalExpressCacheRunner.java
├── OperateData.java
├── Operator.java
├── OperatorOfNumber.java
├── Rule.java
├── RuleContext.java
├── RuleRunner.java
├── RunEnvironment.java
├── dao
└── RuleMapper.java
├── instruction
├── BlockInstructionFactory.java
├── BreakInstructionFactory.java
├── CallFunctionInstructionFactory.java
├── CastInstructionFactory.java
├── ConstDataInstructionFactory.java
├── ContinueInstructionFactory.java
├── DefineInstructionFactory.java
├── ForInstructionFactory.java
├── ForRelBreakContinue.java
├── FunctionInstructionFactory.java
├── FunctionInstructionSet.java
├── IOperateDataCache.java
├── IfInstructionFactory.java
├── InInstructionFactory.java
├── InstructionFactory.java
├── KeyValueInstructionFactory.java
├── LoadAttrInstructionFactory.java
├── MacroInstructionFactory.java
├── MethodCallInstructionFactory.java
├── NewInstructionFactory.java
├── NewVClassInstructionFactory.java
├── NullInstructionFactory.java
├── OperateDataCacheImpl.java
├── OperateDataCacheImpl4Orig.java
├── OperateDataCacheManager.java
├── OperatorInstructionFactory.java
├── detail
│ ├── Instruction.java
│ ├── InstructionCallMacro.java
│ ├── InstructionCallSelfDefineFunction.java
│ ├── InstructionClearDataStack.java
│ ├── InstructionCloseNewArea.java
│ ├── InstructionConstData.java
│ ├── InstructionGoTo.java
│ ├── InstructionGoToWithCondition.java
│ ├── InstructionGoToWithNotNull.java
│ ├── InstructionLoadAttr.java
│ ├── InstructionNewVirClass.java
│ ├── InstructionOpenNewArea.java
│ ├── InstructionOperator.java
│ └── InstructionReturn.java
├── op
│ ├── CanClone.java
│ ├── OperatorAddReduce.java
│ ├── OperatorAlias.java
│ ├── OperatorAnd.java
│ ├── OperatorAnonymousNewArray.java
│ ├── OperatorAnonymousNewList.java
│ ├── OperatorAnonymousNewMap.java
│ ├── OperatorArray.java
│ ├── OperatorBase.java
│ ├── OperatorCast.java
│ ├── OperatorDef.java
│ ├── OperatorDoubleAddReduce.java
│ ├── OperatorEqualsLessMore.java
│ ├── OperatorEvaluate.java
│ ├── OperatorExportAlias.java
│ ├── OperatorExportDef.java
│ ├── OperatorFactory.java
│ ├── OperatorField.java
│ ├── OperatorIf.java
│ ├── OperatorIn.java
│ ├── OperatorKeyValue.java
│ ├── OperatorLike.java
│ ├── OperatorMacro.java
│ ├── OperatorMethod.java
│ ├── OperatorMinMax.java
│ ├── OperatorMultiDiv.java
│ ├── OperatorNew.java
│ ├── OperatorNor.java
│ ├── OperatorNot.java
│ ├── OperatorNullOp.java
│ ├── OperatorOr.java
│ ├── OperatorPrint.java
│ ├── OperatorPrintln.java
│ ├── OperatorRound.java
│ ├── OperatorSelfDefineClassFunction.java
│ └── OperatorSelfDefineServiceFunction.java
└── opdata
│ ├── OperateClass.java
│ ├── OperateDataAlias.java
│ ├── OperateDataArrayItem.java
│ ├── OperateDataAttr.java
│ ├── OperateDataField.java
│ ├── OperateDataKeyValue.java
│ ├── OperateDataLocalVar.java
│ └── OperateDataVirClass.java
├── match
├── IDataNode.java
├── INodeType.java
├── INodeTypeManager.java
├── NodeTypeManagerTestImpl.java
├── QLMatchResult.java
├── QLMatchResultTree.java
├── QLPattern.java
└── QLPatternNode.java
└── parse
├── ExpressNode.java
├── ExpressPackage.java
├── ExpressParse.java
├── KeyWordDefine4Java.java
├── KeyWordDefine4SQL.java
├── NodeType.java
├── NodeTypeManager.java
├── Word.java
└── WordSplit.java
/README.md:
--------------------------------------------------------------------------------
1 | config/rule.xml是规则引擎的配置文件,如果使用spring,请import进spring上下文配置文件里;
2 |
3 | 规则引擎采用了jboss drools的设计思路:
4 |
5 | 规则=规则执行条件+规则执行内容+规则分组 + 规则优先级
6 |
7 | 规则的执行内容和执行条件建议以java脚本的形式存在数据库中,比如我使用了mysql,那么建表语句如下:
8 |
9 | create table `rule` (
10 |
11 | `id` int(10) unsigned not null auto_increment comment '规则主键',
12 |
13 | `rule_name` varchar(50) not null default '' comment '规则名称',
14 |
15 | `priority` int(4) not null default 0 comment '规则优先级,越大优先级越高',
16 |
17 | `group_type` tinyint not null default 0 comment '分组类型 1:占位',
18 |
19 | `group_name` varchar(50) not null default '' comment '分组名称',
20 |
21 | `match_condition` varchar(100) not null default 'true' comment '规则进入条件',
22 |
23 | `execute_content` varchar(1000) not null default '' comment '规则执行内容',
24 |
25 | `del_flag` tinyint(4) not null default 0 comment '是否删除 0 未删除 1已删除',
26 |
27 | `op_time` timestamp not null default current_timestamp on update current_timestamp comment '操作时间',
28 |
29 | primary key (`id`),
30 |
31 | index (`group_type`)
32 |
33 | )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='wanglei@2014-11-25 规则配置表';
34 |
35 | 规则会被缓存在服务部署的机器内存里,所以需要提供一个后门用于刷新缓存,API如下:
36 |
37 | RuleRunner.java
38 |
39 | /**
40 | *
41 | *Description:刷新规则内容
42 | *
43 | *@author wanglei
44 | *@taskId
45 | */
46 |
47 | public synchronized void refreshRules() {
48 |
49 | ruleList = ruleMapper.getRuleList();
50 |
51 | rulesCache = new HashMap>();
52 |
53 | }
54 |
55 | 后续会考虑使用memcache这种分布式的缓存,目前有没有使用,因为觉得有点杀鸡用牛刀。
56 |
57 | 最近发现阿里的diamond真是特别好用,如果公司有接入diamond的话,可以考虑直接用diamond存储规则,不过这样一来RuleManager就得再写一个了,也许这里应该最初就设计成一个工厂或者模板的模式。
58 |
59 | 规则的解析基于taocode的qlexpress,我这里做了简单的封装,以适应于我的项目,关于qlexpress,参考:
60 |
61 | http://code.taobao.org/p/QLExpress/wiki/index/
62 |
--------------------------------------------------------------------------------
/config/rule.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/deploy/lib/commons-beanutils-1.8.2.jar:
--------------------------------------------------------------------------------
1 | PK
2 | spi; META-INF/PK
3 | rpi;|x`鄅 ? META-INF/MANIFEST.MF
--------------------------------------------------------------------------------
/deploy/lib/commons-lang-2.4.jar:
--------------------------------------------------------------------------------
1 | PK
2 | i
--------------------------------------------------------------------------------
/deploy/lib/commons-logging-1.1.1.jar:
--------------------------------------------------------------------------------
1 | PK
2 | s7 META-INF/PK
3 | s7櫨"骢 META-INF/MANIFEST.MF峇蒵
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.tuniu.common
6 | jar
7 | 1.0.0
8 | rule
9 |
10 | 1.6
11 | UTF-8
12 |
13 |
14 |
15 |
16 | commons-beanutils
17 | commons-beanutils
18 | 1.8.2
19 |
20 |
21 | log4j
22 | log4j
23 | 1.2.16
24 |
25 |
26 | commons-logging
27 | commons-logging
28 | 1.1.1
29 |
30 |
31 | commons-lang
32 | commons-lang
33 | 2.4
34 |
35 |
36 | junit
37 | junit
38 | 4.4
39 | test
40 |
41 |
42 | org.unitils
43 | unitils
44 | 2.4
45 | test
46 |
47 |
48 | org.springframework
49 | spring
50 | 2.5.6
51 | test
52 |
53 |
54 | org.mybatis
55 | mybatis
56 | 3.2.3
57 |
58 |
59 |
60 |
61 |
62 |
63 | org.apache.maven.plugins
64 | maven-compiler-plugin
65 |
66 | 1.6
67 | 1.6
68 |
69 |
70 |
71 | maven-source-plugin
72 | 2.1
73 |
74 | true
75 |
76 |
77 |
78 | compile
79 |
80 | jar
81 |
82 |
83 |
84 |
85 |
86 |
87 | rule
88 |
89 |
90 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/CacheObject.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 简单的缓存对象
7 | * @author tianqiao
8 | *
9 | */
10 | public class CacheObject implements Serializable{
11 |
12 | /**
13 | *
14 | */
15 | private static final long serialVersionUID = -145121001676214513L;
16 |
17 | private String expressName;
18 |
19 | private String text;
20 |
21 | private InstructionSet instructionSet;
22 |
23 | public String getExpressName() {
24 | return expressName;
25 | }
26 |
27 | public void setExpressName(String name) {
28 | this.expressName = name;
29 | }
30 |
31 | public String getText() {
32 | return text;
33 | }
34 |
35 | public void setText(String text) {
36 | this.text = text;
37 | }
38 |
39 | public InstructionSet getInstructionSet() {
40 | return instructionSet;
41 | }
42 |
43 | public void setInstructionSet(InstructionSet instructionSet) {
44 | this.instructionSet = instructionSet;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/CallResult.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | public class CallResult{
4 | private Object returnValue;
5 | private boolean isExit;
6 | public CallResult(Object aReturnValue,boolean aIsExit){
7 | this.initial(aReturnValue, aIsExit);
8 | }
9 | public void initial(Object aReturnValue,boolean aIsExit){
10 | this.returnValue = aReturnValue;
11 | this.isExit = aIsExit;
12 | }
13 | public void clear(){
14 | this.returnValue = null;
15 | this.isExit = false;
16 | }
17 | public Object getReturnValue() {
18 | return returnValue;
19 | }
20 | public boolean isExit() {
21 | return isExit;
22 | }
23 |
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/DefaultContext.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.util.HashMap;
4 |
5 |
6 | @SuppressWarnings("serial")
7 | public class DefaultContext extends HashMap implements IExpressContext {
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/DefaultExpressResourceLoader.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.InputStream;
5 | import java.io.InputStreamReader;
6 |
7 | public class DefaultExpressResourceLoader implements IExpressResourceLoader {
8 | public String loadExpress(String expressName) throws Exception {
9 | expressName = expressName.replace('.', '/') + ".ql";
10 | InputStream in = Thread.currentThread().getContextClassLoader()
11 | .getResourceAsStream(expressName);
12 | if (in == null) {
13 | throw new Exception("不能找到表达式文件:" + expressName);
14 | }
15 | BufferedReader reader = new BufferedReader(new InputStreamReader(in));
16 | StringBuilder builder = new StringBuilder();
17 | String tmpStr = null;
18 | while ((tmpStr = reader.readLine()) != null) {
19 | builder.append(tmpStr).append("\n");
20 | }
21 | reader.close();
22 | in.close();
23 | return builder.toString();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/ExportItem.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 输出给其它指令共享使用的对象
7 | * @author xuannan
8 | *
9 | */
10 | public class ExportItem implements Serializable{
11 | private static final long serialVersionUID = 5440012774123494760L;
12 | public static String TYPE_ALIAS ="alias";
13 | public static String TYPE_DEF ="def";
14 | public static String TYPE_FUNCTION ="function";
15 | public static String TYPE_MACRO ="macro";
16 | String globeName;
17 | String name;
18 | String type;//def,alias
19 | String desc;//类名或者别名
20 | public ExportItem(String aName,String aType,String aDesc){
21 | this.globeName = aName;
22 | this.name = aName;
23 | this.type =aType;
24 | this.desc = aDesc;
25 | }
26 | public ExportItem(String aGlobeName,String aName,String aType,String aDesc){
27 | this.globeName = aGlobeName;
28 | this.name = aName;
29 | this.type =aType;
30 | this.desc = aDesc;
31 | }
32 | public String toString(){
33 | return this.globeName + "["+ this.type +":" + this.name +" " + this.desc + "]";
34 | }
35 | public String getGlobeName() {
36 | return globeName;
37 | }
38 | public void setGlobeName(String globeName) {
39 | this.globeName = globeName;
40 | }
41 | public String getName() {
42 | return name;
43 | }
44 | public void setName(String name) {
45 | this.name = name;
46 | }
47 | public String getType() {
48 | return type;
49 | }
50 | public void setType(String type) {
51 | this.type = type;
52 | }
53 | public String getDesc() {
54 | return desc;
55 | }
56 | public void setDesc(String desc) {
57 | this.desc = desc;
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/ExpressClassLoader.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.lang.reflect.Array;
4 | import java.lang.reflect.Method;
5 |
6 | public class ExpressClassLoader extends ClassLoader {
7 | public ExpressClassLoader(ClassLoader parent){
8 | super(parent);
9 | }
10 | public Class> loadClass(String name, byte[] code) {
11 | return this.defineClass(name, code, 0, code.length);
12 | }
13 |
14 | public synchronized Class> loadClass(String name, boolean resolve)
15 | throws ClassNotFoundException {
16 | //System.out.print("开始查找 类" + name + "。。。。。。。。。。。");
17 | Class> clasz = findLoadedClass(this, name);
18 | if (clasz != null) {
19 | //System.out.println(clasz.getClassLoader());
20 | return clasz;
21 | }
22 | if (clasz == null) {
23 | clasz = parentLoadClass(this, name);
24 | }
25 | if (clasz == null && name.startsWith("[")) { // 进行数组处理
26 | int index = name.indexOf("L");
27 | String str = name.substring(0, index);
28 | String componentClassName = name.substring(index + 1,
29 | name.length() - 1);
30 | int[] dimes = new int[str.length()];
31 | for (int i = 0; i < dimes.length; i++) {
32 | dimes[i] = 0;
33 | }
34 | try {
35 | Class> componentType = this.loadClass(componentClassName);
36 | clasz = Array.newInstance(componentType, dimes).getClass();
37 | } catch (Exception e) {
38 | // 不错处理
39 | }
40 | }
41 |
42 | if (clasz == null)
43 | throw new ClassNotFoundException(name);
44 | return clasz;
45 | }
46 |
47 | public static Class> findLoadedClass(ClassLoader loader, String name)
48 | throws ClassNotFoundException {
49 | Method m = null;
50 | try {
51 | m = ClassLoader.class.getDeclaredMethod("findLoadedClass",
52 | new Class[] { String.class });
53 | m.setAccessible(true);
54 | Class> result = (Class>) m.invoke(loader, new Object[] { name });
55 | if (result == null) {
56 | result = (Class>) m.invoke(loader.getClass().getClassLoader(),
57 | new Object[] { name });
58 | }
59 | if (result == null) {
60 | result = (Class>) m.invoke(Thread.currentThread()
61 | .getContextClassLoader(), new Object[] { name });
62 | }
63 | return result;
64 | } catch (Exception ex) {
65 | throw new ClassNotFoundException(ex.getMessage());
66 | } finally {
67 | if (m != null) {
68 | m.setAccessible(false);
69 | }
70 | }
71 | }
72 |
73 | public static Class> parentLoadClass(ClassLoader loader, String name)
74 | throws ClassNotFoundException {
75 | // 如果存在这个类,则直接返回
76 | Class> clasz = null;
77 | if (clasz == null) {
78 | try {
79 | clasz = loader.getClass().getClassLoader().loadClass(name);
80 | } catch (Throwable e) {
81 | }
82 | }
83 | if (clasz == null)
84 | try {
85 | clasz = Thread.currentThread().getContextClassLoader()
86 | .loadClass(name);
87 | } catch (Throwable e) {
88 | }
89 | return clasz;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/ExpressLoader.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.util.Map;
4 | import java.util.TreeMap;
5 | import java.util.concurrent.ConcurrentHashMap;
6 |
7 | import com.ql.util.express.instruction.FunctionInstructionSet;
8 |
9 |
10 | /**
11 | * 表达式装载器
12 | *
13 | * @author xuannan
14 | *
15 | */
16 | public class ExpressLoader {
17 | private ConcurrentHashMap expressInstructionSetCache = new ConcurrentHashMap();
18 | ExpressRunner creator;
19 | public ExpressLoader(ExpressRunner aCreator){
20 | this.creator = aCreator;
21 | }
22 | public InstructionSet loadExpress(String expressName)
23 | throws Exception {
24 | return parseInstructionSet(expressName,this.creator.getExpressResourceLoader().loadExpress(expressName));
25 | }
26 |
27 | public void addInstructionSet(String expressName, InstructionSet set)
28 | throws Exception {
29 | synchronized (expressInstructionSetCache) {
30 | if (expressInstructionSetCache.containsKey(expressName)) {
31 | throw new Exception("表达式定义重复:" + expressName);
32 | }
33 | expressInstructionSetCache.put(expressName, set);
34 | }
35 | }
36 |
37 | public InstructionSet parseInstructionSet(String expressName,
38 | String expressString) throws Exception {
39 | InstructionSet parseResult = null;
40 | if (expressInstructionSetCache.containsKey(expressName)) {
41 | throw new Exception("表达式定义重复:" + expressName);
42 | }
43 | synchronized (expressInstructionSetCache) {
44 | parseResult = this.creator.parseInstructionSet(expressString);
45 | parseResult.setName(expressName);
46 | parseResult.setGlobeName(expressName);
47 | // 需要将函数和宏定义都提取出来
48 | for (FunctionInstructionSet item : parseResult
49 | .getFunctionInstructionSets()) {
50 | this.addInstructionSet(item.name, item.instructionSet);
51 | item.instructionSet.setName(item.name);
52 | item.instructionSet.setGlobeName(expressName+ "." + item.name);
53 | }
54 | if(parseResult.hasMain()){
55 | this.addInstructionSet(expressName, parseResult);
56 | }
57 | }
58 | return parseResult;
59 | }
60 | public void clear(){
61 | this.expressInstructionSetCache.clear();
62 | }
63 | public InstructionSet getInstructionSet(String expressName) {
64 | return expressInstructionSetCache.get(expressName);
65 | }
66 | public ExportItem[] getExportInfo(){
67 | Map result = new TreeMap();
68 | for(InstructionSet item:expressInstructionSetCache.values()){
69 | for(ExportItem var:item.getExportDef()){
70 | var.setGlobeName(item.getGlobeName() + "." + var.name);
71 | result.put(var.getGlobeName(),var);
72 | }
73 | result.put(item.getGlobeName(),new ExportItem(item.getGlobeName(), item.getName(),item.getType(),item.toString()));
74 | }
75 | return (ExportItem[])result.values().toArray(new ExportItem[0]);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/ExpressRemoteCacheRunner.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.commons.logging.Log;
6 |
7 | /**
8 | * 远程缓存对象
9 | * @author tianqiao
10 | *
11 | */
12 | public abstract class ExpressRemoteCacheRunner {
13 |
14 |
15 |
16 | public void loadCache(String expressName,String text){
17 | InstructionSet instructionSet;
18 | try {
19 | instructionSet = getExpressRunner().parseInstructionSet(text);
20 | CacheObject cache = new CacheObject();
21 | cache.setExpressName(expressName);
22 | cache.setText(text);
23 | cache.setInstructionSet(instructionSet);
24 | this.putCache(expressName, cache);
25 | } catch (Exception e) {
26 | throw new RuntimeException("解析指令并缓存过程出现错误.",e);
27 | }
28 | }
29 |
30 |
31 | public Object execute(String name,IExpressContext context, List errorList,
32 | boolean isTrace,boolean isCatchException, Log aLog){
33 | try {
34 | CacheObject cache = (CacheObject) this.getCache(name);
35 | if(cache==null){
36 | throw new RuntimeException("未获取到缓存对象.");
37 | }
38 | return getExpressRunner().execute(new InstructionSet[] {cache.getInstructionSet()}, context, errorList, isTrace, isCatchException, aLog);
39 | } catch (Exception e) {
40 | throw new RuntimeException("获取缓存信息,并且执行指令集出现错误.",e);
41 | }
42 | }
43 |
44 | /**
45 | * 获取执行器ExpressRunner
46 | * @return
47 | */
48 | public abstract ExpressRunner getExpressRunner();
49 | /**
50 | * 获取缓存对象
51 | * @param key
52 | * @return
53 | */
54 | public abstract Object getCache(String key);
55 | /**
56 | * 放置缓存的对象
57 | * @param key
58 | * @param object
59 | */
60 | public abstract void putCache(String key,Object object );
61 |
62 | }
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/IExpressContext.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | /**
4 | * 表达式计算的数据注入接口
5 | * @author qhlhl2010@gmail.com
6 | *
7 | */
8 | public interface IExpressContext {
9 | /**
10 | * 根据名称从属性列表中提取属性值。如果表达式中用到了Spring的对象,也是通过此方法获取
11 | * @param name 属性名称
12 | * @return
13 | * @throws Exception
14 | */
15 | public V get(Object key);
16 | /**
17 | * 表达式计算的结果可以设置回调用系统,例如 userId = 3 + 4
18 | * @param name 属性名称
19 | * @param object 属性值
20 | * @throws Exception
21 | */
22 | public V put(K name, V object);
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/IExpressResourceLoader.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | /**
4 | * 加载表达式资源接口
5 | * @author xuannan
6 | *
7 | */
8 | public interface IExpressResourceLoader {
9 | /**
10 | * 根据表达式名称获取表达式的内容
11 | * @param expressName
12 | * @return
13 | * @throws Exception
14 | */
15 | public String loadExpress(String expressName) throws Exception;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/InstructionSetContext.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import com.ql.util.express.instruction.OperateDataCacheManager;
7 |
8 | public class InstructionSetContext implements IExpressContext {
9 | /*
10 | * 没有知道数据类型的变量定义是否传递到最外层的Context
11 | */
12 | private boolean isExpandToParent = true;
13 |
14 | private IExpressContext parent = null;
15 | private Map content;
16 | /**
17 | * 符号表
18 | */
19 | private Map symbolTable;
20 |
21 | private ExpressLoader expressLoader;
22 |
23 | private boolean isSupportDynamicFieldName = false;
24 | private ExpressRunner runner;
25 |
26 | public InstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
27 | this.initial(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
28 | }
29 | public void initial(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
30 | this.isExpandToParent = aIsExpandToParent;
31 | this.runner = aRunner;
32 | this.parent = aParent;
33 | this.expressLoader = aExpressLoader;
34 | this.isSupportDynamicFieldName = aIsSupportDynamicFieldName;
35 | }
36 | public void clear(){
37 | isExpandToParent = true;
38 | parent = null;
39 | content = null;
40 | symbolTable = null;
41 | expressLoader = null;
42 | isSupportDynamicFieldName = false;
43 | runner = null;
44 | }
45 | public void exportSymbol(String varName,Object aliasNameObject) throws Exception{
46 | if( this.parent != null && this.parent instanceof InstructionSetContext){
47 | ((InstructionSetContext)this.parent).exportSymbol(varName, aliasNameObject);
48 | }else{
49 | this.addSymbol(varName, aliasNameObject);
50 | }
51 | }
52 | public void addSymbol(String varName,Object aliasNameObject) throws Exception{
53 | if(this.symbolTable == null){
54 | this.symbolTable = new HashMap();
55 | }
56 | if(this.symbolTable.containsKey(varName)){
57 | throw new Exception("变量" + varName + "已经存在,不能重复定义,也不能再从函数内部 exprot ");
58 | }
59 | this.symbolTable.put(varName,aliasNameObject);
60 | }
61 |
62 | public void setSupportDynamicFieldName(boolean isSupportDynamicFieldName) {
63 | this.isSupportDynamicFieldName = isSupportDynamicFieldName;
64 | }
65 | public boolean isSupportDynamicFieldName(){
66 | return this.isSupportDynamicFieldName;
67 | }
68 | public ExpressRunner getExpressRunner(){
69 | return this.runner;
70 | }
71 | public Object findAliasOrDefSymbol(String varName)throws Exception{
72 | Object result = null;
73 | if(this.symbolTable != null){
74 | result = this.symbolTable.get(varName);
75 | }
76 | if(result == null){
77 | if( this.parent != null && this.parent instanceof InstructionSetContext){
78 | result = ((InstructionSetContext)this.parent).findAliasOrDefSymbol(varName);
79 | }else{
80 | result = null;
81 | }
82 | }
83 | return result;
84 | }
85 | public Object getSymbol(String varName) throws Exception{
86 | Object result = null;
87 | if(this.symbolTable != null){
88 | result = this.symbolTable.get(varName);
89 | }
90 | if( result == null && this.expressLoader != null){
91 | result = this.expressLoader.getInstructionSet(varName);
92 | }
93 | if(result == null){
94 | if (this.isExpandToParent == true && this.parent != null
95 | && this.parent instanceof InstructionSetContext) {
96 | result = ((InstructionSetContext) this.parent)
97 | .getSymbol(varName);
98 | } else {
99 | result = OperateDataCacheManager.fetchOperateDataAttr(varName, null);
100 | this.addSymbol(varName, result);
101 | }
102 | }
103 | return result;
104 | }
105 |
106 | public ExpressLoader getExpressLoader() {
107 | return expressLoader;
108 | }
109 |
110 | public IExpressContext getParent(){
111 | return this.parent;
112 | }
113 | public Object get(Object key){
114 | if(this.content != null && this.content.containsKey(key)){
115 | return this.content.get(key);
116 | }else if(this.isExpandToParent == true && this.parent != null){
117 | return this.parent.get(key);
118 | }
119 | return null;
120 | }
121 | public Object put(String key, Object value){
122 | if(this.content != null && this.content.containsKey(key) ){
123 | return this.content.put(key,value);
124 | }else if (this.isExpandToParent == false){
125 | if(this.content == null){
126 | this.content = new HashMap();
127 | }
128 | return this.content.put(key,value);
129 | }else if(this.parent != null){
130 | return this.parent.put(key,value);
131 | }else{
132 | throw new RuntimeException("没有定义局部变量:" + key +",而且没有全局上下文");
133 | }
134 | }
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/InstructionSetRunner.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.commons.logging.Log;
6 | import org.apache.commons.logging.LogFactory;
7 |
8 | import com.ql.util.express.instruction.OperateDataCacheManager;
9 |
10 | public class InstructionSetRunner {
11 | private static final Log log = LogFactory.getLog(InstructionSetRunner.class);
12 | public static Object executeOuter(ExpressRunner runner,InstructionSet[] sets,ExpressLoader loader,
13 | IExpressContext aContext, List errorList,
14 | boolean isTrace,boolean isCatchException,
15 | Log aLog,boolean isSupportDynamicFieldName) throws Exception{
16 | try{
17 | //OperateDataCacheManager.resetCache();
18 | return execute(runner,sets, loader, aContext, errorList, isTrace, isCatchException,true, aLog,isSupportDynamicFieldName);
19 | }finally{
20 | OperateDataCacheManager.resetCache();
21 | }
22 | }
23 |
24 | /**
25 | * 批量执行指令集合,指令集间可以共享 变量和函数
26 | * @param sets
27 | * @param aOperatorManager
28 | * @param aContext
29 | * @param errorList
30 | * @param aFunctionCacheMananger
31 | * @param isTrace
32 | * @return
33 | * @throws Exception
34 | */
35 | public static Object execute(ExpressRunner runner,InstructionSet[] sets,ExpressLoader loader,
36 | IExpressContext aContext, List errorList,
37 | boolean isTrace,boolean isCatchException,
38 | boolean isReturnLastData,Log aLog,boolean isSupportDynamicFieldName)
39 | throws Exception {
40 | InstructionSetContext context = OperateDataCacheManager.fetchInstructionSetContext (
41 | true,runner,aContext,loader,isSupportDynamicFieldName);
42 | Object result = execute(sets,context,errorList,isTrace,isCatchException,isReturnLastData,aLog);
43 | return result;
44 | }
45 |
46 | public static Object execute(InstructionSet[] sets,
47 | InstructionSetContext context, List errorList, boolean isTrace,boolean isCatchException,
48 | boolean isReturnLastData,Log aLog) throws Exception {
49 | RunEnvironment environmen = null;
50 | Object result = null;
51 | for (int i = 0; i < sets.length; i++) {
52 | InstructionSet tmpSet = sets[i];
53 | environmen = OperateDataCacheManager.fetRunEnvironment(tmpSet,
54 | (InstructionSetContext ) context, isTrace);
55 | try {
56 | CallResult tempResult = tmpSet.excute(environmen, context,
57 | errorList, i == sets.length - 1,isReturnLastData,aLog);
58 | if (tempResult.isExit() == true) {
59 | result = tempResult.getReturnValue();
60 | break;
61 | }
62 | } catch (Exception e) {
63 | if(isCatchException == true){
64 | if (aLog != null){
65 | aLog.error(e.getMessage(), e);
66 | }else{
67 | log.error(e.getMessage(),e);
68 | }
69 | }else{
70 | throw e;
71 | }
72 | }
73 | }
74 | return result;
75 |
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/LocalExpressCacheRunner.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * 作为表达式
8 | * @author tianqiao
9 | *
10 | */
11 | public class LocalExpressCacheRunner extends ExpressRemoteCacheRunner{
12 |
13 | private static Map expressMap = new HashMap ();
14 |
15 | private ExpressRunner expressRunner;
16 |
17 | public LocalExpressCacheRunner(ExpressRunner expressRunner){
18 | this.expressRunner = expressRunner;
19 | }
20 | @Override
21 | public final Object getCache(String key) {
22 | return expressMap.get(key);
23 | }
24 |
25 | @Override
26 | public final void putCache(String key, Object object) {
27 | expressMap.put(key, object);
28 | }
29 |
30 | @Override
31 | public final ExpressRunner getExpressRunner() {
32 | return this.expressRunner;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/OperateData.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 |
4 | /**
5 | * 数据类型定义
6 | * @author qhlhl2010@gmail.com
7 | *
8 | */
9 |
10 | public class OperateData implements java.io.Serializable {
11 | private static final long serialVersionUID = 4749348640699065036L;
12 | protected Object dataObject;
13 | protected Class> type;
14 |
15 | public OperateData(Object obj, Class> aType) {
16 | this.type = aType;
17 | this.dataObject = obj;
18 | }
19 | /**
20 | * 给对象缓存接口使用
21 | * @param obj
22 | * @param aType
23 | */
24 | public void initial(Object obj, Class> aType) {
25 | this.type = aType;
26 | this.dataObject = obj;
27 | }
28 | public void clear(){
29 | this.dataObject = null;
30 | this.type = null;
31 | }
32 | public Class> getDefineType(){
33 | throw new RuntimeException(this.getClass().getName() + "必须实现方法:getDefineType");
34 | }
35 | public Class> getOrgiType(){
36 | return this.type;
37 | }
38 | public Class> getType(InstructionSetContext parent) throws Exception {
39 | if (type != null)
40 | return type;
41 |
42 | Object obj = this.getObject(parent);
43 | if (obj == null)
44 | return null;
45 | else
46 | return obj.getClass();
47 | }
48 |
49 | public final Object getObject(InstructionSetContext context) throws Exception {
50 | if(this.type != null && this.type.equals(void.class)){
51 | throw new Exception("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句");
52 | }
53 | return getObjectInner(context);
54 | }
55 | public Object getObjectInner(InstructionSetContext context) throws Exception{
56 | return this.dataObject;
57 | }
58 | public void setObject(InstructionSetContext parent, Object object) throws Exception {
59 | throw new RuntimeException("必须在子类中实现此方法");
60 | }
61 | public String toJavaCode(){
62 | if(this.getClass().equals(OperateData.class) == false){
63 | throw new RuntimeException(this.getClass().getName() + "没有实现:toJavaCode()");
64 | }
65 | String result ="new " + OperateData.class.getName() +"(";
66 | if(String.class.equals(this.type)){
67 | result = result + "\"" + this.dataObject + "\"";
68 | }else if(this.type.isPrimitive()){
69 | result = result + this.dataObject.getClass().getName() +".valueOf(\"" + this.dataObject + "\")";
70 | }else{
71 | result = result + "new " + this.dataObject.getClass().getName() + "(\"" + this.dataObject.toString() + "\")";
72 | }
73 | result = result + "," + type.getName() + ".class";
74 | result = result + ")";
75 | return result;
76 | }
77 | public String toString() {
78 | if( this.dataObject == null)
79 | return this.type + ":null";
80 | else{
81 | if(this.dataObject instanceof Class){
82 | return ExpressUtil.getClassName((Class>)this.dataObject);
83 | }else{
84 | return this.dataObject.toString();
85 | }
86 | }
87 | }
88 | public void toResource(StringBuilder builder,int level){
89 | if(this.dataObject != null){
90 | builder.append(this.dataObject.toString());
91 | }else{
92 | builder.append("null");
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/Operator.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import com.ql.util.express.instruction.OperateDataCacheManager;
4 | import com.ql.util.express.instruction.op.OperatorBase;
5 |
6 | /**
7 | * 操作符的基类
8 | * @author xuannan
9 | *
10 | */
11 | public abstract class Operator extends OperatorBase{
12 |
13 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception{
14 | Object[] parameters = new Object[list.length];
15 | for(int i = 0;i
37 | * @throws Exception
38 | */
39 | public static int compareData(Object op1,Object op2) throws Exception{
40 | int compareResult = -1;
41 |
42 | if(op1 instanceof String){
43 | compareResult = ((String)op1).compareTo(op2.toString());
44 | }else if(op2 instanceof String){
45 | compareResult = op1.toString().compareTo((String)op2);
46 | }else if(op1 instanceof Number && op2 instanceof Number){
47 | //数字比较
48 | compareResult = OperatorOfNumber.compareNumber((Number)op1, (Number)op2);
49 | }
50 | else if ((op1 instanceof Boolean) && (op2 instanceof Boolean))
51 | {
52 | if (((Boolean)op1).booleanValue() ==((Boolean)op2).booleanValue())
53 | compareResult =0;
54 | else
55 | compareResult =-1;
56 | }
57 | else
58 | throw new Exception(op1 + "和" + op2 +"不能执行compare 操作");
59 | return compareResult;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/Rule.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | /**
4 | * 自定义规则内容
5 | *
6 | * @author wanglei
7 | * @version 1.0
8 | * @taskId
9 | * @CreateDate 2015年1月26日
10 | */
11 | public class Rule {
12 | private Integer id;
13 |
14 | private String ruleName;
15 |
16 | // 优先级,越大执行优先级越高
17 | private Integer priority;
18 |
19 | private Integer groupType;
20 |
21 | private String groupName;
22 |
23 | // 规则匹配判断条件-表达式
24 | private String matchCondition;
25 |
26 | // 规则匹配执行内容-表达式
27 | private String executeContent;
28 |
29 | public Integer getId() {
30 | return id;
31 | }
32 |
33 | public void setId(Integer id) {
34 | this.id = id;
35 | }
36 |
37 | public String getRuleName() {
38 | return ruleName;
39 | }
40 |
41 | public void setRuleName(String ruleName) {
42 | this.ruleName = ruleName;
43 | }
44 |
45 | public Integer getPriority() {
46 | return priority;
47 | }
48 |
49 | public void setPriority(Integer priority) {
50 | this.priority = priority;
51 | }
52 |
53 | public Integer getGroupType() {
54 | return groupType;
55 | }
56 |
57 | public void setGroupType(Integer groupType) {
58 | this.groupType = groupType;
59 | }
60 |
61 | public String getGroupName() {
62 | return groupName;
63 | }
64 |
65 | public void setGroupName(String groupName) {
66 | this.groupName = groupName;
67 | }
68 |
69 | public String getMatchCondition() {
70 | return matchCondition;
71 | }
72 |
73 | public void setMatchCondition(String matchCondition) {
74 | this.matchCondition = matchCondition;
75 | }
76 |
77 | public String getExecuteContent() {
78 | return executeContent;
79 | }
80 |
81 | public void setExecuteContent(String executeContent) {
82 | this.executeContent = executeContent;
83 | }
84 |
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/RuleContext.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 | /**
3 | *
4 | * 规则上下文
5 | *
6 | * @author wanglei
7 | * @version 1.0
8 | * @taskId
9 | * @CreateDate 2015年1月24日
10 | */
11 | public class RuleContext extends DefaultContext {
12 | /**
13 | * serialVersionUID
14 | */
15 | private static final long serialVersionUID = 20150124L;
16 | private Integer groupType;
17 | private String groupName;
18 | public Integer getGroupType() {
19 | return groupType;
20 | }
21 | public void setGroupType(Integer groupType) {
22 | this.groupType = groupType;
23 | }
24 | public String getGroupName() {
25 | return groupName;
26 | }
27 | public void setGroupName(String groupName) {
28 | this.groupName = groupName;
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/RuleRunner.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collections;
5 | import java.util.Comparator;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | import javax.annotation.Resource;
11 |
12 | import com.ql.util.express.dao.RuleMapper;
13 |
14 | /**
15 | *
16 | * 规则调度-执行
17 | *
18 | * @author wanglei
19 | * @version 1.0
20 | * @taskId
21 | * @CreateDate 2015年1月26日
22 | */
23 | public class RuleRunner{
24 | //表达式执行器
25 | private ExpressRunner expressRunner = new ExpressRunner();
26 | //全部规则
27 | private List ruleList;
28 | //各种组别的规则的缓存
29 | private Map> rulesCache = new HashMap>();
30 | @Resource
31 | private RuleMapper ruleMapper;
32 | /**
33 | *
34 | * Description:规则调度
35 | *
36 | * @author wanglei
37 | * @taskId
38 | * @param ruleList
39 | * @param ruleContext
40 | * @return
41 | * @throws Exception
42 | */
43 | public boolean dispatch(RuleContext ruleContext) throws Exception {
44 | // 延迟初始化
45 | if(null == ruleList) {
46 | synchronized(this) {
47 | if(null == ruleList) {
48 | ruleList = ruleMapper.getRuleList();
49 | }
50 | }
51 | }
52 | //如果规则为空,则返回true
53 | if(null == ruleList || 0 ==ruleList.size()) {
54 | return true;
55 | }
56 | //如果规则不为空,且规则上下文为null,返回false
57 | if(null == ruleContext) {
58 | return false;
59 | }
60 | //获取并缓存基于组别的适应的规则
61 | List rules = this.obtainRulesWithCache(ruleContext.getGroupType());
62 | //匹配并执行匹配的规则
63 | this.executeRules(rules, ruleContext);
64 | return true;
65 | }
66 |
67 | /**
68 | *
69 | * Description:筛选并对规则按照优先级排序
70 | *
71 | * @author wanglei
72 | * @taskId
73 | * @param ruleList
74 | * @param groupType
75 | * @return
76 | */
77 | private List obtainRulesWithCache(Integer groupType) {
78 | List rules = rulesCache.get(groupType);
79 | if(null == rules) {
80 | rules = new ArrayList();
81 | //筛选规则
82 | for(Rule rule : ruleList) {
83 | if(groupType == rule.getGroupType()) {
84 | rules.add(rule);
85 | }
86 | }
87 | //按照优先级排序
88 | Collections.sort(rules, new Comparator(){
89 | @Override
90 | public int compare(Object o1, Object o2) {
91 | Rule rule1 = (Rule)o1;
92 | Rule rule2 = (Rule)o2;
93 | return rule1.getGroupType().compareTo(rule2.getGroupType());
94 | }
95 | });
96 | rulesCache.put(groupType, rules);
97 | }
98 | return rules;
99 | }
100 |
101 | /**
102 | *
103 | * Description:规则匹配并执行
104 | *
105 | * @author wanglei
106 | * @taskId
107 | * @param rules
108 | * @param ruleContext
109 | * @throws Exception
110 | */
111 | private void executeRules(List rules,RuleContext ruleContext) throws Exception {
112 | for(Rule rule : rules) {
113 | //如果规则匹配,则执行
114 | Boolean result = (Boolean)expressRunner.execute(rule.getMatchCondition(), ruleContext, null, true, false);
115 | if(result) {
116 | expressRunner.execute(rule.getExecuteContent(), ruleContext, null, true, false);
117 | }
118 | }
119 | }
120 |
121 | /**
122 | *
123 | * Description:刷新规则内容
124 | *
125 | * @author wanglei
126 | * @taskId
127 | */
128 | public synchronized void refreshRules() {
129 | ruleList = ruleMapper.getRuleList();
130 | rulesCache = new HashMap>();
131 | }
132 |
133 | public List getRuleList() {
134 | return ruleList;
135 | }
136 |
137 | public void setRuleList(List ruleList) {
138 | this.ruleList = ruleList;
139 | }
140 |
141 | public ExpressRunner getExpressRunner() {
142 | return expressRunner;
143 | }
144 |
145 | public void setExpressRunner(ExpressRunner expressRunner) {
146 | this.expressRunner = expressRunner;
147 | }
148 |
149 | public RuleMapper getRuleMapper() {
150 | return ruleMapper;
151 | }
152 |
153 | public void setRuleMapper(RuleMapper ruleMapper) {
154 | this.ruleMapper = ruleMapper;
155 | }
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/RunEnvironment.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express;
2 |
3 |
4 |
5 | public class RunEnvironment {
6 | private static int INIT_DATA_LENTH = 15;
7 | private boolean isTrace = false;
8 | private int point = -1;
9 | private int programPoint = 0;
10 | private OperateData[] dataContainer;
11 |
12 | private boolean isExit = false;
13 | private Object returnValue = null;
14 |
15 | private InstructionSet instructionSet;
16 | private InstructionSetContext context;
17 |
18 |
19 | public RunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){
20 | dataContainer = new OperateData[INIT_DATA_LENTH];
21 | this.instructionSet = aInstructionSet;
22 | this.context = aContext;
23 | this.isTrace = aIsTrace;
24 | }
25 |
26 | public void initial(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){
27 | dataContainer = new OperateData[INIT_DATA_LENTH];
28 | this.instructionSet = aInstructionSet;
29 | this.context = aContext;
30 | this.isTrace = aIsTrace;
31 | }
32 | public void clear(){
33 | isTrace = false;
34 | point = -1;
35 | programPoint = 0;
36 | dataContainer = null;
37 |
38 | isExit = false;
39 | returnValue = null;
40 |
41 | instructionSet = null;
42 | context = null;
43 |
44 | }
45 | public InstructionSet getInstructionSet() {
46 | return instructionSet;
47 | }
48 |
49 |
50 | public InstructionSetContext getContext(){
51 | return this.context;
52 | }
53 | public void setContext(InstructionSetContext aContext){
54 | this.context = aContext;
55 | }
56 |
57 | public boolean isExit() {
58 | return isExit;
59 | }
60 | public Object getReturnValue() {
61 | return returnValue;
62 | }
63 | public void setReturnValue(Object value){
64 | this.returnValue = value;
65 | }
66 | public void quitExpress(Object aReturnValue){
67 | this.isExit = true;
68 | this.returnValue = aReturnValue;
69 | }
70 | public void quitExpress(){
71 | this.isExit = true;
72 | this.returnValue = null;
73 | }
74 | public boolean isTrace(){
75 | return this.isTrace;
76 | }
77 | public int getProgramPoint() {
78 | return programPoint;
79 | }
80 | public void programPointAddOne() {
81 | programPoint ++ ;
82 | }
83 | public int getDataStackSize(){
84 | return this.point + 1;
85 | }
86 | public void push(OperateData data){
87 | this.point++;
88 | if(this.point >= this.dataContainer.length){
89 | ensureCapacity(this.point + 1);
90 | }
91 | this.dataContainer[point] = data;
92 | }
93 | public OperateData peek(){
94 | if(point <0){
95 | throw new RuntimeException("系统异常,堆栈指针错误");
96 | }
97 | return this.dataContainer[point];
98 | }
99 | public OperateData pop(){
100 | if(point <0)
101 | throw new RuntimeException("系统异常,堆栈指针错误");
102 | OperateData result = this.dataContainer[point];
103 | this.point--;
104 | return result;
105 | }
106 | public void clearDataStack(){
107 | this.point = -1;
108 | }
109 | public void gotoWithOffset(int aOffset ){
110 | this.programPoint = this.programPoint + aOffset;
111 | }
112 | /**
113 | * 此方法是调用最频繁的,因此尽量精简代码,提高效率
114 | * @param context
115 | * @param len
116 | * @return
117 | * @throws Exception
118 | */
119 | public OperateData[] popArray(InstructionSetContext context,int len) throws Exception {
120 | int start = point - len + 1;
121 | OperateData[] result = new OperateData[len];
122 | System.arraycopy(this.dataContainer,start, result,0, len);
123 | point = point - len;
124 | return result;
125 | }
126 | public OperateData[] popArrayBackUp(InstructionSetContext context,int len) throws Exception {
127 | int start = point - len + 1;
128 | if(start <0){
129 | throw new Exception("堆栈溢出,请检查表达式是否错误");
130 | }
131 | OperateData[] result = new OperateData[len];
132 | for (int i = 0 ; i < len; i++) {
133 | result[i] = this.dataContainer[start + i];
134 | if(void.class.equals(result[i].getType(context))){
135 | throw new Exception("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句");
136 | }
137 | }
138 | point = point - len;
139 | return result;
140 | }
141 |
142 | public void ensureCapacity(int minCapacity) {
143 | int oldCapacity = this.dataContainer.length;
144 | if (minCapacity > oldCapacity) {
145 | int newCapacity = (oldCapacity * 3) / 2 + 1;
146 | if (newCapacity < minCapacity){
147 | newCapacity = minCapacity;
148 | }
149 | OperateData[] tempList = new OperateData[newCapacity];
150 | System.arraycopy(this.dataContainer,0,tempList,0,oldCapacity);
151 | this.dataContainer = tempList;
152 | }
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/dao/RuleMapper.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.dao;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.ibatis.annotations.Select;
6 |
7 | import com.ql.util.express.Rule;
8 | /**
9 | *
10 | * 从数据库中获取规则mapper
11 | *
12 | * @author wanglei
13 | * @version 1.0
14 | * @taskId
15 | * @CreateDate 2015年1月26日
16 | */
17 | public interface RuleMapper {
18 | @Select({"select id,rule_name ruleName,priority,group_type groupType,group_name groupName,match_condition matchCondition,execute_content executeContent from rule where del_flag=0"})
19 | public List getRuleList();
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/BlockInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionClearDataStack;
8 | import com.ql.util.express.instruction.detail.InstructionCloseNewArea;
9 | import com.ql.util.express.instruction.detail.InstructionOpenNewArea;
10 | import com.ql.util.express.parse.ExpressNode;
11 |
12 | public class BlockInstructionFactory extends InstructionFactory {
13 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
14 | Stack forStack, ExpressNode node,boolean isRoot)
15 | throws Exception {
16 | if (node.isTypeEqualsOrChild("STAT_SEMICOLON")
17 | &&result.getCurrentPoint() >=0 && result.getInstruction(result.getCurrentPoint()) instanceof InstructionClearDataStack == false) {
18 | result.addInstruction(new InstructionClearDataStack());
19 | }
20 |
21 | int tmpPoint = result.getCurrentPoint()+1;
22 | boolean returnVal = false;
23 | boolean hasDef = false;
24 | for(ExpressNode tmpNode : node.getChildren()){
25 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
26 | hasDef = hasDef || tmpHas;
27 | }
28 | if (hasDef == true&& isRoot == false
29 | && node.getTreeType().isEqualsOrChild("STAT_BLOCK")){
30 | result.insertInstruction(tmpPoint,new InstructionOpenNewArea());
31 | result.insertInstruction(result.getCurrentPoint() + 1,new InstructionCloseNewArea());
32 | returnVal = false;
33 | }else{
34 | returnVal = hasDef;
35 | }
36 | return returnVal;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/BreakInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionGoTo;
8 | import com.ql.util.express.parse.ExpressNode;
9 |
10 | public class BreakInstructionFactory extends InstructionFactory {
11 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
12 | Stack forStack, ExpressNode node,boolean isRoot)
13 | throws Exception {
14 | InstructionGoTo breakInstruction = new InstructionGoTo(result.getCurrentPoint()+1);
15 | breakInstruction.name = "break";
16 | forStack.peek().breakList.add(breakInstruction);
17 | result.addInstruction(breakInstruction);
18 | return false;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/CallFunctionInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionCallSelfDefineFunction;
8 | import com.ql.util.express.instruction.detail.InstructionOperator;
9 | import com.ql.util.express.instruction.op.OperatorBase;
10 | import com.ql.util.express.parse.ExpressNode;
11 |
12 |
13 | public class CallFunctionInstructionFactory extends InstructionFactory{
14 | public boolean createInstruction(ExpressRunner aCompile,
15 | InstructionSet result, Stack forStack,
16 | ExpressNode node, boolean isRoot) throws Exception {
17 | ExpressNode[] children = node.getChildren();
18 | String functionName = children[0].getValue();
19 | boolean returnVal = false;
20 | children = node.getChildren();
21 | for (int i = 1; i < children.length; i++) {
22 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,
23 | forStack, children[i], false);
24 | returnVal = returnVal || tmpHas;
25 | }
26 |
27 | OperatorBase op = aCompile.getOperatorFactory().getOperator(
28 | functionName);
29 | int opNum = children.length -1;
30 | if (op != null) {
31 | result.addInstruction(new InstructionOperator(op,opNum ));
32 | } else {
33 | result.addInstruction(new InstructionCallSelfDefineFunction(
34 | functionName,opNum));
35 | }
36 | return returnVal;
37 | }
38 | }
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/CastInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionOperator;
8 | import com.ql.util.express.instruction.op.OperatorBase;
9 | import com.ql.util.express.parse.ExpressNode;
10 |
11 |
12 | public class CastInstructionFactory extends InstructionFactory{
13 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack forStack, ExpressNode node,boolean isRoot)
14 | throws Exception {
15 | boolean returnVal = false;
16 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
17 | ExpressNode[] children = node.getChildren();
18 | if(children.length ==0){
19 | throw new Exception("扩展类型不存在");
20 | }else if(children.length > 2) {
21 | throw new Exception("扩展操作只能有一个类型为Class的操作数");
22 | }else if(children[0].getNodeType().isEqualsOrChild("CONST_CLASS") == false){
23 | throw new Exception("扩展操作只能有一个类型为Class的操作数,当前的数据类型是:" + children[0].getNodeType().getName());
24 | }
25 |
26 | for(int i =0;i < children.length;i++){
27 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,children[i],false);
28 | returnVal = returnVal || tmpHas;
29 | }
30 | result.addInstruction(new InstructionOperator(op,children.length));
31 | return returnVal;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/ConstDataInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.OperateData;
8 | import com.ql.util.express.instruction.detail.InstructionConstData;
9 | import com.ql.util.express.instruction.opdata.OperateClass;
10 | import com.ql.util.express.parse.ExpressNode;
11 |
12 | public class ConstDataInstructionFactory extends InstructionFactory {
13 | public OperateData genOperateData(ExpressNode node) {
14 | if (node.isTypeEqualsOrChild("CONST_CLASS")) {
15 | return new OperateClass(node.getValue(), (Class>) node.getObjectValue());
16 | } else {
17 | return new OperateData(node.getObjectValue(), node.getObjectValue().getClass());
18 | }
19 | }
20 |
21 | public boolean createInstruction(ExpressRunner aCompile,
22 | InstructionSet result, Stack forStack,
23 | ExpressNode node, boolean isRoot) throws Exception {
24 | result.addInstruction(new InstructionConstData(genOperateData(node)));
25 | return false;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/ContinueInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionGoTo;
8 | import com.ql.util.express.parse.ExpressNode;
9 |
10 | public class ContinueInstructionFactory extends InstructionFactory {
11 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
12 | Stack forStack, ExpressNode node,boolean isRoot)
13 | throws Exception {
14 | InstructionGoTo continueInstruction = new InstructionGoTo(result.getCurrentPoint()+1);
15 | continueInstruction.name = "continue";
16 | forStack.peek().continueList.add(continueInstruction);
17 | result.addInstruction(continueInstruction);
18 | return false;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/DefineInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.ExpressUtil;
7 | import com.ql.util.express.InstructionSet;
8 | import com.ql.util.express.instruction.detail.InstructionOperator;
9 | import com.ql.util.express.instruction.op.OperatorBase;
10 | import com.ql.util.express.parse.ExpressNode;
11 |
12 |
13 | class DefineInstructionFactory extends InstructionFactory{
14 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack forStack, ExpressNode node,boolean isRoot)
15 | throws Exception {
16 | boolean returnVal = false;
17 | ExpressNode[] children = node.getChildren();
18 | int [] finishPoint = new int[children.length];
19 | int arrayDimeCount =0;
20 | String tempStr="";
21 | for(int i = children.length - 2;i>0;i--){
22 | ExpressNode tmpNode = children[i];
23 | if(tmpNode.isTypeEqualsOrChild("[]")){
24 | arrayDimeCount = arrayDimeCount +1;
25 | node.getLeftChildren().remove(i);
26 | tempStr = tempStr +"[]";
27 | }else{
28 | throw new Exception("不正确的类型定义");
29 | }
30 | }
31 | if(arrayDimeCount > 0){
32 | node.getLeftChildren().get(0).setValue(node.getLeftChildren().get(0).getValue() + tempStr);
33 | node.getLeftChildren().get(0).setOrgiValue(node.getLeftChildren().get(0).getOrgiValue() + tempStr);
34 | Object objValue = node.getLeftChildren().get(0).getObjectValue();
35 | if(objValue instanceof Class){
36 | Class> tmpClass = ExpressUtil.getJavaClass(ExpressUtil.getClassName((Class>)objValue) + tempStr);
37 | node.getLeftChildren().get(0).setObjectValue(tmpClass);
38 | }else{
39 | node.getLeftChildren().get(0).setObjectValue(node.getLeftChildren().get(0).getObjectValue()+ tempStr);
40 | }
41 | }
42 |
43 | children = node.getChildren();
44 | for(int i =0;i < children.length;i++){
45 | ExpressNode tmpNode = children[i];
46 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
47 | returnVal = returnVal || tmpHas;
48 | finishPoint[i] = result.getCurrentPoint();
49 | }
50 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
51 | result.addInstruction(new InstructionOperator(op, children.length));
52 | returnVal = true;
53 | return returnVal;
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/ForInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionCloseNewArea;
8 | import com.ql.util.express.instruction.detail.InstructionGoTo;
9 | import com.ql.util.express.instruction.detail.InstructionGoToWithCondition;
10 | import com.ql.util.express.instruction.detail.InstructionOpenNewArea;
11 | import com.ql.util.express.parse.ExpressNode;
12 |
13 | public class ForInstructionFactory extends InstructionFactory {
14 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
15 | Stack forStack, ExpressNode node,boolean isRoot)
16 | throws Exception {
17 | if(node.getChildren().length < 2){
18 | throw new Exception("for 操作符至少需要2个操作数 " );
19 | }else if(node.getChildren().length > 2){
20 | throw new Exception("for 操作符最多只有2个操作数 " );
21 | }
22 | if(node.getChildren()[0].getChildren()!= null && node.getChildren()[0].getChildren().length > 3){
23 | throw new Exception("循环语句的设置不合适:" + node.getChildren()[0]);
24 | }
25 | //生成作用域开始指令
26 | result.addInstruction(new InstructionOpenNewArea());
27 | forStack.push(new ForRelBreakContinue());
28 |
29 | //生成条件语句部分指令
30 | ExpressNode conditionNode = node.getChildren()[0];
31 | int nodePoint = 0;
32 | if (conditionNode.getChildren() != null && conditionNode.getChildren().length == 3){//变量定义,判断,自增都存在
33 | int tempPoint = result.getCurrentPoint();
34 | aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[0],false);
35 | if(result.getCurrentPoint() > tempPoint){
36 | nodePoint = nodePoint + 1;
37 | }
38 | }
39 | //循环的开始的位置
40 | int loopStartPoint = result.getCurrentPoint()+ 1;
41 |
42 | //有条件语句
43 | InstructionGoToWithCondition conditionInstruction=null;
44 | if(conditionNode.getChildren() != null
45 | && (conditionNode.getChildren().length == 1
46 | || conditionNode.getChildren().length == 2
47 | || conditionNode.getChildren().length == 3)
48 | ) {
49 | aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[nodePoint],false);
50 | //跳转的位置需要根据后续的指令情况决定
51 | conditionInstruction = new InstructionGoToWithCondition(false,-1,true);
52 | result.insertInstruction(result.getCurrentPoint()+1,conditionInstruction);
53 | nodePoint = nodePoint+ 1;
54 | }
55 | int conditionPoint = result.getCurrentPoint();
56 | //生成循环体的代码
57 | aCompile.createInstructionSetPrivate(result,forStack,node.getChildren()[1],false);
58 |
59 | int selfAddPoint = result.getCurrentPoint()+1;
60 | //生成自增代码指令
61 | if(conditionNode.getChildren()!= null &&(
62 | conditionNode.getChildren().length == 2 || conditionNode.getChildren().length == 3
63 | )){
64 | aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[nodePoint],false);
65 | }
66 | //增加一个无条件跳转
67 | InstructionGoTo reStartGoto = new InstructionGoTo(loopStartPoint - (result.getCurrentPoint() + 1));
68 | result.addInstruction(reStartGoto);
69 |
70 | //修改条件判断的跳转位置
71 | if(conditionInstruction != null){
72 | conditionInstruction.setOffset( result.getCurrentPoint() - conditionPoint + 1);
73 | }
74 |
75 | //修改Break和Continue指令的跳转位置,循环出堆
76 | ForRelBreakContinue rel = forStack.pop();
77 | for(InstructionGoTo item:rel.breakList){
78 | item.setOffset(result.getCurrentPoint() - item.getOffset()) ;
79 | }
80 | for(InstructionGoTo item:rel.continueList){
81 | item.setOffset(selfAddPoint - item.getOffset() - 1);
82 | }
83 |
84 | //生成作用域结束指令
85 | result.addInstruction(new InstructionCloseNewArea());
86 |
87 | return false;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/ForRelBreakContinue.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.ql.util.express.instruction.detail.InstructionGoTo;
7 |
8 | public class ForRelBreakContinue{
9 | List breakList = new ArrayList();
10 | List continueList = new ArrayList();
11 |
12 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/FunctionInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
8 | import com.ql.util.express.parse.ExpressNode;
9 |
10 | public class FunctionInstructionFactory extends InstructionFactory {
11 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
12 | Stack forStack, ExpressNode node,boolean isRoot)
13 | throws Exception {
14 | ExpressNode[] children = node.getChildren();
15 | if(children.length != 3){
16 | throw new Exception("funciton 操作符需要3个操作数 " );
17 | }
18 | String functionName =children[0].getValue();
19 | ExpressNode[] varDefines = children[1].getChildren();
20 | int point =0;
21 |
22 | String instructionSetType ="";
23 | if (node.isTypeEqualsOrChild("class")) {
24 | instructionSetType = InstructionSet.TYPE_CLASS;
25 | } else {
26 | instructionSetType = InstructionSet.TYPE_FUNCTION;
27 | }
28 | InstructionSet functionSet = new InstructionSet(instructionSetType);
29 |
30 | while(point varClass = (Class>)varDefines[point].getChildren()[0].getObjectValue();
35 | String varName = varDefines[point].getChildren()[1].getValue();
36 | OperateDataLocalVar tmpVar = new OperateDataLocalVar(varName,varClass);
37 | functionSet.addParameter(tmpVar);
38 | point = point + 1;
39 | }
40 |
41 | ExpressNode functionRoot = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("FUNCTION_DEFINE"),"function-" + functionName);
42 | for(ExpressNode tempNode : children[2].getChildren()){
43 | functionRoot.addLeftChild(tempNode);
44 | }
45 | aCompile.createInstructionSet(functionRoot,functionSet);
46 | result.addMacroDefine(functionName, new FunctionInstructionSet(functionName,instructionSetType,functionSet));
47 | return false;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/FunctionInstructionSet.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.io.Serializable;
4 |
5 | import com.ql.util.express.InstructionSet;
6 |
7 |
8 | public class FunctionInstructionSet implements Serializable{
9 | private static final long serialVersionUID = 8735208809492617401L;
10 | public String name;
11 | public String type;
12 | public InstructionSet instructionSet;
13 | public FunctionInstructionSet(String aName,String aType,InstructionSet aInstructionSet){
14 | this.name = aName;
15 | this.type = aType;
16 | this.instructionSet = aInstructionSet;
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/IOperateDataCache.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import com.ql.util.express.CallResult;
4 | import com.ql.util.express.ExpressLoader;
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.IExpressContext;
7 | import com.ql.util.express.InstructionSet;
8 | import com.ql.util.express.InstructionSetContext;
9 | import com.ql.util.express.OperateData;
10 | import com.ql.util.express.RunEnvironment;
11 | import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
12 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
13 | import com.ql.util.express.instruction.opdata.OperateDataField;
14 | import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
15 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
16 |
17 | interface IOperateDataCache {
18 | public OperateData fetchOperateData(Object obj, Class> aType);
19 | public OperateDataAttr fetchOperateDataAttr(String name, Class> aType);
20 | public OperateDataLocalVar fetchOperateDataLocalVar(String name, Class> aType);
21 | public OperateDataField fetchOperateDataField(Object aFieldObject,String aFieldName);
22 | public OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject,int aIndex);
23 | public OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue);
24 | public RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace);
25 | public CallResult fetchCallResult(Object aReturnValue,boolean aIsExit);
26 | public InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName);
27 | public void resetCache();
28 | public long getFetchCount();
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/IfInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionGoTo;
8 | import com.ql.util.express.instruction.detail.InstructionGoToWithCondition;
9 | import com.ql.util.express.parse.ExpressNode;
10 |
11 | public class IfInstructionFactory extends InstructionFactory {
12 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
13 | Stack forStack, ExpressNode node,boolean isRoot)
14 | throws Exception {
15 | ExpressNode[] oldChildren = node.getChildren();
16 | if(oldChildren.length < 2){
17 | throw new Exception("if 操作符至少需要2个操作数 " );
18 | }else if(oldChildren.length > 5){
19 | throw new Exception("if 操作符最多只有5个操作数 " );
20 | }
21 | ExpressNode[] children = new ExpressNode[3];
22 | int point = 0;
23 | for(int i=0;i forStack,
15 | ExpressNode node, boolean isRoot) throws Exception {
16 | ExpressNode[] children = node.getChildren();
17 | if (children[1].isTypeEqualsOrChild("CHILD_EXPRESS")) {
18 | node.getLeftChildren().remove(1);
19 | ExpressNode[] parameterList = children[1].getChildren();
20 | for (int i = 0; i < parameterList.length; i++) {
21 | node.getLeftChildren().add(parameterList[i]);
22 | }
23 | }
24 |
25 | boolean returnVal = false;
26 | children = node.getChildren();
27 | for (int i = 0; i < children.length; i++) {
28 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
29 | returnVal = returnVal || tmpHas;
30 | }
31 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
32 | result.addInstruction(new InstructionOperator(op, children.length));
33 | return returnVal;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/InstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.Stack;
6 |
7 | import com.ql.util.express.ExpressRunner;
8 | import com.ql.util.express.InstructionSet;
9 | import com.ql.util.express.parse.ExpressNode;
10 |
11 | public abstract class InstructionFactory {
12 | private static Map instructionFactory = new HashMap();
13 |
14 | public static InstructionFactory getInstructionFactory(String factory) {
15 | try {
16 | InstructionFactory result = instructionFactory.get(factory);
17 | if (result == null) {
18 | result = (InstructionFactory) Class.forName(factory)
19 | .newInstance();
20 | }
21 | return result;
22 | } catch (Exception e) {
23 | throw new RuntimeException(e);
24 | }
25 | }
26 | public abstract boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
27 | Stack forStack, ExpressNode node,boolean isRoot)
28 | throws Exception;
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/KeyValueInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionOperator;
8 | import com.ql.util.express.instruction.op.OperatorBase;
9 | import com.ql.util.express.parse.ExpressNode;
10 |
11 |
12 | class KeyValueInstructionFactory extends InstructionFactory{
13 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack forStack, ExpressNode node,boolean isRoot)
14 | throws Exception {
15 | boolean returnVal = false;
16 | ExpressNode[] children = node.getChildren();
17 | if( node.getParent() != null && node.getParent().isTypeEqualsOrChild("STATEMENT")){
18 | children[0].setNodeType(aCompile.getNodeTypeManager().findNodeType("CONST_STRING"));
19 | children[0].setTreeType(aCompile.getNodeTypeManager().findNodeType("CONST"));
20 | children[0].setObjectValue(children[0].getValue());
21 | }
22 | if( node.getParent() != null && node.getParent().isTypeEqualsOrChild("STATEMENT") && children[1].isTypeEqualsOrChild("STAT_BLOCK")){
23 | returnVal = new MacroInstructionFactory().createInstruction(aCompile, result, forStack, node, isRoot);
24 | } else if (node.getParent() != null&& node.getParent().isTypeEqualsOrChild("STATEMENT")) {
25 | for(int i =0;i < children.length;i++){
26 | ExpressNode tmpNode = children[i];
27 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
28 | returnVal = returnVal || tmpHas;
29 | }
30 | OperatorBase op = aCompile.getOperatorFactory().newInstance("alias");
31 | result.addInstruction(new InstructionOperator(op, children.length));
32 | returnVal = true;
33 | }else{
34 | for(int i =0;i < children.length;i++){
35 | ExpressNode tmpNode = children[i];
36 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
37 | returnVal = returnVal || tmpHas;
38 | }
39 |
40 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
41 | result.addInstruction(new InstructionOperator(op,children.length));
42 | }
43 | return returnVal;
44 | }
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/LoadAttrInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionCallMacro;
8 | import com.ql.util.express.instruction.detail.InstructionLoadAttr;
9 | import com.ql.util.express.parse.ExpressNode;
10 |
11 |
12 | public class LoadAttrInstructionFactory extends InstructionFactory {
13 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
14 | Stack forStack, ExpressNode node,boolean isRoot)
15 | throws Exception{
16 | FunctionInstructionSet functionSet = result.getMacroDefine(node.getValue());
17 | if(functionSet != null){//是宏定义
18 | result.insertInstruction(result.getCurrentPoint()+1, new InstructionCallMacro(node.getValue()));
19 | }else{
20 | result.addInstruction(new InstructionLoadAttr(node.getValue()));
21 | if(node.getChildren().length >0){
22 | throw new Exception("表达式设置错误");
23 | }
24 | }
25 | return false;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/MacroInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.parse.ExpressNode;
8 |
9 | public class MacroInstructionFactory extends InstructionFactory {
10 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
11 | Stack forStack, ExpressNode node,boolean isRoot)
12 | throws Exception {
13 | ExpressNode[] children = node.getChildren();
14 | String macroName =children[0].getValue();
15 | ExpressNode macroRoot = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("FUNCTION_DEFINE"),"macro-" + macroName);
16 | for(ExpressNode tempNode : children[1].getChildren()){
17 | macroRoot.addLeftChild(tempNode);
18 | }
19 | InstructionSet macroInstructionSet = aCompile.createInstructionSet(macroRoot,InstructionSet.TYPE_MARCO);
20 | result.addMacroDefine(macroName, new FunctionInstructionSet(macroName,"macro",macroInstructionSet));
21 | return false;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/MethodCallInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionOperator;
8 | import com.ql.util.express.instruction.op.OperatorBase;
9 | import com.ql.util.express.parse.ExpressNode;
10 |
11 |
12 | public class MethodCallInstructionFactory extends InstructionFactory {
13 | public boolean createInstruction(ExpressRunner aCompile,
14 | InstructionSet result, Stack forStack,
15 | ExpressNode node, boolean isRoot) throws Exception {
16 | boolean returnVal = false;
17 | ExpressNode[] children = node.getChildren();
18 | for (int i = 0; i < children.length; i++) {
19 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
20 | returnVal = returnVal || tmpHas;
21 | }
22 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
23 | result.addInstruction(new InstructionOperator(op, children.length));
24 | return returnVal;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/NewInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.ExpressUtil;
7 | import com.ql.util.express.InstructionSet;
8 | import com.ql.util.express.instruction.detail.InstructionOperator;
9 | import com.ql.util.express.instruction.op.OperatorBase;
10 | import com.ql.util.express.parse.ExpressNode;
11 |
12 |
13 | public class NewInstructionFactory extends InstructionFactory{
14 | public boolean createInstruction(ExpressRunner aCompile,
15 | InstructionSet result, Stack forStack,
16 | ExpressNode node, boolean isRoot) throws Exception {
17 | OperatorBase op = aCompile.getOperatorFactory().newInstance("new");
18 | ExpressNode[] children = node.getChildren();
19 | if (node.isTypeEqualsOrChild("NEW_ARRAY")) {
20 | String tempStr = children[0].getValue();
21 | for (int i = 0; i < children.length - 1; i++) {
22 | tempStr = tempStr + "[]";
23 | }
24 | children[0].setValue(tempStr);
25 | children[0].setOrgiValue(tempStr);
26 | children[0].setObjectValue(ExpressUtil.getJavaClass(tempStr));
27 | }else if (node.isTypeEqualsOrChild("anonymousNewArray")) {
28 | op = aCompile.getOperatorFactory().newInstance("anonymousNewArray");
29 | }
30 |
31 | boolean returnVal = false;
32 | children = node.getChildren();// 需要重新获取数据
33 | for (int i = 0; i < children.length; i++) {
34 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
35 | returnVal = returnVal || tmpHas;
36 | }
37 | result.addInstruction(new InstructionOperator(op, children.length));
38 | return returnVal;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/NewVClassInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.instruction.detail.InstructionNewVirClass;
8 | import com.ql.util.express.parse.ExpressNode;
9 |
10 |
11 | public class NewVClassInstructionFactory extends InstructionFactory{
12 | public boolean createInstruction(ExpressRunner aCompile,
13 | InstructionSet result, Stack forStack,
14 | ExpressNode node, boolean isRoot) throws Exception {
15 | ExpressNode[] children = node.getChildren();
16 | boolean returnVal = false;
17 | String virClassName = children[0].getValue();
18 | for (int i = 1; i < children.length; i++) {
19 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
20 | returnVal = returnVal || tmpHas;
21 | }
22 | result.addInstruction(new InstructionNewVirClass(virClassName, children.length -1));
23 | return returnVal;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/NullInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.InstructionSet;
7 | import com.ql.util.express.parse.ExpressNode;
8 |
9 | public class NullInstructionFactory extends InstructionFactory {
10 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
11 | Stack forStack, ExpressNode node,boolean isRoot)
12 | throws Exception {
13 | return false;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/OperateDataCacheImpl4Orig.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import com.ql.util.express.CallResult;
4 | import com.ql.util.express.ExpressLoader;
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.IExpressContext;
7 | import com.ql.util.express.InstructionSet;
8 | import com.ql.util.express.InstructionSetContext;
9 | import com.ql.util.express.OperateData;
10 | import com.ql.util.express.RunEnvironment;
11 | import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
12 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
13 | import com.ql.util.express.instruction.opdata.OperateDataField;
14 | import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
15 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
16 |
17 |
18 | class OperateDataCacheImpl4Orig implements IOperateDataCache {
19 |
20 | public OperateData fetchOperateData(Object obj, Class> aType) {
21 | return new OperateData(obj,aType);
22 | }
23 | public OperateDataAttr fetchOperateDataAttr(String name, Class> aType) {
24 | return new OperateDataAttr(name, aType);
25 | }
26 | public OperateDataLocalVar fetchOperateDataLocalVar(String name, Class> aType) {
27 | return new OperateDataLocalVar(name, aType);
28 | }
29 | public OperateDataField fetchOperateDataField(Object aFieldObject,String aFieldName){
30 | return new OperateDataField(aFieldObject, aFieldName);
31 | }
32 | public OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject,int aIndex){
33 | return new OperateDataArrayItem(aArrayObject, aIndex);
34 | }
35 | public OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue){
36 | return new OperateDataKeyValue(aKey, aValue);
37 | }
38 |
39 | public RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){
40 | return new RunEnvironment(aInstructionSet, aContext, aIsTrace);
41 | }
42 | public CallResult fetchCallResult(Object aReturnValue,boolean aIsExit){
43 | return new CallResult(aReturnValue, aIsExit);
44 | }
45 | public InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
46 | return new InstructionSetContext(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
47 | }
48 |
49 | public void resetCache(){
50 |
51 | }
52 | public long getFetchCount(){
53 | return 0;
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/OperateDataCacheManager.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import com.ql.util.express.CallResult;
4 | import com.ql.util.express.ExpressLoader;
5 | import com.ql.util.express.ExpressRunner;
6 | import com.ql.util.express.IExpressContext;
7 | import com.ql.util.express.InstructionSet;
8 | import com.ql.util.express.InstructionSetContext;
9 | import com.ql.util.express.OperateData;
10 | import com.ql.util.express.RunEnvironment;
11 | import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
12 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
13 | import com.ql.util.express.instruction.opdata.OperateDataField;
14 | import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
15 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
16 |
17 |
18 | public class OperateDataCacheManager {
19 |
20 | private static ThreadLocal m_OperateDataObjectCache = new ThreadLocal(){
21 | protected IOperateDataCache initialValue() {
22 | return new OperateDataCacheImpl(30);
23 | //return new OperateDataCacheImpl4Orig();
24 | }
25 | };
26 | public static IOperateDataCache getOperateDataCache(){
27 | return m_OperateDataObjectCache.get();
28 | }
29 | public static OperateData fetchOperateData(Object obj, Class> aType) {
30 | return getOperateDataCache().fetchOperateData(obj, aType);
31 | }
32 | public static OperateDataAttr fetchOperateDataAttr(String name, Class> aType) {
33 | return getOperateDataCache().fetchOperateDataAttr(name, aType);
34 | }
35 | public static OperateDataLocalVar fetchOperateDataLocalVar(String name, Class> aType) {
36 | return getOperateDataCache().fetchOperateDataLocalVar(name, aType);
37 | }
38 | public static OperateDataField fetchOperateDataField(Object aFieldObject,String aFieldName){
39 | return getOperateDataCache().fetchOperateDataField(aFieldObject, aFieldName);
40 | }
41 | public static OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject,int aIndex){
42 | return getOperateDataCache().fetchOperateDataArrayItem(aArrayObject, aIndex);
43 | }
44 | public static OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue){
45 | return getOperateDataCache().fetchOperateDataKeyValue(aKey, aValue);
46 | }
47 |
48 | public static RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){
49 | return getOperateDataCache().fetRunEnvironment(aInstructionSet, aContext, aIsTrace);
50 | }
51 | public static CallResult fetchCallResult(Object aReturnValue,boolean aIsExit){
52 | return getOperateDataCache().fetchCallResult(aReturnValue, aIsExit);
53 | }
54 | public static InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
55 | return getOperateDataCache().fetchInstructionSetContext(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
56 | }
57 |
58 | public static long getFetchCount(){
59 | return getOperateDataCache().getFetchCount();
60 | }
61 |
62 | public static void resetCache(){
63 | getOperateDataCache().resetCache();
64 | }
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/OperatorInstructionFactory.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction;
2 |
3 | import java.util.Stack;
4 |
5 | import com.ql.util.express.ExportItem;
6 | import com.ql.util.express.ExpressRunner;
7 | import com.ql.util.express.InstructionSet;
8 | import com.ql.util.express.instruction.detail.InstructionGoToWithCondition;
9 | import com.ql.util.express.instruction.detail.InstructionGoToWithNotNull;
10 | import com.ql.util.express.instruction.detail.InstructionOperator;
11 | import com.ql.util.express.instruction.detail.InstructionReturn;
12 | import com.ql.util.express.instruction.op.OperatorBase;
13 | import com.ql.util.express.parse.ExpressNode;
14 |
15 |
16 | class OperatorInstructionFactory extends InstructionFactory{
17 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack forStack, ExpressNode node,boolean isRoot)
18 | throws Exception {
19 | boolean returnVal = false;
20 | ExpressNode[] children = node.getChildren();
21 | int [] finishPoint = new int[children.length];
22 | for(int i =0;i < children.length;i++){
23 | ExpressNode tmpNode = children[i];
24 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
25 | returnVal = returnVal || tmpHas;
26 | finishPoint[i] = result.getCurrentPoint();
27 | }
28 |
29 | if(node.isTypeEqualsOrChild("return")){
30 | result.addInstruction(new InstructionReturn(children.length > 0));
31 | }else{
32 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
33 | result.addInstruction(new InstructionOperator(op,children.length));
34 | if(node.isTypeEqualsOrChild("&&") && aCompile.isShortCircuit()){
35 | result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithCondition(false,result.getCurrentPoint() - finishPoint[0] + 1,false));
36 | }else if(node.isTypeEqualsOrChild("||") && aCompile.isShortCircuit()){
37 | result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithCondition(true,result.getCurrentPoint() - finishPoint[0] + 1,false));
38 | }else if(node.isTypeEqualsOrChild("nor") ){
39 | result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithNotNull(result.getCurrentPoint() - finishPoint[0] + 1,false));
40 | }else if(node.isTypeEqualsOrChild("def") || node.isTypeEqualsOrChild("alias")){
41 | returnVal = true;
42 | }else if(node.isTypeEqualsOrChild("exportDef")){
43 | //添加对外的变量声明
44 | result.addExportDef(new ExportItem(children[1].toString(),ExportItem.TYPE_DEF,"还没有实现"));
45 | }else if(node.isTypeEqualsOrChild("exportAlias")){
46 | result.addExportDef(new ExportItem(children[0].toString(),ExportItem.TYPE_ALIAS,"还没有实现"));
47 | }
48 | }
49 | return returnVal;
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/Instruction.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.commons.logging.Log;
6 | import org.apache.commons.logging.LogFactory;
7 |
8 | import com.ql.util.express.RunEnvironment;
9 |
10 |
11 | public abstract class Instruction implements java.io.Serializable {
12 |
13 | private static final long serialVersionUID = 1361458333068300443L;
14 | protected static transient Log staticLog = LogFactory.getLog(Instruction.class);
15 | protected static transient Log log = staticLog;
16 | public void setLog(Log aLog) {
17 | if (aLog != null) {
18 | this.log = aLog;
19 | }
20 | }
21 | public abstract void execute(RunEnvironment environment, List errorList)
22 | throws Exception;
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionCallMacro.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.InstructionSet;
6 | import com.ql.util.express.InstructionSetRunner;
7 | import com.ql.util.express.OperateData;
8 | import com.ql.util.express.RunEnvironment;
9 | import com.ql.util.express.instruction.OperateDataCacheManager;
10 |
11 |
12 | public class InstructionCallMacro extends Instruction{
13 | private static final long serialVersionUID = -5760553701305043649L;
14 | String name;
15 | public InstructionCallMacro(String aName){
16 | this.name = aName;
17 | }
18 |
19 | public void execute(RunEnvironment environment,List errorList)throws Exception{
20 | if(environment.isTrace()&&log.isDebugEnabled()){
21 | log.debug(this);
22 | }
23 | Object functionSet = environment.getContext().getSymbol(this.name);
24 |
25 | Object result =InstructionSetRunner.execute(
26 | environment.getContext().getExpressRunner(),
27 | new InstructionSet[]{(InstructionSet)functionSet},
28 | environment.getContext().getExpressLoader(),
29 | environment.getContext(),
30 | errorList,
31 | environment.isTrace(),
32 | false,false,this.log,
33 | environment.getContext().isSupportDynamicFieldName());
34 | if(result instanceof OperateData){
35 | environment.push((OperateData)result);
36 | }else{
37 | environment.push(OperateDataCacheManager.fetchOperateData(result,null));
38 | }
39 |
40 | environment.programPointAddOne();
41 | }
42 | public String toString(){
43 | return "call macro " + this.name ;
44 | }
45 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionCallSelfDefineFunction.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.commons.logging.Log;
6 |
7 | import com.ql.util.express.InstructionSet;
8 | import com.ql.util.express.InstructionSetContext;
9 | import com.ql.util.express.InstructionSetRunner;
10 | import com.ql.util.express.OperateData;
11 | import com.ql.util.express.RunEnvironment;
12 | import com.ql.util.express.instruction.OperateDataCacheManager;
13 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
14 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
15 |
16 | public class InstructionCallSelfDefineFunction extends Instruction{
17 | private static final long serialVersionUID = 8315682251443515151L;
18 | String functionName;
19 | int opDataNumber;
20 | public InstructionCallSelfDefineFunction(String name,int aOpDataNumber){
21 | this.functionName = name;
22 | this.opDataNumber =aOpDataNumber;
23 | }
24 |
25 | public void execute(RunEnvironment environment, List errorList)
26 | throws Exception {
27 | OperateData[] parameters = environment.popArray(
28 | environment.getContext(), this.opDataNumber);
29 | if (environment.isTrace() && log.isDebugEnabled()) {
30 | String str = this.functionName + "(";
31 | for (int i = 0; i < parameters.length; i++) {
32 | if (i > 0) {
33 | str = str + ",";
34 | }
35 | if (parameters[i] instanceof OperateDataAttr) {
36 | str = str
37 | + parameters[i]
38 | + ":"
39 | + parameters[i].getObject(environment
40 | .getContext());
41 | } else {
42 | str = str + parameters[i];
43 | }
44 | }
45 | str = str + ")";
46 | log.debug(str);
47 | }
48 |
49 | Object function = environment.getContext().getSymbol(functionName);
50 | if (function == null || function instanceof InstructionSet == false) {
51 | throw new Exception("在Runner的操作符定义和自定义函数中都没有找到\""
52 | + this.functionName + "\"的定义");
53 | }
54 | InstructionSet functionSet = (InstructionSet)function;
55 | OperateData result = InstructionCallSelfDefineFunction
56 | .executeSelfFunction(environment, functionSet, parameters,
57 | errorList, this.log);
58 | environment.push(result);
59 | environment.programPointAddOne();
60 | }
61 | public static OperateData executeSelfFunction(RunEnvironment environment,InstructionSet functionSet,
62 | OperateData[] parameters,List errorList,Log log)throws Exception{
63 | InstructionSetContext context = OperateDataCacheManager.fetchInstructionSetContext (
64 | true,environment.getContext().getExpressRunner(),environment.getContext(),environment.getContext().getExpressLoader(),environment.getContext().isSupportDynamicFieldName());
65 | OperateDataLocalVar[] vars = functionSet.getParameters();
66 | for(int i=0;i errorList)throws Exception{
11 | //目前的模式,不需要执行任何操作
12 | if(environment.isTrace() && log.isDebugEnabled()){
13 | log.debug(this);
14 | }
15 | environment.clearDataStack();
16 | environment.programPointAddOne();
17 | }
18 | public String toString(){
19 | return "clearDataStack";
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionCloseNewArea.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.InstructionSetContext;
6 | import com.ql.util.express.RunEnvironment;
7 |
8 | public class InstructionCloseNewArea extends Instruction{
9 | private static final long serialVersionUID = -996832248972683705L;
10 | public void execute(RunEnvironment environment,List errorList)throws Exception{
11 | //目前的模式,不需要执行任何操作
12 | if(environment.isTrace() && log.isDebugEnabled()){
13 | log.debug(this);
14 | }
15 | environment.setContext((InstructionSetContext )environment.getContext().getParent());
16 | environment.programPointAddOne();
17 | }
18 | public String toString(){
19 | return "closeNewArea";
20 | }
21 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionConstData.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.OperateData;
6 | import com.ql.util.express.RunEnvironment;
7 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
8 |
9 | public class InstructionConstData extends Instruction {
10 | private static final long serialVersionUID = 745531116947232321L;
11 | OperateData operateData;
12 |
13 | public InstructionConstData(OperateData data) {
14 | this.operateData = data;
15 | }
16 | public OperateData getOperateData(){
17 | return this.operateData;
18 | }
19 | public void execute(RunEnvironment environment, List errorList)
20 | throws Exception {
21 | if (environment.isTrace() && log.isDebugEnabled()) {
22 | if (this.operateData instanceof OperateDataAttr) {
23 | log.debug(this + ":"
24 | + this.operateData.getObject(environment.getContext()));
25 | } else {
26 | log.debug(this);
27 | }
28 | }
29 | environment.push(this.operateData);
30 | environment.programPointAddOne();
31 | }
32 | public String toString() {
33 | if (this.operateData instanceof OperateDataAttr) {
34 | return "LoadData attr:" + this.operateData.toString();
35 | } else {
36 | return "LoadData " + this.operateData.toString();
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionGoTo.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.RunEnvironment;
6 |
7 | public class InstructionGoTo extends Instruction{
8 | private static final long serialVersionUID = 198094562177756098L;
9 | /**
10 | * 跳转指令的偏移量
11 | */
12 | int offset;
13 | public String name;
14 |
15 | public InstructionGoTo(int aOffset){
16 | this.offset = aOffset;
17 | }
18 |
19 | public void execute(RunEnvironment environment,List errorList) throws Exception {
20 | if(environment.isTrace() && log.isDebugEnabled() ){
21 | log.debug(this);
22 | }
23 | environment.gotoWithOffset(this.offset);
24 | }
25 | public String toString(){
26 | String result = (this.name ==null?"":this.name +":") + "GoTo ";
27 | if(this.offset >=0){
28 | result = result +"+";
29 | }
30 | result = result + this.offset + " ";
31 | return result;
32 | }
33 |
34 | public int getOffset() {
35 | return offset;
36 | }
37 |
38 | public void setOffset(int offset) {
39 | this.offset = offset;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionGoToWithCondition.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.OperateData;
6 | import com.ql.util.express.RunEnvironment;
7 | import com.ql.util.express.instruction.OperateDataCacheManager;
8 |
9 | public class InstructionGoToWithCondition extends Instruction{
10 | private static final long serialVersionUID = -4817805156872407837L;
11 | /**
12 | * 跳转指令的偏移量
13 | */
14 | int offset;
15 | boolean condition;
16 | boolean isPopStackData;
17 | public InstructionGoToWithCondition(boolean aCondition,int aOffset,boolean aIsPopStackData){
18 | this.offset = aOffset;
19 | this.condition = aCondition;
20 | this.isPopStackData = aIsPopStackData;
21 | }
22 |
23 | public void execute(RunEnvironment environment,List errorList)throws Exception{
24 | Object o = null;
25 | if(this.isPopStackData == false){
26 | o = environment.peek().getObject(environment.getContext());
27 | if(o == null){
28 | environment.pop();
29 | environment.push(OperateDataCacheManager.fetchOperateData(false,boolean.class));
30 | }
31 | }else{
32 | o = environment.pop().getObject(environment.getContext());
33 | }
34 | boolean r = false;
35 | if(o == null){
36 | r = false;
37 | }else if(o instanceof Boolean){
38 | r = ((Boolean)o).booleanValue();
39 | }else{
40 | throw new Exception("指令错误:" + o + " 不是Boolean");
41 | }
42 | if (r == this.condition) {
43 | if (environment.isTrace() && log.isDebugEnabled()) {
44 | log.debug("goto +" + this.offset);
45 | }
46 | environment.gotoWithOffset(this.offset);
47 | } else {
48 | if (environment.isTrace() && log.isDebugEnabled()) {
49 | log.debug("programPoint ++ ");
50 | }
51 | environment.programPointAddOne();
52 | }
53 | }
54 |
55 |
56 | public String toString(){
57 | String result = "GoToIf[" + this.condition +",isPop=" + this.isPopStackData +"] " ;
58 | if(this.offset >=0){
59 | result = result +"+";
60 | }
61 | result = result + this.offset;
62 | return result;
63 | }
64 |
65 | public int getOffset() {
66 | return offset;
67 | }
68 |
69 | public void setOffset(int offset) {
70 | this.offset = offset;
71 | }
72 |
73 | public boolean isCondition() {
74 | return condition;
75 | }
76 |
77 | public void setCondition(boolean condition) {
78 | this.condition = condition;
79 | }
80 |
81 | public boolean isPopStackData() {
82 | return isPopStackData;
83 | }
84 |
85 | public void setPopStackData(boolean isPopStackData) {
86 | this.isPopStackData = isPopStackData;
87 | }
88 |
89 |
90 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionGoToWithNotNull.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.RunEnvironment;
6 |
7 | public class InstructionGoToWithNotNull extends Instruction{
8 | private static final long serialVersionUID = -2314675800146495935L;
9 | /**
10 | * 跳转指令的偏移量
11 | */
12 | int offset;
13 | boolean isPopStackData;
14 | public InstructionGoToWithNotNull(int aOffset,boolean aIsPopStackData){
15 | this.offset = aOffset;
16 | this.isPopStackData = aIsPopStackData;
17 | }
18 |
19 | public void execute(RunEnvironment environment,List errorList)throws Exception{
20 | Object o = null;
21 | if(this.isPopStackData == false){
22 | o = environment.peek().getObject(environment.getContext());
23 | }else{
24 | o = environment.pop().getObject(environment.getContext());
25 | }
26 | if (o != null) {
27 | if (environment.isTrace() && log.isDebugEnabled()) {
28 | log.debug("goto +" + this.offset);
29 | }
30 | environment.gotoWithOffset(this.offset);
31 | } else {
32 | if (environment.isTrace() && log.isDebugEnabled()) {
33 | log.debug("programPoint ++ ");
34 | }
35 | environment.programPointAddOne();
36 | }
37 | }
38 |
39 |
40 | public String toString(){
41 | String result = "GoToIf[NOTNULL,isPop=" + this.isPopStackData +"] " ;
42 | if(this.offset >=0){
43 | result = result +"+";
44 | }
45 | result = result + this.offset;
46 | return result;
47 | }
48 |
49 | public int getOffset() {
50 | return offset;
51 | }
52 |
53 | public void setOffset(int offset) {
54 | this.offset = offset;
55 | }
56 |
57 | public boolean isPopStackData() {
58 | return isPopStackData;
59 | }
60 |
61 | public void setPopStackData(boolean isPopStackData) {
62 | this.isPopStackData = isPopStackData;
63 | }
64 |
65 |
66 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionLoadAttr.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.InstructionSet;
6 | import com.ql.util.express.RunEnvironment;
7 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
8 |
9 | public class InstructionLoadAttr extends Instruction{
10 | private static final long serialVersionUID = -2761666977949467250L;
11 | String attrName;
12 | public InstructionLoadAttr(String aName){
13 | this.attrName = aName;
14 | }
15 | public String getAttrName(){
16 | return this.attrName;
17 | }
18 | public void execute(RunEnvironment environment,List errorList)throws Exception{
19 | Object o = environment.getContext().getSymbol(this.attrName);
20 | if(o != null && o instanceof InstructionSet){//是函数,则执行
21 | if(environment.isTrace() && log.isDebugEnabled()){
22 | log.debug("指令转换: LoadAttr -- >CallMacro ");
23 | }
24 | InstructionCallMacro macro = new InstructionCallMacro(this.attrName);
25 | macro.setLog(this.log);
26 | macro.execute(environment, errorList);
27 | //注意,此处不能在增加指令,因为在InstructionCallMacro已经调用 environment.programPointAddOne();
28 | }else{
29 | if(environment.isTrace() && log.isDebugEnabled()){
30 | log.debug(this +":" + ((OperateDataAttr)o).getObject(environment.getContext()));
31 | }
32 | environment.push((OperateDataAttr)o);
33 | environment.programPointAddOne();
34 | }
35 | }
36 |
37 | public String toString(){
38 | return "LoadAttr:" +this.attrName;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionNewVirClass.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.OperateData;
6 | import com.ql.util.express.RunEnvironment;
7 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
8 | import com.ql.util.express.instruction.opdata.OperateDataVirClass;
9 |
10 | public class InstructionNewVirClass extends Instruction {
11 | private static final long serialVersionUID = -4174411242319009814L;
12 | String className;
13 | int opDataNumber;
14 |
15 | public InstructionNewVirClass(String name, int aOpDataNumber) {
16 | this.className = name;
17 | this.opDataNumber = aOpDataNumber;
18 | }
19 |
20 | public void execute(RunEnvironment environment, List errorList)
21 | throws Exception {
22 | OperateData[] parameters = environment.popArray(
23 | environment.getContext(), this.opDataNumber);
24 | if (environment.isTrace() && log.isDebugEnabled()) {
25 | String str = "new VClass(";
26 | for (int i = 0; i < parameters.length; i++) {
27 | if (i > 0) {
28 | str = str + ",";
29 | }
30 | if (parameters[i] instanceof OperateDataAttr) {
31 | str = str + parameters[i] + ":"
32 | + parameters[i].getObject(environment.getContext());
33 | } else {
34 | str = str + parameters[i];
35 | }
36 | }
37 | str = str + ")";
38 | log.debug(str);
39 | }
40 | OperateDataVirClass result = new OperateDataVirClass(className);
41 | environment.push(result);
42 | environment.programPointAddOne();
43 | result.initialInstance(environment.getContext(), parameters, errorList,
44 | environment.isTrace(), this.log);
45 | }
46 |
47 | public String toString() {
48 | return "new VClass[" + this.className + "] OPNUMBER["
49 | + this.opDataNumber + "]";
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionOpenNewArea.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.InstructionSetContext;
6 | import com.ql.util.express.RunEnvironment;
7 | import com.ql.util.express.instruction.OperateDataCacheManager;
8 |
9 | public class InstructionOpenNewArea extends Instruction{
10 | private static final long serialVersionUID = -118527079334123637L;
11 | public void execute(RunEnvironment environment,List errorList)throws Exception{
12 | //目前的模式,不需要执行任何操作
13 | if(environment.isTrace() && log.isDebugEnabled()){
14 | log.debug(this);
15 | }
16 | InstructionSetContext parentContext = environment.getContext();
17 | environment.setContext(OperateDataCacheManager.fetchInstructionSetContext (
18 | true,
19 | parentContext.getExpressRunner(),
20 | parentContext,
21 | parentContext.getExpressLoader(),
22 | parentContext.isSupportDynamicFieldName()));
23 | environment.programPointAddOne();
24 | }
25 | public String toString(){
26 | return "openNewArea";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionOperator.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.commons.logging.Log;
6 |
7 | import com.ql.util.express.OperateData;
8 | import com.ql.util.express.RunEnvironment;
9 | import com.ql.util.express.instruction.op.OperatorBase;
10 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
11 |
12 | public class InstructionOperator extends Instruction{
13 | private static final long serialVersionUID = -1217916524030161947L;
14 | OperatorBase operator;
15 | int opDataNumber;
16 | public InstructionOperator(OperatorBase aOperator,int aOpDataNumber){
17 | this.operator = aOperator;
18 | this.opDataNumber =aOpDataNumber;
19 | }
20 | public OperatorBase getOperator(){
21 | return this.operator;
22 | }
23 | public void execute(RunEnvironment environment,List errorList) throws Exception{
24 | execute(this.operator,this.opDataNumber, environment, errorList, this.log);
25 | }
26 | public static void execute(OperatorBase aOperator,int aOpNum,RunEnvironment environment,List errorList,Log log) throws Exception{
27 | OperateData[] parameters = environment.popArray(environment.getContext(),aOpNum);
28 | if(environment.isTrace() && log.isDebugEnabled()){
29 | String str = aOperator.toString() + "(";
30 | for(int i=0;i 0){
32 | str = str + ",";
33 | }
34 | if(parameters[i] instanceof OperateDataAttr){
35 | str = str + parameters[i] + ":" + parameters[i].getObject(environment.getContext());
36 | }else{
37 | str = str + parameters[i];
38 | }
39 | }
40 | str = str + ")";
41 | log.debug(str);
42 | }
43 |
44 | OperateData result = aOperator.execute(environment.getContext(),parameters, errorList);
45 | environment.push(result);
46 | environment.programPointAddOne();
47 | }
48 | public String toString(){
49 | String result = "OP : " + this.operator.toString() + " OPNUMBER[" + this.opDataNumber +"]";
50 | return result;
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/detail/InstructionReturn.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.detail;
2 |
3 | import java.util.List;
4 |
5 | import com.ql.util.express.RunEnvironment;
6 |
7 | public class InstructionReturn extends Instruction{
8 | private static final long serialVersionUID = -4991998239277488949L;
9 | boolean haveReturnValue;
10 | public InstructionReturn(boolean aHaveReturnValue){
11 | this.haveReturnValue = aHaveReturnValue;
12 | }
13 | public void execute(RunEnvironment environment,List errorList)throws Exception{
14 | //目前的模式,不需要执行任何操作
15 | if(environment.isTrace() && log.isDebugEnabled()){
16 | log.debug(this);
17 | }
18 | if(this.haveReturnValue == true){
19 | environment.quitExpress(environment.pop().getObject(environment.getContext()));
20 | }else{
21 | environment.quitExpress();
22 | }
23 | environment.programPointAddOne();
24 | }
25 | public String toString(){
26 | if(this.haveReturnValue){
27 | return "return [value]";
28 | }else{
29 | return "return";
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/op/CanClone.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.op;
2 |
3 | public interface CanClone {
4 | public OperatorBase cloneMe(String name,String errorInfo) throws Exception;
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/op/OperatorAddReduce.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.op;
2 |
3 | import com.ql.util.express.Operator;
4 | import com.ql.util.express.OperatorOfNumber;
5 |
6 | public class OperatorAddReduce extends Operator {
7 | public OperatorAddReduce(String name) {
8 | this.name = name;
9 | }
10 | public OperatorAddReduce(String aAliasName, String aName, String aErrorInfo) {
11 | this.name = aName;
12 | this.aliasName = aAliasName;
13 | this.errorInfo = aErrorInfo;
14 | }
15 | public Object executeInner(Object[] list) throws Exception {
16 | return executeInner(list[0], list[1]);
17 | }
18 |
19 | public Object executeInner(Object op1,
20 | Object op2) throws Exception {
21 | Object obj = null;
22 | if (this.getName().equals("+")) {
23 | obj = OperatorOfNumber.add(op1, op2,this.isPrecise);
24 | } else if (this.getName().equals("-")) {
25 | obj = OperatorOfNumber.subtract(op1, op2,this.isPrecise);
26 | }
27 | return obj;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/op/OperatorAlias.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.op;
2 |
3 | import com.ql.util.express.InstructionSetContext;
4 | import com.ql.util.express.OperateData;
5 | import com.ql.util.express.instruction.opdata.OperateDataAlias;
6 | import com.ql.util.express.instruction.opdata.OperateDataAttr;
7 |
8 | public class OperatorAlias extends OperatorBase {
9 | public OperatorAlias(String aName) {
10 | this.name = aName;
11 | }
12 | public OperatorAlias(String aAliasName, String aName, String aErrorInfo) {
13 | this.name = aName;
14 | this.aliasName = aAliasName;
15 | this.errorInfo = aErrorInfo;
16 | }
17 |
18 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception {
19 | String varName = (String)list[0].getObjectInner(context);
20 | OperateDataAttr realAttr = (OperateDataAttr)list[1];
21 | OperateDataAttr result = new OperateDataAlias(varName,realAttr);
22 | context.addSymbol(varName, result);
23 | return result;
24 | }
25 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/op/OperatorAnd.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.op;
2 |
3 | import com.ql.util.express.Operator;
4 |
5 | /**
6 | * 处理 And,Or,&&,||操作
7 | */
8 |
9 | public class OperatorAnd extends Operator {
10 | public OperatorAnd(String name) {
11 | this.name = name;
12 | }
13 | public OperatorAnd(String aAliasName, String aName, String aErrorInfo) {
14 | this.name = aName;
15 | this.aliasName = aAliasName;
16 | this.errorInfo = aErrorInfo;
17 | }
18 | public Object executeInner(Object[] list) throws Exception {
19 | return executeInner(list[0], list[1]);
20 | }
21 |
22 | public Object executeInner(Object op1,
23 | Object op2) throws Exception {
24 |
25 | Object o1 = op1;
26 | Object o2 = op2;
27 | boolean r1 = false;
28 | boolean r2= false;
29 | if(o1 == null){
30 | r1 = false;
31 | }else if(o1 instanceof Boolean){
32 | r1 = ((Boolean) o1).booleanValue();
33 | }else{
34 | String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作";
35 | throw new Exception(msg);
36 | }
37 | if(o2 == null){
38 | r2 = false;
39 | }else if(o2 instanceof Boolean){
40 | r2 = ((Boolean) o2).booleanValue();
41 | }else{
42 | String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作";
43 | throw new Exception(msg);
44 | }
45 | boolean result = r1 && r2;
46 | return Boolean.valueOf(result);
47 |
48 | }
49 | }
--------------------------------------------------------------------------------
/src/main/java/com/ql/util/express/instruction/op/OperatorAnonymousNewArray.java:
--------------------------------------------------------------------------------
1 | package com.ql.util.express.instruction.op;
2 |
3 | import java.lang.reflect.Array;
4 |
5 | import com.ql.util.express.ExpressUtil;
6 | import com.ql.util.express.InstructionSetContext;
7 | import com.ql.util.express.OperateData;
8 | import com.ql.util.express.instruction.OperateDataCacheManager;
9 |
10 | public class OperatorAnonymousNewArray extends OperatorBase {
11 | public OperatorAnonymousNewArray(String aName) {
12 | this.name = aName;
13 | }
14 | public OperatorAnonymousNewArray(String aAliasName, String aName, String aErrorInfo) {
15 | this.name = aName;
16 | this.aliasName = aAliasName;
17 | this.errorInfo = aErrorInfo;
18 | }
19 |
20 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception {
21 | Class> type = Object.class;
22 | if(list.length >0){
23 | type = list[0].getType(context);
24 | }
25 | type = ExpressUtil.getSimpleDataType(type);
26 | int[] dims = new int[1];
27 | dims[0]= list.length;
28 | Object data = Array.newInstance(type,dims);
29 | for(int i=0;i result = new ArrayList