写点什么

案例研究之聊聊 QLExpress 源码 (八 -1)

发布于: 2021 年 01 月 16 日
案例研究之聊聊 QLExpress 源码 (八-1)

指令模块是非常大的一个模块,代码非常多,分为 2 次说明。本次说明的内容是具体模块。

8.1、detail 明细

8.1.1、Instruction 指令

package com.ql.util.express.instruction.detail;
import java.util.List;
import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;
import com.ql.util.express.RunEnvironment;
/** * 抽象指令 */public abstract class Instruction implements java.io.Serializable { private static final long serialVersionUID = 1361458333068300443L; /** * 静态日志 非序列化 */ protected static transient Log staticLog = LogFactory.getLog(Instruction.class); protected static transient Log log = staticLog; private Integer line = 0;
/** * 设置行号 * @param line * @return */ public Instruction setLine(Integer line) { this.line = line; return this; } public Integer getLine() { return line; } public void setLog(Log aLog) { if (aLog != null) { this.log = aLog; } } public String getExceptionPrefix() { return "run QlExpress Exception at line "+line+" :"; }
/** * 抽象执行方法 * @param environment * @param errorList * @throws Exception */ public abstract void execute(RunEnvironment environment, List<String> errorList) throws Exception;}

复制代码

8.1.2、InstructionCallMacro 指令调用宏

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.InstructionSet;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.InstructionSetRunner;import com.ql.util.express.OperateData;import com.ql.util.express.RunEnvironment;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * 指令调用宏 */public class InstructionCallMacro extends Instruction { private static final long serialVersionUID = -5760553701305043649L; String name;
public InstructionCallMacro(String aName) { this.name = aName; }
/** * 执行环境 * @param environment * @param errorList * @throws Exception */ public void execute(RunEnvironment environment, List<String> errorList) throws Exception { if (environment.isTrace() && log.isDebugEnabled()) { log.debug(this); }
InstructionSetContext context = environment.getContext();
Object functionSet = context.getSymbol(this.name);
Object result = InstructionSetRunner.execute( context.getExpressRunner(), (InstructionSet) functionSet, context.getExpressLoader(), context, errorList, environment.isTrace(), false, false, this.log, environment.getContext().isSupportDynamicFieldName()); if (result instanceof OperateData) { environment.push((OperateData) result); } else { environment.push(OperateDataCacheManager.fetchOperateData(result, null)); }
environment.programPointAddOne(); }
public String toString() { return "call macro " + this.name; }}

复制代码

8.1.3、InstructionCallSelfDefineFunction(指令调用自定义函数)

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.exception.QLException;import org.apache.commons.logging.Log;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSet;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.InstructionSetRunner;import com.ql.util.express.OperateData;import com.ql.util.express.RunEnvironment;import com.ql.util.express.instruction.OperateDataCacheManager;import com.ql.util.express.instruction.opdata.OperateDataAttr;import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
/** * 指令调用自定义函数 */public class InstructionCallSelfDefineFunction extends Instruction{ private static final long serialVersionUID = 8315682251443515151L; String functionName; int opDataNumber; public InstructionCallSelfDefineFunction(String name,int aOpDataNumber){ this.functionName = name; this.opDataNumber =aOpDataNumber; }
public String getFunctionName() { return functionName; }
public int getOpDataNumber() { return opDataNumber; }
/** * 执行 * @param environment * @param errorList * @throws Exception */ public void execute(RunEnvironment environment, List<String> errorList) throws Exception { ArraySwap parameters = environment.popArray( environment.getContext(), this.opDataNumber); if (environment.isTrace() && log.isDebugEnabled()) { String str = this.functionName + "("; OperateData p; for (int i = 0; i < parameters.length; i++) { p = parameters.get(i); if (i > 0) { str = str + ","; } if (p instanceof OperateDataAttr) { str = str + p + ":" + p.getObject(environment .getContext()); } else { str = str + p; } } str = str + ")"; log.debug(str); }
Object function = environment.getContext().getSymbol(functionName); if (function == null || function instanceof InstructionSet == false) { throw new QLException(getExceptionPrefix()+"在Runner的操作符定义和自定义函数中都没有找到\"" + this.functionName + "\"的定义"); } InstructionSet functionSet = (InstructionSet)function; OperateData result = InstructionCallSelfDefineFunction .executeSelfFunction(environment, functionSet, parameters, errorList, this.log); environment.push(result); environment.programPointAddOne(); }
/** * 执行自定义函数 * @param environment * @param functionSet * @param parameters * @param errorList * @param log * @return * @throws Exception */ public static OperateData executeSelfFunction(RunEnvironment environment,InstructionSet functionSet, ArraySwap parameters,List<String> errorList,Log log)throws Exception{ InstructionSetContext context = OperateDataCacheManager.fetchInstructionSetContext ( true,environment.getContext().getExpressRunner(),environment.getContext(),environment.getContext().getExpressLoader(),environment.getContext().isSupportDynamicFieldName()); OperateDataLocalVar[] vars = functionSet.getParameters(); for(int i=0;i<vars.length;i++){ //注意此处必须new 一个新的对象,否则就会在多次调用的时候导致数据冲突 OperateDataLocalVar var = OperateDataCacheManager.fetchOperateDataLocalVar(vars[i].getName(),vars[i].getOrgiType()); context.addSymbol(var.getName(), var); var.setObject(context, parameters.get(i).getObject(environment.getContext())); } Object result =InstructionSetRunner.execute((InstructionSet)functionSet, context,errorList,environment.isTrace(),false,true,log); return OperateDataCacheManager.fetchOperateData(result,null); } @Override public String toString(){ return "call Function[" + this.functionName +"] OPNUMBER["+ this.opDataNumber +"]" ; }
}

复制代码

8.1.4、InstructionClearDataStack 指令清除数据栈

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.RunEnvironment;
/** * 指令清除数据栈 */public class InstructionClearDataStack extends Instruction{ private static final long serialVersionUID = 6286430548739444891L; @Override public void execute(RunEnvironment environment, List<String> errorList)throws Exception{ //目前的模式,不需要执行任何操作 if(environment.isTrace() && log.isDebugEnabled()){ log.debug(this); } environment.clearDataStack(); environment.programPointAddOne(); } @Override public String toString(){ return "clearDataStack"; }}
复制代码

8.1.5、InstructionCloseNewArea 指令关闭新区域

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.InstructionSetContext;import com.ql.util.express.RunEnvironment;
/** * 指令关闭新区域 */public class InstructionCloseNewArea extends Instruction{ private static final long serialVersionUID = -996832248972683705L; @Override public void execute(RunEnvironment environment, List<String> errorList)throws Exception{ //目前的模式,不需要执行任何操作 if(environment.isTrace() && log.isDebugEnabled()){ log.debug(this); } environment.setContext((InstructionSetContext )environment.getContext().getParent()); environment.programPointAddOne(); } @Override public String toString(){ return "closeNewArea"; }}

复制代码

8.1.6、InstructionConstData 指令加载常量数据

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.OperateData;import com.ql.util.express.RunEnvironment;import com.ql.util.express.instruction.opdata.OperateDataAttr;
/** * 指令常量数据 */public class InstructionConstData extends Instruction { private static final long serialVersionUID = 745531116947232321L; OperateData operateData;
public InstructionConstData(OperateData data) { this.operateData = data; } public OperateData getOperateData(){ return this.operateData; } @Override public void execute(RunEnvironment environment, List<String> errorList) throws Exception { if (environment.isTrace() && log.isDebugEnabled()) { if (this.operateData instanceof OperateDataAttr) { log.debug(this + ":" + this.operateData.getObject(environment.getContext())); } else { log.debug(this); } } environment.push(this.operateData); environment.programPointAddOne(); } @Override public String toString() { if (this.operateData instanceof OperateDataAttr) { return "LoadData attr:" + this.operateData.toString(); } else { return "LoadData " + this.operateData.toString(); } }
}
复制代码

8.1.7、InstructionGoTo 指令跳转 goto 语法

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.RunEnvironment;
/** * 指令跳转goto语法 */public class InstructionGoTo extends Instruction{ private static final long serialVersionUID = 198094562177756098L; /** * 跳转指令的偏移量 */ int offset; public String name;
public InstructionGoTo(int aOffset){ this.offset = aOffset; }
@Override public void execute(RunEnvironment environment, List<String> errorList) throws Exception { if(environment.isTrace() && log.isDebugEnabled() ){ log.debug(this); } environment.gotoWithOffset(this.offset); } @Override public String toString(){ String result = (this.name ==null?"":this.name +":") + "GoTo "; if(this.offset >=0){ result = result +"+"; } result = result + this.offset + " "; return result; }
public int getOffset() { return offset; }
public void setOffset(int offset) { this.offset = offset; }
}
复制代码

8.1.8、InstructionGoToWithCondition(带条件的 goto 指令)

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.OperateData;import com.ql.util.express.RunEnvironment;import com.ql.util.express.exception.QLException;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * 指令有条件的goto跳转 */public class InstructionGoToWithCondition extends Instruction{ private static final long serialVersionUID = -4817805156872407837L; /** * 跳转指令的偏移量 */ int offset; boolean condition; boolean isPopStackData; public InstructionGoToWithCondition(boolean aCondition,int aOffset,boolean aIsPopStackData){ this.offset = aOffset; this.condition = aCondition; this.isPopStackData = aIsPopStackData; }
@Override public void execute(RunEnvironment environment, List<String> errorList)throws Exception{ Object o = null; if(this.isPopStackData == false){ o = environment.peek().getObject(environment.getContext()); if(o == null){ environment.pop(); environment.push(OperateDataCacheManager.fetchOperateData(false,boolean.class)); } }else{ o = environment.pop().getObject(environment.getContext()); } boolean r = false; if(o == null){ r = false; }else if(o instanceof Boolean){ r = ((Boolean)o).booleanValue(); }else{ throw new QLException(getExceptionPrefix()+"指令错误:" + o + " 不是Boolean"); } if (r == this.condition) { if (environment.isTrace() && log.isDebugEnabled()) { log.debug("goto +" + this.offset); } environment.gotoWithOffset(this.offset); } else { if (environment.isTrace() && log.isDebugEnabled()) { log.debug("programPoint ++ "); } environment.programPointAddOne(); } }
@Override public String toString(){ String result = "GoToIf[" + this.condition +",isPop=" + this.isPopStackData +"] " ; if(this.offset >=0){ result = result +"+"; } result = result + this.offset; return result; }
public int getOffset() { return offset; }
public void setOffset(int offset) { this.offset = offset; }
public boolean isCondition() { return condition; }
public void setCondition(boolean condition) { this.condition = condition; }
public boolean isPopStackData() { return isPopStackData; }
public void setPopStackData(boolean isPopStackData) { this.isPopStackData = isPopStackData; } }
复制代码

8.1.9、InstructionGoToWithNotNull(无空值跳转指令)

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.RunEnvironment;
/** * 没有控制的GOTO跳转指令 */public class InstructionGoToWithNotNull extends Instruction{ private static final long serialVersionUID = -2314675800146495935L; /** * 跳转指令的偏移量 */ int offset; boolean isPopStackData; public InstructionGoToWithNotNull(int aOffset,boolean aIsPopStackData){ this.offset = aOffset; this.isPopStackData = aIsPopStackData; }
@Override public void execute(RunEnvironment environment, List<String> errorList)throws Exception{ Object o = null; if(this.isPopStackData == false){ o = environment.peek().getObject(environment.getContext()); }else{ o = environment.pop().getObject(environment.getContext()); } if (o != null) { if (environment.isTrace() && log.isDebugEnabled()) { log.debug("goto +" + this.offset); } environment.gotoWithOffset(this.offset); } else { if (environment.isTrace() && log.isDebugEnabled()) { log.debug("programPoint ++ "); } environment.programPointAddOne(); } }
@Override public String toString(){ String result = "GoToIf[NOTNULL,isPop=" + this.isPopStackData +"] " ; if(this.offset >=0){ result = result +"+"; } result = result + this.offset; return result; }
public int getOffset() { return offset; }
public void setOffset(int offset) { this.offset = offset; }
public boolean isPopStackData() { return isPopStackData; }
public void setPopStackData(boolean isPopStackData) { this.isPopStackData = isPopStackData; } }

复制代码

8.1.10、InstructionLoadAttr(加载属性指令)

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.InstructionSet;import com.ql.util.express.RunEnvironment;import com.ql.util.express.instruction.opdata.OperateDataAttr;
/** * 加载属性指令 */public class InstructionLoadAttr extends Instruction{ private static final long serialVersionUID = -2761666977949467250L; String attrName; public InstructionLoadAttr(String aName){ this.attrName = aName; } public String getAttrName(){ return this.attrName; } @Override public void execute(RunEnvironment environment, List<String> errorList)throws Exception{ Object o = environment.getContext().getSymbol(this.attrName); if(o != null && o instanceof InstructionSet){//是函数,则执行 if(environment.isTrace() && log.isDebugEnabled()){ log.debug("指令转换: LoadAttr -- >CallMacro "); } InstructionCallMacro macro = new InstructionCallMacro(this.attrName); macro.setLog(this.log); macro.execute(environment, errorList); //注意,此处不能在增加指令,因为在InstructionCallMacro已经调用 environment.programPointAddOne(); }else{ if(environment.isTrace() && log.isDebugEnabled()){ log.debug(this +":" + ((OperateDataAttr)o).getObject(environment.getContext())); } environment.push((OperateDataAttr)o); environment.programPointAddOne(); } } @Override public String toString(){ return "LoadAttr:" +this.attrName; }}

复制代码

8.1.11、InstructionNewVirClass 新虚拟机类指令

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.ArraySwap;import com.ql.util.express.OperateData;import com.ql.util.express.RunEnvironment;import com.ql.util.express.instruction.opdata.OperateDataAttr;import com.ql.util.express.instruction.opdata.OperateDataVirClass;
/** * 新虚拟机类指令 */public class InstructionNewVirClass extends Instruction { private static final long serialVersionUID = -4174411242319009814L; String className; int opDataNumber;
public InstructionNewVirClass(String name, int aOpDataNumber) { this.className = name; this.opDataNumber = aOpDataNumber; } public String getClassName() { return className; } @Override public void execute(RunEnvironment environment, List<String> errorList) throws Exception { ArraySwap parameters = environment.popArray( environment.getContext(), this.opDataNumber); if (environment.isTrace() && log.isDebugEnabled()) { String str = "new VClass("; OperateData p; for (int i = 0; i < parameters.length; i++) { p = parameters.get(i); if (i > 0) { str = str + ","; } if (p instanceof OperateDataAttr) { str = str + p + ":" + p.getObject(environment.getContext()); } else { str = str + p; } } str = str + ")"; log.debug(str); } //因为会影响堆栈,要先把对象拷贝出来 OperateData[] list = new OperateData[parameters.length]; for(int i = 0;i <list.length;i++){ list[i] = parameters.get(i); } OperateDataVirClass result = new OperateDataVirClass(className); environment.push(result); environment.programPointAddOne(); result.initialInstance(environment.getContext(), list, errorList, environment.isTrace(), this.log); }
@Override public String toString() { return "new VClass[" + this.className + "] OPNUMBER[" + this.opDataNumber + "]"; }
}

复制代码

8.1.12、InstructionOpenNewArea(开放的新区域指令)

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.InstructionSetContext;import com.ql.util.express.RunEnvironment;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * 开放的新区域指令 */public class InstructionOpenNewArea extends Instruction{ private static final long serialVersionUID = -118527079334123637L; @Override public void execute(RunEnvironment environment, List<String> errorList)throws Exception{ //目前的模式,不需要执行任何操作 if(environment.isTrace() && log.isDebugEnabled()){ log.debug(this); } InstructionSetContext parentContext = environment.getContext(); environment.setContext(OperateDataCacheManager.fetchInstructionSetContext ( true, parentContext.getExpressRunner(), parentContext, parentContext.getExpressLoader(), parentContext.isSupportDynamicFieldName())); environment.programPointAddOne(); } @Override public String toString(){ return "openNewArea"; }}

复制代码

8.1.13、InstructionOperator 运算指令

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.exception.QLBizException;import com.ql.util.express.exception.QLException;import org.apache.commons.logging.Log;
import com.ql.util.express.ArraySwap;import com.ql.util.express.OperateData;import com.ql.util.express.RunEnvironment;import com.ql.util.express.instruction.op.OperatorBase;import com.ql.util.express.instruction.opdata.OperateDataAttr;
/** * 运算指令 */public class InstructionOperator extends Instruction{ private static final long serialVersionUID = -1217916524030161947L; OperatorBase operator; int opDataNumber; public InstructionOperator(OperatorBase aOperator,int aOpDataNumber){ this.operator = aOperator; this.opDataNumber =aOpDataNumber; } public OperatorBase getOperator(){ return this.operator; } @Override public void execute(RunEnvironment environment, List<String> errorList) throws Exception{ ArraySwap parameters = environment.popArray(environment.getContext(),this.opDataNumber); if(environment.isTrace() && this.log.isDebugEnabled()){ String str = this.operator.toString() + "("; OperateData p = null; for(int i=0;i<parameters.length;i++){ p = parameters.get(i); if(i > 0){ str = str + ","; } if(p instanceof OperateDataAttr){ str = str + p + ":" + p.getObject(environment.getContext()); }else{ str = str + p; } } str = str + ")"; this.log.debug(str); } try { OperateData result = this.operator.execute(environment.getContext(), parameters, errorList); environment.push(result); environment.programPointAddOne(); }catch (QLException e){ throw new QLException(getExceptionPrefix(),e); }catch (Throwable t){ throw new QLBizException(getExceptionPrefix(),t); } } @Override public String toString(){ String result = "OP : " + this.operator.toString() + " OPNUMBER[" + this.opDataNumber +"]"; return result; }}

复制代码

8.1.13、InstructionReturn(返回指令)

package com.ql.util.express.instruction.detail;
import java.util.List;
import com.ql.util.express.RunEnvironment;
/** * 返回指令 */public class InstructionReturn extends Instruction{ private static final long serialVersionUID = -4991998239277488949L; boolean haveReturnValue; public InstructionReturn(boolean aHaveReturnValue){ this.haveReturnValue = aHaveReturnValue; } @Override public void execute(RunEnvironment environment, List<String> errorList)throws Exception{ //目前的模式,不需要执行任何操作 if(environment.isTrace() && log.isDebugEnabled()){ log.debug(this); } if(this.haveReturnValue == true){ environment.quitExpress(environment.pop().getObject(environment.getContext())); }else{ environment.quitExpress(); } environment.gotoLastWhenReturn(); } @Override public String toString(){ if(this.haveReturnValue){ return "return [value]"; }else{ return "return"; } } }

复制代码

8.1.14、小结

  • 对于指令进行了抽象提高了子类指令的扩展性继承

8.2、op 运算符

8.2.1、CanClone(能克隆)

package com.ql.util.express.instruction.op;
/** * 能可隆 * @author xiaochengxinyizhan */public interface CanClone { public OperatorBase cloneMe(String name,String errorInfo) throws Exception;}

复制代码

8.2.2、OperatorAdd(添加运算符)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.Operator;import com.ql.util.express.OperatorOfNumber;
/** * 添加运算 * @author didi */public class OperatorAdd extends Operator { /** * 添加名字 * @param name */ public OperatorAdd(String name) { this.name = name; }
/** * 重载函数添加别名 * @param aAliasName * @param aName * @param aErrorInfo */ public OperatorAdd(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 执行内部集合添加二元运算 * @param list * @return * @throws Exception */ @Override public Object executeInner(Object[] list) throws Exception { return OperatorOfNumber.add(list[0], list[1],this.isPrecise); }}

复制代码

8.2.3、OperatorAlias (别名运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.opdata.OperateDataAlias;import com.ql.util.express.instruction.opdata.OperateDataAttr;
/** * 别名运算 * @author xiaochengxinyizhan */public class OperatorAlias extends OperatorBase { /** * 别名运算 * @param aName */ public OperatorAlias(String aName) { this.name = aName; }
/** * 别名重载运算 * @param aAliasName * @param aName * @param aErrorInfo */ public OperatorAlias(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 执行内部集合上下文运算指令,通过别名获取数据属性 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { String varName = (String)list.get(0).getObjectInner(context); OperateDataAttr realAttr = (OperateDataAttr)list.get(1); OperateDataAttr result = new OperateDataAlias(varName,realAttr); context.addSymbol(varName, result); return result; }}

复制代码

8.2.4、OperatorAnd(and 或者 or 运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.exception.QLException;
/** * 处理 And,Or操作 * @author xiaochengxinyizhan */
public class OperatorAnd extends Operator { /** * 添加运算符 * @param name */ public OperatorAnd(String name) { this.name = name; } public OperatorAnd(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 执行内部数组运算 * @param list * @return * @throws Exception */ @Override public Object executeInner(Object[] list) throws Exception { return executeInner(list[0], list[1]); }
/** * 执行运算操作一般是定义的传入运算符号 * @param op1 * @param op2 * @return * @throws Exception */ public Object executeInner(Object op1, Object op2) throws Exception {
Object o1 = op1; Object o2 = op2; boolean r1 = false; boolean r2= false; if(o1 == null){ r1 = false; }else if(o1 instanceof Boolean){ r1 = ((Boolean) o1).booleanValue(); }else{ String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作"; throw new QLException(msg); } if(o2 == null){ r2 = false; }else if(o2 instanceof Boolean){ r2 = ((Boolean) o2).booleanValue(); }else{ String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作"; throw new QLException(msg); } boolean result = r1 && r2; return Boolean.valueOf(result);
}}

复制代码

8.2.5、OperatorAnonymousNewArray(匿名新数组)

package com.ql.util.express.instruction.op;
import java.lang.reflect.Array;
import com.ql.util.express.ArraySwap;import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * 匿名新数组运算 * @author xiaochengxinyizhan */public class OperatorAnonymousNewArray extends OperatorBase { /** * 构造函数 * @param aName */ public OperatorAnonymousNewArray(String aName) { this.name = aName; }
/** * 构造函数 * @param aAliasName * @param aName * @param aErrorInfo */ public OperatorAnonymousNewArray(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 执行内部运算-指令级上下文,交换数组 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { /** * 查询数组类型 */ Class<?> type = this.findArrayClassType(context,list); /** * 表达式获取简单数据类型 */ type = ExpressUtil.getSimpleDataType(type); int[] dims = new int[1]; dims[0]= list.length; Object data = Array.newInstance(type,dims); for(int i=0;i<list.length;i++){ Array.set(data, i, list.get(i).getObject(context)); } /** * 拉取运算数据 */ return OperateDataCacheManager.fetchOperateData(data,data.getClass()); }
/** * 查找数组类类型 * @param context * @param list * @return * @throws Exception */ private Class<?>findArrayClassType(InstructionSetContext context, ArraySwap list) throws Exception { Class<?> type = null; for(int i=0;i<list.length;i++){ Class<?> type1 = list.get(i).getType(context); if(type1==null){ //doNothing }else if(type==null){ //第一次赋值 type = type1; }else if(type1==type || type.isAssignableFrom(type1)){//type1是type的子类 //doNothing }else if(type1.isAssignableFrom(type)){ //寻找更基础的类 type = type1 ; }else{ type = Object.class; } } if(type==null) type = Object.class;//参数全部为null的情况 return type; }}

复制代码

8.2.6、OperatorAnonymousNewList(匿名新集合)

package com.ql.util.express.instruction.op;
import java.util.ArrayList;import java.util.List;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * 匿名新集合 * @author xiaochengxinyizhan */public class OperatorAnonymousNewList extends OperatorBase { public OperatorAnonymousNewList(String aName) { this.name = aName; } public OperatorAnonymousNewList(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 从内存中拉取集合运算数据 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { List<Object> result = new ArrayList<Object>(); for(int i=0;i<list.length;i++){ result.add(list.get(i).getObject(context)); } return OperateDataCacheManager.fetchOperateData(result,List.class); }}

复制代码

8.2.7、OperatorAnonymousNewMap(匿名新集合 HashMap)

package com.ql.util.express.instruction.op;
import java.util.HashMap;import java.util.Map;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.OperateDataCacheManager;import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
/** * 匿名新集合map * @author xiaochengxinyizhan */public class OperatorAnonymousNewMap extends OperatorBase { public OperatorAnonymousNewMap(String aName) { this.name = aName; } public OperatorAnonymousNewMap(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 从内存获取hashmap集合数据 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { Map<Object,Object> result = new HashMap<Object,Object>(); for(int i=0;i<list.length;i++){ result.put(((OperateDataKeyValue)list.get(i)).getKey().getObject(context), ((OperateDataKeyValue)list.get(i)).getValue().getObject(context)); } return OperateDataCacheManager.fetchOperateData(result,HashMap.class); }}

复制代码

8.2.8、OperatorArray(数组运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.exception.QLException;import com.ql.util.express.instruction.OperateDataCacheManager;import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
/** * 数组运算 * @author xiaochengxinyizhan */public class OperatorArray extends OperatorBase { public OperatorArray(String aName) { this.name = aName; } public OperatorArray(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 数组运算相关操作 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { OperateData p0 = list.get(0); if(p0 == null || p0.getObject(context) == null){ throw new QLException("对象为null,不能执行数组相关操作"); } Object tmpObject = p0.getObject(context); if( tmpObject.getClass().isArray() == false){ throw new QLException("对象:"+ tmpObject.getClass() +"不是数组,不能执行相关操作" ); } int index = ((Number)list.get(1).getObject(context)).intValue(); OperateData result = OperateDataCacheManager.fetchOperateDataArrayItem((OperateData)p0,index); return result; }}

复制代码

8.2.9、OperatorBase(操作符号定义统一抽象类)

/** * * <p>Title:Operator </p> * <p>Description:表达式计算的运算符号 </p> * <p>Copyright: Copyright (c) 2001</p> * <p>Company: </p> * @author 墙辉 * @version 1.0 */
package com.ql.util.express.instruction.op;
import java.util.List;
import com.ql.util.express.ArraySwap;import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.exception.QLException;import com.ql.util.express.instruction.opdata.OperateDataAttr;
/** * 操作符号定义 * * @author qhlhl2010@gmail.com * */
public abstract class OperatorBase implements java.io.Serializable { /** * 别名 */ protected String aliasName; /** * 名字 */ protected String name; /** * 错误信息 */ protected String errorInfo; /** * 是否需要高精度计算 */ protected boolean isPrecise = false; /** * 操作数描述 */ protected String[] operDataDesc; /** * 操作数的其它定义 */ protected String[] operDataAnnotation;
/** * 转对象集合 * @param parent * @param list * @return * @throws Exception */ public Object[] toObjectList(InstructionSetContext parent, ArraySwap list) throws Exception { if (list == null) { return new Object[0]; } Object[] result = new Object[list.length]; OperateData p; for (int i = 0; i < list.length; i++) { p = list.get(i); if(p instanceof OperateDataAttr){ result[i] = ((OperateDataAttr) p).getName()+":"+p.getObject(parent); }else{ result[i] = p.getObject(parent); } } return result; }
/** * 执行 * @param context * @param list * @param errorList * @return * @throws Exception */ public OperateData execute(InstructionSetContext context, ArraySwap list, List<String> errorList) throws Exception { OperateData result = null; result = this.executeInner(context, list); //输出错误信息 if (errorList != null && this.errorInfo != null && result != null) { Object obj = result.getObject(context); if ( obj != null && obj instanceof Boolean && ((Boolean) obj).booleanValue() == false) { String tmpStr = ExpressUtil.replaceString(this.errorInfo, toObjectList(context, list)); if(errorList.contains(tmpStr) == false){ errorList.add(tmpStr); } } } return result; } @Override public String toString(){ if(this.aliasName != null){ return this.aliasName; }else{ return this.name; } }
/** * 执行内部数据运算 * @param parent * @param list * @return * @throws Exception */ public abstract OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception;
public String[] getOperDataDesc(){ return this.operDataDesc; } public String[] getOperDataAnnotaion(){ return this.operDataAnnotation; } public void setName(String aName) { this.name = aName; }
public String getName() { return this.name; }
public String getAliasName() { if(this.aliasName != null){ return this.aliasName; }else{ return this.name; } }
public void setAliasName(String aliasName) { this.aliasName = aliasName; }
public boolean isPrecise() { return isPrecise; } public void setPrecise(boolean isPrecise) { this.isPrecise = isPrecise; } public String getErrorInfo() { return errorInfo; }
public void setErrorInfo(String errorInfo) { this.errorInfo = errorInfo; } }
/** * 运算函数 */class OperatorFunction extends OperatorBase { public OperatorFunction(String aName) { this.name = aName; } public OperatorFunction(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 没有实际业务 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { throw new QLException("还没有实现"); }}
/** * 返回运算 */class OperatorReturn extends OperatorBase{ public OperatorReturn(String name) { this.name = name; } public OperatorReturn(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 执行指令集合上下文 * @param parent * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { return executeInner(parent); }
/** * 不支持方法 * @param parent * @return * @throws Exception */ public OperateData executeInner(InstructionSetContext parent) throws Exception { throw new QLException("return 是通过特殊指令来实现的,不能支持此方法"); } }
/** * 调用运算 */class OperatorCall extends OperatorBase{ public OperatorCall(String name) { this.name = name; } public OperatorCall(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 不支持方法 * @param parent * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { throw new QLException("call 是通过特殊指令来实现的,不能支持此方法"); } }
/** * break关键词 */class OperatorBreak extends OperatorBase{ public OperatorBreak(String name) { this.name = name; } public OperatorBreak(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 不支持本方法 * @param parent * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { throw new QLException("OperatorBreak 是通过特殊指令来实现的,不能支持此方法"); } }
/** * continue关键字 */class OperatorContinue extends OperatorBase{ public OperatorContinue(String name) { this.name = name; } public OperatorContinue(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } /** * 不支持本方法 * @param parent * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { throw new QLException("OperatorContinue 是通过特殊指令来实现的,不能支持此方法"); } }
/** * for关键字 */class OperatorFor extends OperatorBase { public OperatorFor(String aName) { this.name = aName; }
public OperatorFor(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { throw new QLException("cache 是通过特殊指令来实现的,不能支持此方法"); }
}

复制代码

8.2.10、OperatorBit(bit 运算符)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.exception.QLException;
import java.util.Arrays;
/** * bit运算 * Created by tianqiao on 16/12/15. */public class OperatorBit extends Operator { public OperatorBit(String name) { this.name = name; } @Override public Object executeInner(Object[] list) throws Exception { if( this.name.equals("~")){ if (list.length == 1 && list[0] instanceof Number) { if(list[0]instanceof Integer) { return ~(((Number) list[0]).intValue()); }else{ return ~(((Number) list[0]).longValue()); } }else{ throw new QLException("取反操作符 ~ 参数不合法:"+ Arrays.toString(list)); } } if( this.name.equals("&")){ if (list.length == 2 && list[0] instanceof Number && list[1] instanceof Number) { if(list[0]instanceof Integer && list[1] instanceof Integer){ return (Integer)list[0]&(Integer)list[1]; } return (((Number)list[0]).longValue())&(((Number)list[1]).longValue()); }else{ throw new QLException("按位与操作符 & 两边的参数不合法:"+ Arrays.toString(list)); } } if( this.name.equals("|")){ if (list.length == 2 && list[0] instanceof Number && list[1] instanceof Number) { if(list[0]instanceof Integer && list[1] instanceof Integer){ return (Integer)list[0]|(Integer)list[1]; } return (((Number)list[0]).longValue())|(((Number)list[1]).longValue()); }else{ throw new QLException("按位或操作符 | 两边的参数不合法:"+ Arrays.toString(list)); } } if( this.name.equals("^")){ if (list.length == 2 && list[0] instanceof Number && list[1] instanceof Number) { if(list[0]instanceof Integer && list[1] instanceof Integer){ return (Integer)list[0]^(Integer)list[1]; } return (((Number)list[0]).longValue())^(((Number)list[1]).longValue()); }else{ throw new QLException("按位异或操作符 ^ 两边的参数不合法:"+ Arrays.toString(list)); } } if( this.name.equals("<<")){ if (list.length == 2 && list[0] instanceof Number && list[1] instanceof Number) { if(list[0]instanceof Integer && list[1] instanceof Integer){ return (Integer)list[0]<<(Integer)list[1]; } return (((Number)list[0]).longValue())<<(((Number)list[1]).longValue()); }else{ throw new QLException("左移操作符 << 两边的参数不合法:"+ Arrays.toString(list)); } } if( this.name.equals(">>")){ if (list.length == 2 && list[0] instanceof Number && list[1] instanceof Number) { if(list[0]instanceof Integer && list[1] instanceof Integer){ return (Integer)list[0]>>(Integer)list[1]; } return (((Number)list[0]).longValue())>>(((Number)list[1]).longValue()); }else{ throw new QLException("右移操作符 >> 两边的参数不合法:"+ Arrays.toString(list)); } } throw new QLException("不支持的位运算操作符:"+ Arrays.toString(list)); }}

复制代码

8.2.11、OperatorCast(cast 运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * cast运算 * @author xiaochengxinyizhan */public class OperatorCast extends OperatorBase { public OperatorCast(String aName) { this.name = aName; }
@Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { Class<?> tmpClass = (Class<?>) list.get(0).getObject(parent); Object castObj = ExpressUtil.castObject(list.get(1).getObject(parent), tmpClass,true); OperateData result = OperateDataCacheManager.fetchOperateData(castObj,tmpClass); return result; }}

复制代码

8.2.12、OperatorDef(定义运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.OperateDataCacheManager;import com.ql.util.express.instruction.opdata.OperateDataLocalVar;import com.ql.util.express.instruction.opdata.OperateDataVirClass;
/** * def定义运算 * @author xiaochengxinyizhan */public class OperatorDef extends OperatorBase { public OperatorDef(String aName) { this.name = aName; } public OperatorDef(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { Object type = list.get(0).getObject(context); String varName = (String)list.get(1).getObject(context); Class<?> tmpClass = null; if(type instanceof Class ){ tmpClass = (Class<?>) type; }else{ tmpClass = OperateDataVirClass.class; } OperateDataLocalVar result = OperateDataCacheManager.fetchOperateDataLocalVar(varName,tmpClass); context.addSymbol(varName, result); return result; }}

复制代码

8.2.13、OperatorDoubleAddReduce(double 自增和自减运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.OperatorOfNumber;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * double自增和自减运算 * @author xiaochengxinyizhan */public class OperatorDoubleAddReduce extends OperatorBase { public OperatorDoubleAddReduce(String name) { this.name = name; }
/** * 执行内部运算 * @param parent * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { Object obj = list.get(0).getObject(parent); Object result = null; if (this.getName().equals("++")) { result = OperatorOfNumber.add(obj, 1,this.isPrecise); } else if (this.getName().equals("--")) { result = OperatorOfNumber.subtract(obj, 1,this.isPrecise); } ((OperateData)list.get(0)).setObject(parent, result); if(result == null){ return OperateDataCacheManager.fetchOperateData(null,null); }else{ return OperateDataCacheManager.fetchOperateData(result,ExpressUtil.getSimpleDataType(result.getClass())); } }}

复制代码


8.2.14、OperatorEqualsLessMore(处理比较符号的运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.exception.QLException;
import static com.ql.util.express.config.QLExpressRunStrategy.*;
/** * 处理比较操作符号 * @author xiaochengxinyizhan */public class OperatorEqualsLessMore extends Operator { public OperatorEqualsLessMore(String aName) { this.name = aName; }
public OperatorEqualsLessMore(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
@Override public Object executeInner(Object[] list) throws Exception { return executeInner(list[0], list[1]); }
public Object executeInner(Object op1,Object op2) throws Exception { boolean result = executeInner(this.name, op1, op2); return result; }
/** * 处理比较字符操作 * @param opStr * @param obj1 * @param obj2 * @return * @throws Exception */ public static boolean executeInner(String opStr, Object obj1, Object obj2) throws Exception { if(opStr.equals("==")){ return Operator.objectEquals(obj1, obj2); } if(opStr.equals("!=")||opStr.equals("<>")){ return !Operator.objectEquals(obj1, obj2); } //进行其他大小比较操作 if (obj1 == null || obj2 == null){ if (isCompareNullLessMoreAsFalse()) { return false; } throw new QLException("空操作数无法进行数字比较操作:left = " + obj1+",right = "+ obj2); } int i = Operator.compareData(obj1, obj2); boolean result = false; if (i > 0) { if (opStr.equals(">") || opStr.equals(">=") || opStr.equals("!=") || opStr.equals("<>")) result = true; else result = false; } else if (i == 0) { if (opStr.equals("=") || opStr.equals("==") || opStr.equals(">=") || opStr.equals("<=")) result = true; else result = false; } else if (i < 0) { if (opStr.equals("<") || opStr.equals("<=") || opStr.equals("!=") || opStr.equals("<>")) result = true; else result = false; } return result; }}

复制代码


8.2.15、OperatorEvaluate(对象转换运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;
import com.ql.util.express.exception.QLException;
/** * 对象转换运算 * @author xiaochengxinyizhan */public class OperatorEvaluate extends OperatorBase { public OperatorEvaluate(String name) { this.name = name; } public OperatorEvaluate(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { return executeInner(parent, list.get(0), list.get(1)); }
public OperateData executeInner(InstructionSetContext parent, OperateData op1, OperateData op2) throws Exception { Class<?> targetType = op1.getDefineType(); Class<?> sourceType = op2.getType(parent); if (targetType != null) { if (ExpressUtil.isAssignable(targetType, sourceType) == false) { throw new QLException("赋值时候,类型转换错误:" + ExpressUtil.getClassName(sourceType) + " 不能转换为 " + ExpressUtil.getClassName(targetType)); }
} Object result = op2.getObject(parent); if(targetType != null){ result = ExpressUtil.castObject(result,targetType,false); } op1.setObject(parent,result); return op1; }
}
复制代码


8.2.16、OperatorExportAlias(导出别名运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.opdata.OperateDataAlias;import com.ql.util.express.instruction.opdata.OperateDataAttr;
/** * 导出别名运算 * @author xiaochengxinyizhan */public class OperatorExportAlias extends OperatorBase { public OperatorExportAlias(String aName) { this.name = aName; } public OperatorExportAlias(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
@Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { String varName = (String)list.get(0).getObjectInner(context); OperateDataAttr realAttr = (OperateDataAttr)list.get(1); OperateDataAttr result = new OperateDataAlias(varName,realAttr); context.exportSymbol(varName, result); return result; }}

复制代码


8.2.17、OperatorExportDef(自定义导出运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.opdata.OperateDataAttr;
/** * 自定义导出运算 * @author xiaochengxinyizhan */public class OperatorExportDef extends OperatorBase { public OperatorExportDef(String aName) { this.name = aName; } public OperatorExportDef(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
@Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { Class<?> tmpClass = (Class<?>) list.get(0).getObject(context); String varName = (String)list.get(1).getObject(context); //OperateDataLocalVar result = new OperateDataLocalVar(varName,tmpClass); //context.exportSymbol(varName, result); OperateDataAttr result = (OperateDataAttr)context.getSymbol(varName); result.setDefineType(tmpClass); return result; }}

复制代码


8.2.18、OperatorFactory(运算工厂)

package com.ql.util.express.instruction.op;
import java.lang.reflect.Constructor;import java.util.HashMap;import java.util.Map;
import com.ql.util.express.exception.QLCompileException;import com.ql.util.express.exception.QLException;import com.ql.util.express.parse.ExpressNode;
/** * 运算工厂 * @author xiaochengxinyizhan */public class OperatorFactory { /** * 是否需要高精度计算,可参考readme上高精度说明 */ protected boolean isPrecise = false; /** * 运算符号集合 */ private Map<String, OperatorBase> operator = new HashMap<String, OperatorBase>();
/** * 运算符合工厂初始化 运算符号转义 * * @param aIsPrecise */ public OperatorFactory(boolean aIsPrecise){ this.isPrecise = aIsPrecise; addOperator("new",new OperatorNew("new")); addOperator("anonymousNewArray",new OperatorAnonymousNewArray("anonymousNewArray")); addOperator("NewList",new OperatorAnonymousNewList("NewList")); addOperator(":",new OperatorKeyValue(":")); addOperator("NewMap",new OperatorAnonymousNewMap("NewMap")); addOperator("def", new OperatorDef("def")); addOperator("exportDef", new OperatorExportDef("exportDef")); addOperator("!",new OperatorNot("!")); addOperator("*", new OperatorMultiDiv("*")); addOperator("/", new OperatorMultiDiv("/")); addOperator("%", new OperatorMultiDiv("%")); addOperator("mod", new OperatorMultiDiv("mod")); addOperator("+",new OperatorAdd("+")); addOperator("-",new OperatorReduce("-")); addOperator("<",new OperatorEqualsLessMore("<")); addOperator(">",new OperatorEqualsLessMore(">")); addOperator("<=",new OperatorEqualsLessMore("<=")); addOperator(">=",new OperatorEqualsLessMore(">=")); addOperator("==",new OperatorEqualsLessMore("==")); addOperator("!=",new OperatorEqualsLessMore("!=")); addOperator("<>",new OperatorEqualsLessMore("<>")); addOperator("&&",new OperatorAnd("&&")); addOperator("||",new OperatorOr("||")); addOperator("nor",new OperatorNor("nor")); addOperator("=",new OperatorEvaluate("=")); addOperator("exportAlias",new OperatorExportAlias("exportAlias")); addOperator("alias",new OperatorAlias("alias")); addOperator("break",new OperatorBreak("break")); addOperator("continue",new OperatorContinue("continue")); addOperator("return",new OperatorReturn("return")); addOperator("ARRAY_CALL",new OperatorArray("ARRAY_CALL")); addOperator("++",new OperatorDoubleAddReduce("++")); addOperator("--",new OperatorDoubleAddReduce("--")); addOperator("cast", new OperatorCast("cast")); addOperator("macro",new OperatorMacro("macro")); addOperator("function",new OperatorFunction("function")); addOperator("in", new OperatorIn("in")); addOperator("like", new OperatorLike("like")); //bit operator addOperator("&",new OperatorBit("&")); addOperator("|",new OperatorBit("|")); addOperator("^",new OperatorBit("^")); addOperator("~",new OperatorBit("~")); addOperator("<<",new OperatorBit("<<")); addOperator(">>",new OperatorBit(">>")); }
/** * 运算符号容器添加运算符 * @param name * @param op */ public void addOperator(String name, OperatorBase op) { OperatorBase oldOp = this.operator.get(name); if (oldOp != null) { throw new RuntimeException("重复定义操作符:" + name + "定义1:" + oldOp.getClass() + " 定义2:" + op.getClass()); } op.setPrecise(this.isPrecise); op.setAliasName(name); operator.put(name, op); }
/** * 替换运算符 * @param name * @param op * @return */ public OperatorBase replaceOperator(String name, OperatorBase op){ OperatorBase old = this.operator.remove(name); this.addOperator(name, op); return old; }
/** * 给运算符号 添加别名 * @param aAliasName * @param name * @param errorInfo * @throws Exception */ @SuppressWarnings("unchecked") public void addOperatorWithAlias(String aAliasName,String name,String errorInfo) throws Exception{ if (!this.operator.containsKey(name)){ throw new QLException(name + " 不是系统级别的操作符号,不能设置别名"); }else{ OperatorBase orgiOperator = this.operator.get(name); if(orgiOperator == null){ throw new QLException(name + " 不能被设置别名"); } OperatorBase destOperator = null; //是否可以被克隆 if (orgiOperator instanceof CanClone) { destOperator = ((CanClone)orgiOperator).cloneMe(aAliasName, errorInfo); } else { Class<OperatorBase> opClass = (Class<OperatorBase>) orgiOperator.getClass(); Constructor<OperatorBase> constructor = null; try { constructor = (Constructor<OperatorBase>) opClass .getConstructor(String.class, String.class,String.class); } catch (Exception e) { throw new QLException(name + " 不能被设置别名:" + e.getMessage()); } if (constructor == null) { throw new QLException(name + " 不能被设置别名"); } destOperator = constructor.newInstance(aAliasName, name,errorInfo); } if(this.operator.containsKey(aAliasName)){ throw new RuntimeException("操作符号:\"" + aAliasName + "\" 已经存在"); } this.addOperator(aAliasName,destOperator); } }
/** * 运算符号是否存在 * @param operName * @return * @throws Exception */ public boolean isExistOperator(String operName) throws Exception { return operator.containsKey(operName); }
/** * 获取运算符号 * @param aOperName * @return */ public OperatorBase getOperator(String aOperName){ return this.operator.get(aOperName); }
/** * 创建一个新的操作符实例 */ public OperatorBase newInstance(ExpressNode opItem) throws Exception { OperatorBase op = operator.get(opItem.getNodeType().getName()); if (op == null) { op = operator.get(opItem.getTreeType().getName()); } if(op == null){ op = operator.get(opItem.getValue()); } if (op == null) throw new QLCompileException("没有为\"" + opItem.getValue() + "\"定义操作符处理对象"); return op; }
/** * 定义操作符号的处理对象 * @param opName * @return * @throws Exception */ public OperatorBase newInstance(String opName) throws Exception { OperatorBase op = operator.get(opName); if (op == null){ throw new QLCompileException("没有为\"" + opName + "\"定义操作符处理对象"); } return op; }}

复制代码


8.2.19、OperatorField(属性运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.config.QLExpressRunStrategy;import com.ql.util.express.instruction.OperateDataCacheManager;import com.ql.util.express.instruction.opdata.OperateDataField;
/** * 属性运算 * @author xiaochengxinyizhan */public class OperatorField extends OperatorBase { String filedName; public OperatorField() { this.name = "FieldCall"; } public OperatorField(String aFieldName) { this.name = "FieldCall"; this.filedName = aFieldName; }
/** * 从内存获取属性运算 * @param parent * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { OperateData operateData = list.get(0); if (operateData == null && QLExpressRunStrategy.isAvoidNullPointer()) { return null; } Object obj = operateData.getObject(parent); return OperateDataCacheManager.fetchOperateDataField(obj,this.filedName); } @Override public String toString(){ return this.name + ":" + this.filedName; } }

复制代码


8.2.20、OperatorIf(if 运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.exception.QLException;
/** * if运算 * @author xiaochengxinyizhan */public class OperatorIf extends OperatorBase { public OperatorIf(String aName) { this.name = aName; }
public OperatorIf(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 执行if比较运算操作数 * @param parent * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { if(list.length <2){ throw new QLException("\"" + this.aliasName + "\"操作至少要两个操作数"); } Object obj = list.get(0).getObject(parent); if (obj == null) { String msg ="\"" + this.aliasName + "\"的判断条件不能为空"; throw new QLException(msg); } else if ((obj instanceof Boolean) == false) { String msg = "\"" + this.aliasName + "\"的判断条件 必须是 Boolean,不能是:"; throw new QLException(msg + obj.getClass().getName()); } else { if (((Boolean)obj).booleanValue() == true){ return list.get(1); }else{ if(list.length == 3){ return list.get(2); } } return null; } }}

复制代码

8.2.21、OperatorIn(In 运算符)

package com.ql.util.express.instruction.op;
import java.lang.reflect.Array;import java.util.List;
import com.ql.util.express.Operator;import com.ql.util.express.config.QLExpressRunStrategy;import com.ql.util.express.exception.QLException;
/** * in运算 * @author xiaochengxinyizhan */public class OperatorIn extends Operator { public OperatorIn(String aName) { this.name = aName; }
public OperatorIn(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 执行数字或者字符串类型的in参数 * @param list * @return * @throws Exception */ @Override public Object executeInner(Object[] list) throws Exception { Object obj = list[0]; if (obj == null) { if(QLExpressRunStrategy.isAvoidNullPointer()){ //避免空指针策略异常则返回false return false; } // 对象为空,不能执行方法 String msg = "对象为空,不能执行方法:"; throw new QLException(msg + this.name); } else if (((obj instanceof Number) || (obj instanceof String)) == false) { String msg = "对象类型不匹配,只有数字和字符串类型才才能执行 in 操作,当前数据类型是:"; throw new QLException(msg + obj.getClass().getName()); } else if(list.length == 2 && (list[1].getClass().isArray() || list[1] instanceof List)){ if(obj.equals(list[1]) == true){ return true; }else if(list[1].getClass().isArray()){ int len = Array.getLength(list[1]); for(int i=0;i<len;i++){ boolean f = OperatorEqualsLessMore.executeInner("==", obj,Array.get(list[1],i)); if (f == true) { return Boolean.TRUE; } } }else if(list[1] instanceof List){ @SuppressWarnings("unchecked") List<Object> array = (List<Object>)list[1]; for(int i=0;i<array.size();i++){ boolean f = OperatorEqualsLessMore.executeInner("==", obj,array.get(i)); if (f == true) { return Boolean.TRUE; } } } return false; } else { for (int i = 1; i < list.length; i++) { boolean f = OperatorEqualsLessMore.executeInner("==", obj,list[i]); if (f == true) { return Boolean.TRUE; } } return Boolean.FALSE; } }
}

复制代码


8.2.22、OperatorInstanceOf(InstanceOf 运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;
/** * instanceOf运算 * Created by tianqiao on 17/9/19. */public class OperatorInstanceOf extends Operator { public OperatorInstanceOf(String anInstanceof) { this.name = anInstanceof; } @Override public Object executeInner(Object[] list) throws Exception { Object obj = list[0]; Object cls = list[1]; if(obj!=null && cls!=null && cls instanceof Class){ Class targetClass = (Class) cls; Class fromClass = obj.getClass(); return targetClass.isAssignableFrom(fromClass); } return false; }}

复制代码


8.2.23、OperatorKeyValue

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.OperateDataCacheManager;import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
/** * keyValue运算 * @author xiaochengxinyizhan */public class OperatorKeyValue extends OperatorBase { public OperatorKeyValue(String aName) { this.name = aName; } public OperatorKeyValue(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
/** * 从内存中获取key-value运算 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { return OperateDataCacheManager.fetchOperateDataKeyValue(list.get(0),list.get(1)); }}

复制代码


8.2.24、OperatorLike(like 关键字运算)

package com.ql.util.express.instruction.op;
import java.util.ArrayList;
import com.ql.util.express.Operator;
/** * like运算 * * @author xiaochengxinyizhan */public class OperatorLike extends Operator { public OperatorLike(String name) { this.name = name; } public OperatorLike(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } @Override public Object executeInner(Object[] list) throws Exception { return executeInner(list[0], list[1]); }
/** * 执行运算操作 * @param op1 * @param op2 * @return * @throws Exception */ public Object executeInner(Object op1,Object op2) throws Exception { boolean result = true; String s1 = op1.toString(); String s2 = op2.toString(); if (s2.indexOf("%") >= 0) { String[] list = split(s2, "%"); int index = 0; for (int i = 0; i < list.length; i++) { if (index >= s1.length()) { result = false; break; } index = s1.indexOf(list[i], index); if (index < 0) { result = false; break; } index = index + 1; } } else if (s1.equals(s2)) result = true; else result = false;
return Boolean.valueOf(result); }
/** * 切割字符串 * @param str * @param s * @return */ public String[] split(String str, String s) { int start = 0; int end = -1; String tmpStr = ""; ArrayList<String> list = new ArrayList<String>(); do { end = str.indexOf(s, start); if (end < 0) tmpStr = str.substring(start); else tmpStr = str.substring(start, end); if (tmpStr.length() > 0) list.add(tmpStr); start = end + 1; if (start >= str.length()) break; } while (end >= 0); return (String[]) list.toArray(new String[0]); }}

复制代码


8.2.25、OperatorMacro(宏运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.opdata.OperateDataAlias;import com.ql.util.express.instruction.opdata.OperateDataAttr;
/** * 宏运算 * @author xiaochengxinyizhan */public class OperatorMacro extends OperatorBase { public OperatorMacro(String aName) { this.name = aName; } public OperatorMacro(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
@Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { String varName = (String)list.get(0).getObjectInner(context); OperateDataAttr realAttr = (OperateDataAttr)list.get(1); OperateDataAttr result = new OperateDataAlias(varName,realAttr); context.addSymbol(varName, result); return result; }}

复制代码


8.2.26、OperatorMethod(方法运算)

package com.ql.util.express.instruction.op;
import java.lang.reflect.Method;
import com.ql.util.express.ArraySwap;import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.config.QLExpressRunStrategy;import com.ql.util.express.exception.QLException;import com.ql.util.express.instruction.OperateDataCacheManager;import com.ql.util.express.instruction.opdata.OperateClass;import com.ql.util.express.instruction.opdata.OperateDataVirClass;import com.ql.util.express.parse.AppendingClassMethodManager;
/** * 方法运算 * @author xiaochengxinyizhan */public class OperatorMethod extends OperatorBase { String methodName; public OperatorMethod() { this.name ="MethodCall"; } public OperatorMethod(String aMethodName) { this.name ="MethodCall"; this.methodName = aMethodName; } static Class<?> ArrayClass = (new Object[]{}).getClass(); @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { OperateData p0 = list.get(0); Object obj = p0.getObject(parent); if(obj instanceof OperateDataVirClass ){ OperateDataVirClass vClass = (OperateDataVirClass)obj; OperateData[] parameters = new OperateData[list.length - 1]; for(int i=0;i< list.length -1;i++){ parameters[i] =list.get(i+1); } return vClass.callSelfFunction(this.methodName, parameters); } if (obj == null) { if(QLExpressRunStrategy.isAvoidNullPointer()){ return null; } // 对象为空,不能执行方法 String msg = "对象为空,不能执行方法:"; throw new QLException(msg + this.methodName); } else { Class<?>[] types = new Class[list.length - 1]; Class<?>[] orgiTypes = new Class[list.length - 1]; Object[] objs = new Object[list.length - 1]; Object tmpObj; OperateData p; for (int i = 0; i < types.length; i++) { p = list.get(i+ 1); tmpObj = p.getObject(parent); types[i] = p.getType(parent); orgiTypes[i] = p.getType(parent); objs[i] = tmpObj; } AppendingClassMethodManager appendingClassMethodManager = parent.getExpressRunner().getAppendingClassMethodManager();
if(appendingClassMethodManager!=null) { AppendingClassMethodManager.AppendingMethod appendingClassMethod = appendingClassMethodManager.getAppendingClassMethod(obj, this.methodName); if (appendingClassMethod != null) { return appendingClassMethodManager.invoke(appendingClassMethod, parent, list, null); } } Method m = null; if (p0 instanceof OperateClass) {// 调用静态方法 m = ExpressUtil.findMethodWithCache((Class<?>) obj, this.methodName, types, true, true); } else { if(obj instanceof Class){ m = ExpressUtil.findMethodWithCache((Class<?>) obj, this.methodName, types, true, true); } if(m==null) { m = ExpressUtil.findMethodWithCache(obj.getClass(), this.methodName, types, true, false); } } if(m == null){ types = new Class[]{ArrayClass}; if (p0 instanceof OperateClass) {// 调用静态方法 m = ExpressUtil.findMethodWithCache((Class<?>) obj, methodName, types, true, true); } else { m = ExpressUtil.findMethodWithCache(obj.getClass(), methodName, types, true, false); } objs = new Object[]{objs}; } if (m == null) { StringBuilder s = new StringBuilder(); s.append("没有找到" + obj.getClass().getName() + "的方法:" + methodName + "("); for (int i = 0; i < orgiTypes.length; i++) { if (i > 0) s.append(","); if(orgiTypes[i] == null){ s.append("null"); }else{ s.append(orgiTypes[i].getName()); } } s.append(")"); throw new QLException(s.toString()); } //阻止调用不安全的方法 QLExpressRunStrategy.assertBlackMethod(m);
if (p0 instanceof OperateClass) {// 调用静态方法 boolean oldA = m.isAccessible(); m.setAccessible(true); tmpObj = m.invoke(null,ExpressUtil.transferArray(objs,m.getParameterTypes())); m.setAccessible(oldA); } else { boolean oldA = m.isAccessible(); m.setAccessible(true); tmpObj = m.invoke(obj, ExpressUtil.transferArray(objs,m.getParameterTypes())); m.setAccessible(oldA); } return OperateDataCacheManager.fetchOperateData(tmpObj, m.getReturnType()); } } @Override public String toString(){ return this.name + ":" + this.methodName; }}

复制代码


8.2.27、OperatorMinMax(最小最大运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.exception.QLException;
/** * 最小最大运算 * @author xiaochengxinyizhan */public class OperatorMinMax extends Operator { public OperatorMinMax(String name) { this.name = name; }
@Override public Object executeInner(Object[] list) throws Exception { if (list.length == 0){ throw new QLException("操作数异常"); } Object result = list[0];
for (int i = 1; i < list.length; i++) result = executeInner(result, list[i]); return result; }
/** * 匹配关键字 * @param op1 * @param op2 * @return * @throws Exception */ public Object executeInner(Object op1, Object op2) throws Exception { Object result = null; int compareResult = Operator.compareData(op1,op2); if (this.name.equals("min")) { if (compareResult < 0) result = op1; else result = op2; } else if (this.name.equals("max")) { if (compareResult < 0) result = op2; else result = op1; } return result; }}

复制代码


8.2.28、OperatorMultiDiv(乘除运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.OperatorOfNumber;
/** * 乘除法运算 * @author xiaochengxinyizhan */public class OperatorMultiDiv extends Operator { public OperatorMultiDiv(String name) { this.name = name; }
@Override public Object executeInner(Object[] list) throws Exception { return executeInner( list[0], list[1]); }
/** * 执行内部运算 * @param op1 * @param op2 * @return * @throws Exception */ public Object executeInner(Object op1, Object op2) throws Exception { Object obj = null; if (this.getName().equals("*")) obj = OperatorOfNumber.multiply(op1, op2,this.isPrecise); else if (this.getName().equals("/")) obj = OperatorOfNumber.divide(op1, op2,this.isPrecise); else if (this.getName().equals("%")) obj = OperatorOfNumber.modulo(op1, op2); else if (this.getName().equals("mod")) obj = OperatorOfNumber.modulo(op1, op2);
return obj;
}}
复制代码


8.2.29、OperatorNew(new 运算)

package com.ql.util.express.instruction.op;
import java.lang.reflect.Array;import java.lang.reflect.Constructor;
import com.ql.util.express.ArraySwap;import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;import com.ql.util.express.exception.QLException;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * new运算 * @author didi */public class OperatorNew extends OperatorBase { public OperatorNew(String aName) { this.name = aName; }
/** * 通过newInstance代替new关键字 * @param parent * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { Class<?> obj = (Class<?>) list.get(0).getObject(parent); if (obj.isArray()) { Class<?> tmpClass = obj; int dim = 0; while (tmpClass.isArray()) { tmpClass = tmpClass.getComponentType(); dim = dim + 1; } int[] dimLength = new int[dim]; for (int index = 0; index < dim; index++) { dimLength[index] = ((Number) (list.get(index + 1).getObject(parent))) .intValue(); } return OperateDataCacheManager.fetchOperateData(Array.newInstance(tmpClass, dimLength), obj); } Class<?>[] types = new Class[list.length - 1]; Object[] objs = new Object[list.length - 1]; Object tmpObj; for (int i = 0; i < types.length; i++) { tmpObj = list.get(i + 1).getObject(parent); types[i] = list.get(i + 1).getType(parent); objs[i] = tmpObj; } Constructor<?> c = ExpressUtil.findConstructorWithCache(obj, types);
if (c == null) { // "没有找到" + obj.getName() + "的构造方法:" StringBuilder s = new StringBuilder(); s.append("没有找到" + obj.getName() + "的构造方法:" + obj.getName() + "("); for (int i = 0; i < types.length; i++) { if (i > 0){ s.append(","); } s.append(types[i].getName()); } s.append(")"); throw new QLException(s.toString()); }
tmpObj = c.newInstance(objs); return OperateDataCacheManager.fetchOperateData(tmpObj, obj); }}

复制代码

8.2.30、OperatorNor(nor 运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;
/** * nor运算 * @author xiaochengxinyizhan */public class OperatorNor extends Operator { public OperatorNor(String name) { this.name = name; }
public OperatorNor(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; }
@Override public Object executeInner(Object[] list) throws Exception { return executeInner(list[0], list[1]); }
/** * 参数不为空,则返回,否则返回第二个参数 * @param op1 * @param op2 * @return * @throws Exception */
public Object executeInner(Object op1, Object op2) throws Exception {
if (op1 != null) { return op1; } else { return op2; } }}

复制代码

8.2.31、OperatorNot(not 运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.exception.QLException;
/** * not运算 * @author xiaochengxinyizhan */public class OperatorNot extends Operator { public OperatorNot(String name) { this.name = name; } public OperatorNot(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } @Override public Object executeInner(Object[] list) throws Exception { return executeInner(list[0]); }
/** * 执行对象运算 * @param op * @return * @throws Exception */ public Object executeInner(Object op) throws Exception { Object result = null; if (op == null){ throw new QLException("null 不能执行操作:" + this.getAliasName()); } if (Boolean.class.equals(op.getClass()) == true) { boolean r = !((Boolean) op).booleanValue(); result = Boolean.valueOf(r); } else { // String msg = "没有定义类型" + op.getClass().getName() + " 的 " + this.name + "操作"; throw new QLException(msg); } return result; }}

复制代码

8.2.32、OperatorNullOp(空运算--废弃中)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.IExpressContext;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;

/** * 处理 ",","(",")",";" */
public class OperatorNullOp extends OperatorBase { public OperatorNullOp(String name) { this.name = name; } public OperatorNullOp(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception { return executeInner(parent); }
public OperateData executeInner(IExpressContext<String,Object> parent) throws Exception { return null; }}

复制代码

8.2.33、OperatorOr(或运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.exception.QLException;
/** * 或运算 * @author xiaochengxinyizhan */public class OperatorOr extends Operator { public OperatorOr(String name) { this.name = name; } public OperatorOr(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } @Override public Object executeInner(Object[] list) throws Exception { return executeInner(list[0], list[1]); }
public Object executeInner(Object op1, Object op2) throws Exception { Object o1 = op1; Object o2 = op2; boolean r1 = false; boolean r2= false; if(o1 == null){ r1 = false; }else if(o1 instanceof Boolean){ r1 = ((Boolean) o1).booleanValue(); }else{ String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作"; throw new QLException(msg); } if(o2 == null){ r2 = false; }else if(o2 instanceof Boolean){ r2 = ((Boolean) o2).booleanValue(); }else{ String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作"; throw new QLException(msg); } boolean result = r1 || r2; return Boolean.valueOf(result);
}}

复制代码

8.2.34、OperatorPrint(打印运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.exception.QLException;
/** * 打印运算 * @author xiaochengxinyizhan */public class OperatorPrint extends Operator { public OperatorPrint(String name) { this.name = name; } public OperatorPrint(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } @Override public Object executeInner(Object[] list) throws Exception { if (list.length != 1 ){ throw new QLException("操作数异常,有且只能有一个操作数"); } System.out.print(list[0]); return null; }

}

复制代码

8.2.35、OperatorPrintln(换行打印运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.exception.QLException;
/** * 换行打印运算 * @author didi */public class OperatorPrintln extends Operator { public OperatorPrintln(String name) { this.name = name; } public OperatorPrintln(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } @Override public Object executeInner(Object[] list) throws Exception { if (list.length != 1 ){ throw new QLException("操作数异常,有且只能有一个操作数"); } System.out.println(list[0]); return null; }

}

复制代码

8.2.36、OperatorReduce(字符串减法运算)

package com.ql.util.express.instruction.op;
import com.ql.util.express.ArraySwap;import com.ql.util.express.Operator;import com.ql.util.express.OperatorOfNumber;
/** * 字符串截取运算 * @author xiaochengxinyizhan */public class OperatorReduce extends Operator { public OperatorReduce(String name) { this.name = name; } public OperatorReduce(String aAliasName, String aName, String aErrorInfo) { this.name = aName; this.aliasName = aAliasName; this.errorInfo = aErrorInfo; } @Override public Object executeInner(Object[] list) throws Exception { return OperatorOfNumber.subtract(list[0], list[1],this.isPrecise); }}

复制代码

8.2.37、OperatorRound(四舍五入转整数)

package com.ql.util.express.instruction.op;
import com.ql.util.express.Operator;import com.ql.util.express.OperatorOfNumber;
/** * 四舍五入转整数 * @author xiaochengxinyizhan */public class OperatorRound extends Operator { public OperatorRound(String name) { this.name = name; }
@Override public Object executeInner(Object[] list) throws Exception { return executeInner(list[0], list[1]); }
public Object executeInner(Object op1,Object op2) throws Exception { double r = OperatorOfNumber.round( ((Number) op1).doubleValue(), ((Number) op2).intValue()); return new Double(r); }}

复制代码

8.2.38、OperatorSelfDefineClassFunction(用户自定义函数操作)

package com.ql.util.express.instruction.op;
import java.lang.reflect.Method;import java.lang.reflect.Modifier;
import com.ql.util.express.*;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * 用户自定义的函数操作 * * @author qhlhl2010@gmail.com */public class OperatorSelfDefineClassFunction extends OperatorBase implements CanClone { /** * 函数名字 */ String functionName; /** * 参数类型 */ String[] parameterTypes; /** * 参数类 */ Class<?>[] parameterClasses; /** * 操作类 */ Class<?> operClass; /** * 操作对象 */ Object operInstance; /** * 方法 */ Method method; /** * 是否无返回值 */ boolean isReturnVoid; /** * 是否是动态参数 */ boolean maybeDynamicParams;
/** * 自定义类函数运算构造函数 * @param aOperName * @param aOperClass * @param aFunctionName * @param aParameterClassTypes * @param aParameterDesc * @param aParameterAnnotation * @param aErrorInfo * @throws Exception */ public OperatorSelfDefineClassFunction(String aOperName, Class<?> aOperClass, String aFunctionName, Class<?>[] aParameterClassTypes, String[] aParameterDesc, String[] aParameterAnnotation, String aErrorInfo) throws Exception { if (errorInfo != null && errorInfo.trim().length() == 0) { errorInfo = null; } this.name = aOperName; this.errorInfo = aErrorInfo; this.functionName = aFunctionName; this.parameterClasses = aParameterClassTypes; this.parameterTypes = new String[aParameterClassTypes.length]; this.operDataDesc = aParameterDesc; this.operDataAnnotation = aParameterAnnotation; for (int i = 0; i < this.parameterClasses.length; i++) { this.parameterTypes[i] = this.parameterClasses[i].getName(); } operClass = aOperClass; method = operClass.getMethod(functionName, parameterClasses); this.isReturnVoid = method.getReturnType().equals(void.class); this.maybeDynamicParams = DynamicParamsUtil.maybeDynamicParams(parameterClasses); }
/** * 自定义类函数构造函数 * @param aOperName * @param aClassName * @param aFunctionName * @param aParameterClassTypes * @param aParameterDesc * @param aParameterAnnotation * @param aErrorInfo * @throws Exception */ public OperatorSelfDefineClassFunction(String aOperName, String aClassName, String aFunctionName, Class<?>[] aParameterClassTypes, String[] aParameterDesc, String[] aParameterAnnotation, String aErrorInfo) throws Exception { if (errorInfo != null && errorInfo.trim().length() == 0) { errorInfo = null; } this.name = aOperName; this.errorInfo = aErrorInfo; this.functionName = aFunctionName; this.parameterClasses = aParameterClassTypes; this.parameterTypes = new String[aParameterClassTypes.length]; this.operDataDesc = aParameterDesc; this.operDataAnnotation = aParameterAnnotation; for (int i = 0; i < this.parameterClasses.length; i++) { this.parameterTypes[i] = this.parameterClasses[i].getName(); } operClass = ExpressUtil.getJavaClass(aClassName); method = operClass.getMethod(functionName, parameterClasses); this.isReturnVoid = method.getReturnType().equals(void.class); this.maybeDynamicParams = DynamicParamsUtil.maybeDynamicParams(parameterClasses); }
/** * 自定义类函数构造函数 * @param aOperName * @param aClassName * @param aFunctionName * @param aParameterTypes * @param aParameterDesc * @param aParameterAnnotation * @param aErrorInfo * @throws Exception */ public OperatorSelfDefineClassFunction(String aOperName, String aClassName, String aFunctionName, String[] aParameterTypes, String[] aParameterDesc, String[] aParameterAnnotation, String aErrorInfo) throws Exception { if (errorInfo != null && errorInfo.trim().length() == 0) { errorInfo = null; } this.name = aOperName; this.errorInfo = aErrorInfo; this.functionName = aFunctionName; this.parameterTypes = aParameterTypes; this.operDataDesc = aParameterDesc; this.operDataAnnotation = aParameterAnnotation; this.parameterClasses = new Class[this.parameterTypes.length]; for (int i = 0; i < this.parameterClasses.length; i++) { this.parameterClasses[i] = ExpressUtil.getJavaClass(this.parameterTypes[i]); } operClass = ExpressUtil.getJavaClass(aClassName); method = operClass.getMethod(functionName, parameterClasses); this.maybeDynamicParams = DynamicParamsUtil.maybeDynamicParams(parameterClasses); }
/** * 克隆 * @param opName * @param errorInfo * @return * @throws Exception */ @Override public OperatorBase cloneMe(String opName, String errorInfo) throws Exception { OperatorBase result = new OperatorSelfDefineClassFunction(opName, this.operClass.getName(), this.functionName, this.parameterClasses, this.operDataDesc, this.operDataAnnotation, errorInfo); return result; }
/** * 执行自定义类函数的执行 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { Object[] parameres = DynamicParamsUtil.transferDynamicParams(context, list, parameterClasses, this.maybeDynamicParams); Object obj = null; if (Modifier.isStatic(this.method.getModifiers())) { obj = this.method.invoke(null, ExpressUtil.transferArray(parameres, parameterClasses)); } else { if (operInstance == null) { operInstance = operClass.newInstance(); } obj = this.method.invoke(operInstance, ExpressUtil.transferArray(parameres, parameterClasses)); }
if (obj != null) { return OperateDataCacheManager.fetchOperateData(obj, obj.getClass()); } if (this.isReturnVoid == true) { return OperateDataCacheManager.fetchOperateDataAttr("null", void.class); } else { return OperateDataCacheManager.fetchOperateDataAttr("null", null); } }

}

复制代码

8.2.39、OperatorSelfDefineServiceFunction(自定义服务函数运算)

package com.ql.util.express.instruction.op;
import java.lang.reflect.Method;
import com.ql.util.express.*;import com.ql.util.express.instruction.OperateDataCacheManager;
/** * 用户自定义的服务函数操作 * * @author qhlhl2010@gmail.com */public class OperatorSelfDefineServiceFunction extends OperatorBase implements CanClone { /** * 服务对象 */ Object serviceObject; /** * 函数名字 */ String functionName; /** * 参数类型 */ String[] parameterTypes; /** * 参数类 */ Class<?>[] parameterClasses; /** * 方法 */ Method method; /** * 是否返回值 */ boolean isReturnVoid; /** * 是否动态参数 */ boolean maybeDynamicParams;
public OperatorSelfDefineServiceFunction(String aOperName, Object aServiceObject, String aFunctionName, Class<?>[] aParameterClassTypes, String[] aParameterDesc, String[] aParameterAnnotation, String aErrorInfo) throws Exception { if (errorInfo != null && errorInfo.trim().length() == 0) { errorInfo = null; } this.name = aOperName; this.errorInfo = aErrorInfo; this.serviceObject = aServiceObject; this.functionName = aFunctionName; this.parameterClasses = aParameterClassTypes; this.operDataDesc = aParameterDesc; this.operDataAnnotation = aParameterAnnotation; this.parameterTypes = new String[this.parameterClasses.length]; for (int i = 0; i < this.parameterClasses.length; i++) { this.parameterTypes[i] = this.parameterClasses[i].getName(); } Class<?> operClass = serviceObject.getClass(); method = operClass.getMethod(functionName, parameterClasses); this.isReturnVoid = method.getReturnType().equals(void.class); this.maybeDynamicParams = DynamicParamsUtil.maybeDynamicParams(parameterClasses); }
public OperatorSelfDefineServiceFunction(String aOperName, Object aServiceObject, String aFunctionName, String[] aParameterTypes, String[] aParameterDesc, String[] aParameterAnnotation, String aErrorInfo) throws Exception {
if (errorInfo != null && errorInfo.trim().length() == 0) { errorInfo = null; } this.name = aOperName; this.errorInfo = aErrorInfo; this.serviceObject = aServiceObject; this.functionName = aFunctionName; this.parameterTypes = aParameterTypes; this.operDataDesc = aParameterDesc; this.operDataAnnotation = aParameterAnnotation; this.parameterClasses = new Class[this.parameterTypes.length]; for (int i = 0; i < this.parameterClasses.length; i++) { this.parameterClasses[i] = ExpressUtil.getJavaClass(this.parameterTypes[i]); } Class<?> operClass = serviceObject.getClass(); method = operClass.getMethod(functionName, parameterClasses); this.maybeDynamicParams = DynamicParamsUtil.maybeDynamicParams(parameterClasses); }
@Override public OperatorBase cloneMe(String opName, String errorInfo) throws Exception { OperatorBase result = new OperatorSelfDefineServiceFunction(opName, this.serviceObject, this.functionName, this.parameterClasses, this.operDataDesc, this.operDataAnnotation, errorInfo); return result; }
/** * 执行内部运算 * @param context * @param list * @return * @throws Exception */ @Override public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception { Object[] parameres = DynamicParamsUtil.transferDynamicParams(context, list, parameterClasses, this.maybeDynamicParams); Object obj = this.method.invoke(this.serviceObject, ExpressUtil.transferArray(parameres, parameterClasses)); if (obj != null) { return OperateDataCacheManager.fetchOperateData(obj, obj.getClass()); } if (this.isReturnVoid == true) { return OperateDataCacheManager.fetchOperateDataAttr("null", void.class); } else { return OperateDataCacheManager.fetchOperateDataAttr("null", null); } }}

复制代码

8.3、opdata 运算数据

8.3.1、OperateClass 类操作

package com.ql.util.express.instruction.opdata;
import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;
/** * 类操作 * @author xiaochengxinyizhan */public class OperateClass extends OperateData { /** * 名称 */ private String name; /** * 类 */ private Class<?> m_class; public OperateClass(String name, Class<?> aClass) { super(null,null); this.name = name; this.m_class = aClass; } @Override public void toResource(StringBuilder builder, int level){ builder.append(this.name); } @Override public String toString() { return "Class:" + name; // return name; } public Class<?> getVarClass(){ return this.m_class; } public void reset(String aName,Class<?> newClass){ this.name = aName; this.m_class = newClass; } @Override public Object getObjectInner(InstructionSetContext parent) { return m_class; } public String getName(){ return this.name; }}

复制代码

8.3.2、OperateDataAlias 数据别名操作

package com.ql.util.express.instruction.opdata;
import com.ql.util.express.InstructionSetContext;
/** * 数据别名 * @author xiaochengxinyizhan */public class OperateDataAlias extends OperateDataAttr { /** * 真实属性 */ OperateDataAttr realAttr; public OperateDataAlias(String aName,OperateDataAttr aRealAttr) { super(aName,null); this.realAttr = aRealAttr; } @Override public String toString() { try { return this.name + "[alias=" + this.realAttr.name+"]"; } catch (Exception ex) { return ex.getMessage(); } }
/** * 获取对象内部指令对象 * @param context * @return */ @Override public Object getObjectInner(InstructionSetContext context) { try { return realAttr.getObject(context); } catch (Exception e) { throw new RuntimeException(e); } }
/** * 获取类型 * @param context * @return * @throws Exception */ @Override public Class<?> getType(InstructionSetContext context) throws Exception { return realAttr.getType(context); }
/** * 设置真实属性指令集上下文对象 * @param context * @param object */ @Override public void setObject(InstructionSetContext context, Object object) { try { realAttr.setObject(context, object); } catch (Exception e) { throw new RuntimeException(e); } }}

复制代码

8.3.3、OperateDataArrayItem 数据数组项

package com.ql.util.express.instruction.opdata;
import java.lang.reflect.Array;
import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;
/** * 数据数组项 * @author xiaochengxinyizhan */public class OperateDataArrayItem extends OperateDataAttr { /** * 数组对象 */ OperateData arrayObject; /** * 索引 */ int index;
/** * 构造函数 * @param aArrayObject * @param aIndex */ public OperateDataArrayItem(OperateData aArrayObject,int aIndex) { super("array[" + aArrayObject +"," + aIndex +"]",null); this.arrayObject = aArrayObject; this.index = aIndex; }
/** * 初始化数据组项 * @param aArrayObject * @param aIndex */ public void initialDataArrayItem(OperateData aArrayObject,int aIndex){ super.initialDataAttr("array[" + aArrayObject +"," + aIndex +"]",null); this.arrayObject = aArrayObject; this.index = aIndex; }
/** * 清除数据组项 */ public void clearDataArrayItem(){ super.clearDataAttr(); this.arrayObject = null; this.index = -1; } @Override public void toResource(StringBuilder builder, int level){ builder.append(this.index); } @Override public Class<?> getType(InstructionSetContext context) throws Exception { return this.arrayObject.getObject(context).getClass(); } @Override public Object getObjectInner(InstructionSetContext context){ try { return Array.get(this.arrayObject.getObject(context),this.index); } catch (Exception e) { throw new RuntimeException(e); } }
@Override public void setObject(InstructionSetContext context, Object value) { try { Array.set(this.arrayObject.getObject(context), this.index, value); } catch (Exception e) { throw new RuntimeException(e); } }}
复制代码

8.3.4、OperateDataAttr 数据属性操作

package com.ql.util.express.instruction.opdata;
import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;
/** * 数据属性操作 * * @author xiaochengxinyizhan */public class OperateDataAttr extends OperateData { /** * 名称 */ protected String name;
/** * 构造函数 * @param aName * @param aType */ public OperateDataAttr(String aName, Class<?> aType) { super(null, aType); this.name = aName; }
/** * 初始化 * @param aName * @param aType */ public void initialDataAttr(String aName, Class<?> aType) { super.initial(null, aType); this.name = aName; }
/** * 清除数据属性 */ public void clearDataAttr() { super.clear(); this.name = null; }
/** * 设置定义类型 * @param orgiType */ public void setDefineType(Class<?> orgiType) { this.type = orgiType; }
/** * 获取定义类型 * @return */ @Override public Class<?> getDefineType() { return this.type; }
public String getName() { return name; }
@Override public void toResource(StringBuilder builder, int level) { builder.append(this.name); }
@Override public String toString() { try { String str = ""; if (this.type == null) { str = name; } else { str = name + "[" + ExpressUtil.getClassName(this.type) + "]"; } return str; } catch (Exception ex) { return ex.getMessage(); } }
/** * 获取表达式计算的上下文 * @param context * @return * @throws Exception */ @Override public Object getObjectInner(InstructionSetContext context) throws Exception { if (this.name.equalsIgnoreCase("null")) { return null; } if (context == null) { throw new RuntimeException("没有设置表达式计算的上下文,不能获取属性:\"" + this.name + "\"请检查表达式"); } try { return context.get(this.name); } catch (Exception e) { throw new RuntimeException(e); } }
/** * 获取指令集上下文类 * @param context * @return * @throws Exception */ @Override public Class<?> getType(InstructionSetContext context) throws Exception { if (this.type != null) { return this.type; } Object obj = context.get(name); if (obj == null) return null; else return obj.getClass(); }
@Override public void setObject(InstructionSetContext parent, Object object) throws Exception { try { parent.put(this.name, object); } catch (Exception e) { throw new RuntimeException(e); } }}

复制代码


8.3.5、OperateDataField 数据属性操作

package com.ql.util.express.instruction.opdata;
import com.ql.util.express.ExpressUtil;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.config.QLExpressRunStrategy;import com.ql.util.express.parse.AppendingClassFieldManager;
/** * 数据属性操作 * @author xiaochengxinyizhan */public class OperateDataField extends OperateDataAttr { Object fieldObject; String orgiFieldName; public OperateDataField(Object aFieldObject,String aFieldName) { super(null,null); if(aFieldObject == null){ this.name = "没有初始化的Field"; }else{ this.name = aFieldObject.getClass().getName() + "." + aFieldName; } this.fieldObject = aFieldObject; this.orgiFieldName =aFieldName; } public void initialDataField(Object aFieldObject,String aFieldName){ super.initialDataAttr(null, null); if(aFieldObject==null){ this.name = Void.class.getName()+ "." + aFieldName; }else { this.name = aFieldObject.getClass().getName() + "." + aFieldName; } this.fieldObject = aFieldObject; this.orgiFieldName = aFieldName; } public void clearDataField(){ super.clearDataAttr(); this.name = null; this.fieldObject = null; this.orgiFieldName = null; } @Override public String getName(){ return name; } @Override public String toString() { try { return name; } catch (Exception ex) { return ex.getMessage(); } }
public Object transferFieldName(InstructionSetContext context,String oldName){ if (context.isSupportDynamicFieldName() == false) { return oldName; } else { try { OperateDataAttr o = (OperateDataAttr) context .findAliasOrDefSymbol(oldName); if (o != null) { return o.getObject(context); } else { return oldName; } } catch (Exception e) { throw new RuntimeException(e); } } } @Override public Object getObjectInner(InstructionSetContext context) throws Exception {
AppendingClassFieldManager appendingClassFieldManager = context.getExpressRunner().getAppendingClassFieldManager();
if(appendingClassFieldManager!=null) { AppendingClassFieldManager.AppendingField appendingField = appendingClassFieldManager.getAppendingClassField(this.fieldObject, this.orgiFieldName); if (appendingField != null) { return appendingClassFieldManager.invoke(appendingField, context, this.fieldObject, null); } } //如果能找到aFieldName的定义,则再次运算 if(this.fieldObject instanceof OperateDataVirClass){ return ((OperateDataVirClass)this.fieldObject).getValue(transferFieldName(context,this.orgiFieldName)); }else{ return ExpressUtil.getProperty(this.fieldObject,transferFieldName(context,this.orgiFieldName)); } } @Override public Class<?> getType(InstructionSetContext context) throws Exception { AppendingClassFieldManager appendingClassFieldManager = context.getExpressRunner().getAppendingClassFieldManager();
if(appendingClassFieldManager!=null) { AppendingClassFieldManager.AppendingField appendingField = appendingClassFieldManager.getAppendingClassField(this.fieldObject, this.orgiFieldName); if (appendingField != null) { return appendingField.returnType; } } if(this.fieldObject instanceof OperateDataVirClass){ return ((OperateDataVirClass)this.fieldObject).getValueType(transferFieldName(context,this.orgiFieldName)); }else{ if(this.fieldObject==null && QLExpressRunStrategy.isAvoidNullPointer()){ return Void.class; } return ExpressUtil.getPropertyClass(this.fieldObject,transferFieldName(context,this.orgiFieldName)); } }
@Override public void setObject(InstructionSetContext context, Object value) throws Exception{ if(this.fieldObject instanceof OperateDataVirClass){ ((OperateDataVirClass)this.fieldObject).setValue(transferFieldName(context,this.orgiFieldName).toString(),value); }else{ ExpressUtil.setProperty(fieldObject, transferFieldName(context,this.orgiFieldName), value); } }}

复制代码


8.3.6、OperateDataKeyValue 数据 keyValue 操作

package com.ql.util.express.instruction.opdata;
import com.ql.util.express.InstructionSetContext;import com.ql.util.express.OperateData;
/** * 数据keyValue操作 * @author xiaochengxinyizhan */public class OperateDataKeyValue extends OperateData { /** * 数据操作key */ OperateData key; /** * 数据操作value */ OperateData value;
/** * 构造函数 * @param aKey * @param aValue */ public OperateDataKeyValue(OperateData aKey, OperateData aValue) { super(null, null); this.key = aKey; this.value = aValue; }
/** * 初始化数据keyValue * @param aKey * @param aValue */ public void initialDataKeyValue(OperateData aKey, OperateData aValue){ super.initial(null, null); this.key = aKey; this.value = aValue; } public void clearDataKeyValue(){ super.clear(); this.key = null; this.value = null; } public OperateData getKey() { return key; }
public OperateData getValue() { return value; }
@Override public String toString() { return this.key + ":" + this.value; }
@Override public Object getObjectInner(InstructionSetContext context) { throw new RuntimeException("没有实现方法:getObjectInner"); }
@Override public Class<?> getType(InstructionSetContext context) throws Exception { throw new RuntimeException("没有实现方法:getType"); }
@Override public void setObject(InstructionSetContext parent, Object object) { throw new RuntimeException("没有实现方法:setObject"); }}

复制代码


8.3.7、OperateDataLocalVar 数据本地变量

package com.ql.util.express.instruction.opdata;
import com.ql.util.express.InstructionSetContext;

/** * 数据本地变量 * @author xiaochengxinyizhan */public class OperateDataLocalVar extends OperateDataAttr { /** * 构造函数 * @param name * @param type */ public OperateDataLocalVar(String name,Class<?> type) { super(name,type); }
/** * 初始化数据本地变量 * @param name * @param type */ public void initialDataLocalVar(String name,Class<?> type){ super.initialDataAttr(name, type); }
/** * 清除数据本地变量 */ public void clearDataLocalVar(){ super.clear(); } @Override public String toString() { try { return name +":localVar"; } catch (Exception ex) { return ex.getMessage(); } }
@Override public Object getObjectInner(InstructionSetContext context) { try { return this.dataObject; } catch (Exception e) { throw new RuntimeException(e); } } @Override public Class<?> getType(InstructionSetContext context) throws Exception { return this.type; }
@Override public void setObject(InstructionSetContext parent, Object value) { this.dataObject = value; }}

复制代码


8.3.8、OperateDataVirClass 虚拟 Class 的内存对象

package com.ql.util.express.instruction.opdata;
import java.util.List;
import com.ql.util.express.exception.QLException;import org.apache.commons.logging.Log;
import com.ql.util.express.InstructionSet;import com.ql.util.express.InstructionSetContext;import com.ql.util.express.InstructionSetRunner;import com.ql.util.express.OperateData;import com.ql.util.express.instruction.OperateDataCacheManager;

/** * 虚拟Class的内存对象 * @author xuannan * */public class OperateDataVirClass extends OperateDataAttr{ /** * 虚拟Class的数据上下文 */ InstructionSetContext context; /** * 虚拟类的指令集合 */ InstructionSet virClassInstructionSet; /** * 是否trace打印 */ boolean isTrace; /** * log对象 */ Log log;
/** * 构造函数 * @param name */ public OperateDataVirClass(String name){ super(name,null); }
/** * 初始化实例 * @param parent * @param parameters * @param errorList * @param aIsTrace * @param aLog * @throws Exception */ public void initialInstance(InstructionSetContext parent,OperateData[] parameters, List<String> errorList,boolean aIsTrace,Log aLog) throws Exception { this.isTrace = aIsTrace; this.log = aLog; this.context = OperateDataCacheManager.fetchInstructionSetContext(false, parent.getExpressRunner(),parent,parent.getExpressLoader(),parent.isSupportDynamicFieldName()); Object functionSet = parent.getSymbol(this.name); if (functionSet == null || functionSet instanceof InstructionSet == false) { throw new QLException("没有找到自定义对象\"" + this.name + "\""); } this.virClassInstructionSet = (InstructionSet)functionSet; OperateDataLocalVar[] vars = virClassInstructionSet.getParameters(); for(int i=0;i<vars.length;i++){ //注意此处必须new 一个新的对象,否则就会在多次调用的时候导致数据冲突 OperateDataLocalVar var = OperateDataCacheManager.fetchOperateDataLocalVar(vars[i].getName(),vars[i].getOrgiType()); this.context.addSymbol(var.getName(), var); var.setObject(context, parameters[i].getObject(parent)); } InstructionSetRunner.execute((InstructionSet)virClassInstructionSet, context,errorList,aIsTrace,false,false,log); }
/** * 调用自定义函数 * @param functionName * @param parameters * @return * @throws Exception */ public OperateData callSelfFunction(String functionName,OperateData[] parameters) throws Exception{ Object function = this.context.getSymbol(functionName); if (function == null || function instanceof InstructionSet == false) { throw new QLException("在VClass:"+ this.name +"中没有定义函数\"" + functionName + "\""); } InstructionSet functionSet = (InstructionSet)function; InstructionSetContext tempContext = OperateDataCacheManager.fetchInstructionSetContext( true,this.context.getExpressRunner(),this.context,this.context.getExpressLoader(), this.context.isSupportDynamicFieldName()); OperateDataLocalVar[] vars = functionSet.getParameters(); for(int i=0;i<vars.length;i++){ //注意此处必须new 一个新的对象,否则就会在多次调用的时候导致数据冲突 OperateDataLocalVar var = OperateDataCacheManager.fetchOperateDataLocalVar(vars[i].getName(),vars[i].getOrgiType()); tempContext.addSymbol(var.getName(), var); var.setObject(tempContext, parameters[i].getObject(this.context)); } Object result =InstructionSetRunner.execute((InstructionSet)functionSet, tempContext,null,this.isTrace,false,true,this.log); return OperateDataCacheManager.fetchOperateData(result,null); }
/** * 获取名称对应的值 * @param name * @return * @throws Exception */ public Object getValue(Object name) throws Exception{ Object o = this.context.findAliasOrDefSymbol(name.toString()); if(o == null){ return null; //变量定义 }else if(o instanceof OperateData){ return ((OperateData)o).getObject(context); //宏定义 }else if( o instanceof InstructionSet){ InstructionSetContext tempContext = OperateDataCacheManager.fetchInstructionSetContext( true,this.context.getExpressRunner(),this.context,this.context.getExpressLoader(), this.context.isSupportDynamicFieldName()); Object result =InstructionSetRunner.execute( this.context.getExpressRunner(), (InstructionSet)o, this.context.getExpressLoader(), tempContext, null, this.isTrace, false,false,this.log, this.context.isSupportDynamicFieldName()); if(result instanceof OperateData){ return ((OperateData)result).getObject(this.context); }else{ return result; } }else{ throw new QLException("不支持的数据类型:" + o.getClass().getName()); } }
/** * 给名字设置值 * @param name * @param value * @throws Exception */ public void setValue(String name,Object value) throws Exception{ Object o = this.context.findAliasOrDefSymbol(name.toString()); if(o instanceof OperateData){ ((OperateData)o).setObject(context,value); }else{ throw new QLException("不支持的数据类型:" + o.getClass().getName()); } }
/** * 获取值的数据类型 * @param name * @return * @throws Exception */ public Class<?> getValueType(Object name) throws Exception{ Object o = this.context.findAliasOrDefSymbol(name.toString()); if(o instanceof OperateData){ return ((OperateData)o).getType(context); }else{ throw new QLException("不支持的数据类型:" + o.getClass().getName()); } } @Override public Object getObjectInner(InstructionSetContext context) { return this; } @Override public Class<?> getType(InstructionSetContext context) throws Exception { return this.getClass(); }
@Override public void setObject(InstructionSetContext parent, Object object) { throw new RuntimeException("不支持的方法"); } @Override public String toString(){ return "VClass[" + this.name+"]"; }}

复制代码


发布于: 2021 年 01 月 16 日阅读数: 22
用户头像

小胜靠智,大胜靠德 2019.06.27 加入

历经创业、京东、腾讯、滴滴公司,希望能够有些东西一起分享。公众号:小诚信驿站,微信/CSDN搜索:wolf_love666

评论

发布
暂无评论
案例研究之聊聊 QLExpress 源码 (八-1)