案例研究之聊聊 QLExpress 源码 (八 -1)
发布于: 2021 年 01 月 16 日
指令模块是非常大的一个模块,代码非常多,分为 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
版权声明: 本文为 InfoQ 作者【小诚信驿站】的原创文章。
原文链接:【http://xie.infoq.cn/article/96c6c2a2526afe24067a1a2fd】。文章转载请联系作者。
小诚信驿站
关注
小胜靠智,大胜靠德 2019.06.27 加入
历经创业、京东、腾讯、滴滴公司,希望能够有些东西一起分享。公众号:小诚信驿站,微信/CSDN搜索:wolf_love666
评论