Bootstrap

案例研究之聊聊 QLExpress 源码 (九)

九、other

9.1、ArraySwap(数组交换)

package com.ql.util.express;

/**
 * 数组交换
 * @author xiaochengxinyizhan
 */
public final class ArraySwap {
	OperateData[] arrays;
	int start;
	public int length;
	
	public void swap(OperateData[] aArrays,int aStart ,int aLength){
		this.arrays = aArrays;
		this.start = aStart;
		this.length = aLength;
	}
	public OperateData get(int i){
		return this.arrays[i+start];
	}

}

9.2、CacheObject(简单的缓存对象)

package com.ql.util.express;

import java.io.Serializable;

/**
 * 简单的缓存对象
 * @author tianqiao
 *
 */
public class CacheObject implements Serializable{
	

	private static final long serialVersionUID = -145121001676214513L;
	/**
	 * 表达式名字
	 */
	private String expressName;
	/**
	 * 文本
	 */
	private String text;
	/**
	 * 指令集
	 */
	private InstructionSet instructionSet;

	public String getExpressName() {
		return expressName;
	}

	public void setExpressName(String name) {
		this.expressName = name;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public InstructionSet getInstructionSet() {
		return instructionSet;
	}

	public void setInstructionSet(InstructionSet instructionSet) {
		this.instructionSet = instructionSet;
	}

}

9.3、CallResult(调用结果)

package com.ql.util.express;

/**
 * 调用结果
 * @author xiaochengxinyizhan
 */
public class CallResult{
	/**
	 * 返回值
	 */
	private Object returnValue;
	/**
	 * 是否退出
	 */
	private boolean isExit;
	public CallResult(Object aReturnValue,boolean aIsExit){
		this.initial(aReturnValue, aIsExit);
	}
	public void initial(Object aReturnValue,boolean aIsExit){
		this.returnValue = aReturnValue;
		this.isExit = aIsExit;
	}
	public void clear(){
		this.returnValue = null;
		this.isExit = false;
	}
	public Object getReturnValue() {
		return returnValue;
	}
	public boolean isExit() {
		return isExit;
	}
	
}


9.4、DefaultContext(默认上下文)

package com.ql.util.express;

import java.util.HashMap;

/**
 * 警告,以后会下掉不建议使用
 * @param 
 * @param 
 */
@SuppressWarnings("serial")
public class DefaultContext extends HashMap implements IExpressContext { 
}

9.5、DefaultExpressResourceLoader(默认的表达式资源加载器)

package com.ql.util.express;

import com.ql.util.express.exception.QLException;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * 默认的表达式资源加载器
 * @author xiaochengxinyizhan
 */
public class DefaultExpressResourceLoader implements IExpressResourceLoader {
	@Override
	public String loadExpress(String expressName) throws Exception {
		expressName = expressName.replace('.', '/') + ".ql";
		InputStream in = Thread.currentThread().getContextClassLoader()
				.getResourceAsStream(expressName);
		if (in == null) {
			throw new QLException("不能找到表达式文件:" + expressName);
		}
		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		StringBuilder builder = new StringBuilder();
		String tmpStr = null;
		while ((tmpStr = reader.readLine()) != null) {
			builder.append(tmpStr).append("\n");
		}
		reader.close();
		in.close();
		return builder.toString();
	}
}

9.6、DynamicParamsUtil(动态参数工具类)

package com.ql.util.express;

import com.ql.util.express.exception.QLException;

import java.lang.reflect.Array;

/**
 * 动态参数工具类
 * Created by tianqiao on 16/9/12.
 */
public class DynamicParamsUtil {

    public static boolean supportDynamicParams = false;

    /**
     * 转成动态参数
     * @param context
     * @param list
     * @param delaredParamsClasses
     * @param maybeDynamicParams
     * @return
     * @throws Exception
     */
    public static Object[] transferDynamicParams(InstructionSetContext context, ArraySwap list, Class[] delaredParamsClasses,boolean maybeDynamicParams) throws Exception {

        Object[] params = null;
        //参数定义不符合动态参数形式 || 用户自定义不支持 || 用户传入的参数不符合
        if(!maybeDynamicParams || !supportDynamicParams || !maybeDynamicParams(context,list,delaredParamsClasses)){
            if(delaredParamsClasses.length != list.length){
                throw new QLException("定义的参数长度与运行期传入的参数长度不一致");
            }
            params = new Object[list.length];
            for (int i = 0; i < list.length; i++) {
                params[i] = list.get(i).getObject(context);
            }
            return params;
        }

        //支持不定参数的使用 function(arg1,arg2,arg3...)
        //list -> parameres[]
        // arg1,arg2 -> arg1,arg2,[]
        // arg1,arg2,arg3,arg4,arg5   ->  arg1,arg2,[arg3,arg4,arg5]
        int paramLength = delaredParamsClasses.length;
        int beforeCount = paramLength-1;
        int paramsCount = list.length - beforeCount;

        if(beforeCount>=0 && ((Class)(delaredParamsClasses[beforeCount])).isArray() && paramsCount>=0){
            ClasscomponentType = delaredParamsClasses[beforeCount].getComponentType();
            params = new Object[beforeCount+1];
            Object[] lastParameres = (Object[]) Array.newInstance(componentType,paramsCount);
            params[beforeCount] = lastParameres;
            for (int i = 0; i < list.length; i++) {
                if(i[] delaredParamsClasses)
    {
        int length = delaredParamsClasses.length;
        if(length>0 && delaredParamsClasses[length-1].isArray())
        {
            return true;
        }
        return false;
    }

    /**
     * 是否动态参数
     * @param context
     * @param list
     * @param delaredParamsClasses
     * @return
     * @throws Exception
     */
    private static boolean maybeDynamicParams(InstructionSetContext context, ArraySwap list, Class[] delaredParamsClasses) throws Exception {

        //长度不一致,有可能
        if(delaredParamsClasses.length != list.length) {
            return true;
        }
        //长度一致的不定参数:不定参数的数组,只输入了一个参数并且为array,有可能
        int length = list.length;
        Object lastParam = list.get(length-1).getObject(context);
        if(lastParam!=null && !lastParam.getClass().isArray())
        {
            return true;
        }
        return false;
    }
}

9.7、ExportItem(输出给其它指令共享使用的对象)

package com.ql.util.express;

import java.io.Serializable;

/**
 * 输出给其它指令共享使用的对象
 * @author xuannan
 *
 */
public class ExportItem implements Serializable{
	private static final long serialVersionUID = 5440012774123494760L;
	public static String TYPE_ALIAS ="alias";
	public static String TYPE_DEF ="def";
	public static String TYPE_FUNCTION ="function";
	public static String TYPE_MACRO ="macro";
	String globeName;
	String name;
	String type;//def,alias
	String desc;//类名或者别名
	public ExportItem(String aName,String aType,String aDesc){
		this.globeName = aName;
		this.name = aName;
		this.type =aType;
		this.desc = aDesc;	
	}
	public ExportItem(String aGlobeName,String aName,String aType,String aDesc){
		this.globeName = aGlobeName;
		this.name = aName;
		this.type =aType;
		this.desc = aDesc;	
	}
	public String toString(){
		return this.globeName + "["+ this.type +":" + this.name +" " + this.desc + "]";
	}
	public String getGlobeName() {
		return globeName;
	}
	public void setGlobeName(String globeName) {
		this.globeName = globeName;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
	
}

9.8、ExpressClassLoader(表达式类加载器)

package com.ql.util.express;

import java.lang.reflect.Array;
import java.lang.reflect.Method;

/**
 * 表达式类加载器
 * @author xiaochengxinyizhan
 */
public class ExpressClassLoader extends ClassLoader {
	public ExpressClassLoader(ClassLoader parent){
		super(parent);
	}
	public Class loadClass(String name, byte[] code) {
		return this.defineClass(name, code, 0, code.length);
	}

	@Override
	public synchronized Class loadClass(String name, boolean resolve)
			throws ClassNotFoundException {
		//System.out.print("开始查找 类" + name + "。。。。。。。。。。。");
		Class clasz = findLoadedClass(this, name);
		if (clasz != null) {
			//System.out.println(clasz.getClassLoader());
			return clasz;
		}
		if (clasz == null) {
			clasz = parentLoadClass(this, name);
		}
		if (clasz == null && name.startsWith("[")) { // 进行数组处理
			int index = name.indexOf("L");
			String str = name.substring(0, index);
			String componentClassName = name.substring(index + 1,
					name.length() - 1);
			int[] dimes = new int[str.length()];
			for (int i = 0; i < dimes.length; i++) {
				dimes[i] = 0;
			}
			try {
				Class componentType = this.loadClass(componentClassName);
				clasz = Array.newInstance(componentType, dimes).getClass();
			} catch (Exception e) {
				// 不错处理
			}
		}

		if (clasz == null)
			throw new ClassNotFoundException(name);
		return clasz;
	}

	/**
	 * 查找加载类
	 * @param loader
	 * @param name
	 * @return
	 * @throws ClassNotFoundException
	 */
	public static Class findLoadedClass(ClassLoader loader, String name)
			throws ClassNotFoundException {
		Method m = null;
		try {
			m = ClassLoader.class.getDeclaredMethod("findLoadedClass",
					new Class[] { String.class });
			m.setAccessible(true);
			Class result = (Class) m.invoke(loader, new Object[] { name });
			if (result == null) {
				result = (Class) m.invoke(loader.getClass().getClassLoader(),
						new Object[] { name });
			}
			if (result == null) {
				result = (Class) m.invoke(Thread.currentThread()
						.getContextClassLoader(), new Object[] { name });
			}
			return result;
		} catch (Exception ex) {
			throw new ClassNotFoundException(ex.getMessage());
		} finally {
			if (m != null) {
				m.setAccessible(false);
			}
		}
	}

	public static Class parentLoadClass(ClassLoader loader, String name)
			throws ClassNotFoundException {
		// 如果存在这个类,则直接返回
		Class clasz = null;
		if (clasz == null) {
			try {
				clasz = loader.getClass().getClassLoader().loadClass(name);
			} catch (Throwable e) {
			}
		}
		if (clasz == null)
			try {
				clasz = Thread.currentThread().getContextClassLoader()
						.loadClass(name);
			} catch (Throwable e) {
			}
		return clasz;
	}
}

9.9、ExpressLoader(表达式装载器)

package com.ql.util.express;

import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

import com.ql.util.express.exception.QLException;
import com.ql.util.express.instruction.FunctionInstructionSet;


/**
 * 表达式装载器
 * 
 * @author xuannan
 * 
 */
public class ExpressLoader {
	/**
	 * 表达式指令集缓存
	 */
	private  ConcurrentHashMap expressInstructionSetCache = new ConcurrentHashMap();
	/**
	 * 表达式运行器
	 */
	ExpressRunner creator;
	public ExpressLoader(ExpressRunner aCreator){
		this.creator = aCreator;
	}
	public InstructionSet loadExpress(String expressName)
			throws Exception {
		return parseInstructionSet(expressName,this.creator.getExpressResourceLoader().loadExpress(expressName));		
	}

	/**
	 * 添加指令集
	 * @param expressName
	 * @param set
	 * @throws Exception
	 */
	public void addInstructionSet(String expressName, InstructionSet set)
			throws Exception {
		synchronized (expressInstructionSetCache) {
			if (expressInstructionSetCache.containsKey(expressName)) {
				throw new QLException("表达式定义重复:" + expressName);
			}
			expressInstructionSetCache.put(expressName, set);
		}
	}

	/**
	 * 解析指令集合
	 * @param expressName
	 * @param expressString
	 * @return
	 * @throws Exception
	 */
	public InstructionSet parseInstructionSet(String expressName,
			String expressString) throws Exception {
		InstructionSet parseResult = null;
		if (expressInstructionSetCache.containsKey(expressName)) {
			throw new QLException("表达式定义重复:" + expressName);
		}
		synchronized (expressInstructionSetCache) {
			parseResult = this.creator.parseInstructionSet(expressString);
			parseResult.setName(expressName);
			parseResult.setGlobeName(expressName);
			// 需要将函数和宏定义都提取出来
			for (FunctionInstructionSet item : parseResult
					.getFunctionInstructionSets()) {
				this.addInstructionSet(item.name, item.instructionSet);
				item.instructionSet.setName(item.name);
				item.instructionSet.setGlobeName(expressName+ "." + item.name);
			}
			if(parseResult.hasMain()){
			   this.addInstructionSet(expressName, parseResult);
			}
		}
		return parseResult;
	}

	/**
	 * 清除指令集缓存
	 */
   public void clear(){
	   this.expressInstructionSetCache.clear();
   }

	/**
	 * 获取指令集
	 * @param expressName
	 * @return
	 */
	public InstructionSet getInstructionSet(String expressName) {
			return expressInstructionSetCache.get(expressName);
	}

	/**
	 * 获取导出信息
	 * @return
	 */
	public ExportItem[] getExportInfo(){
		Map result = new TreeMap();
		for(InstructionSet item:expressInstructionSetCache.values()){
			for(ExportItem var:item.getExportDef()){
				var.setGlobeName(item.getGlobeName() + "." + var.name);
				result.put(var.getGlobeName(),var);
			}
			result.put(item.getGlobeName(),new ExportItem(item.getGlobeName(), item.getName(),item.getType(),item.toString()));
		}
		return (ExportItem[])result.values().toArray(new ExportItem[0]);
	}
}

9.10、ExpressRemoteCacheRunner(远程缓存对象)

package com.ql.util.express;

import java.util.List;

import org.apache.commons.logging.Log;

/**
 * 远程缓存对象
 * @author tianqiao
 *
 */
public abstract class ExpressRemoteCacheRunner {


	/**
	 * 加载缓存
	 * @param expressName
	 * @param text
	 */
	public void loadCache(String expressName,String text){
		InstructionSet instructionSet;
		try {
			instructionSet = getExpressRunner().parseInstructionSet(text);
			CacheObject cache = new CacheObject();
			cache.setExpressName(expressName);
			cache.setText(text);
			cache.setInstructionSet(instructionSet);
			this.putCache(expressName, cache);
		} catch (Exception e) {
			throw new RuntimeException("解析指令并缓存过程出现错误.",e);
		}		
	}

	/**
	 * 执行
	 * @param name
	 * @param context
	 * @param errorList
	 * @param isTrace
	 * @param isCatchException
	 * @param aLog
	 * @return
	 */
	public Object execute(String name,IExpressContext context, List errorList,
			boolean isTrace,boolean isCatchException, Log aLog){
		try {
			CacheObject cache = (CacheObject) this.getCache(name);
			if(cache==null){
				throw new RuntimeException("未获取到缓存对象.");
			}
			return getExpressRunner().execute(cache.getInstructionSet(), context, errorList, isTrace, isCatchException, aLog);
		} catch (Exception e) {
			throw new RuntimeException("获取缓存信息,并且执行指令集出现错误.",e);
		}		
	}
	
	/**
	 * 获取执行器ExpressRunner
	 * @return
	 */
	public  abstract ExpressRunner getExpressRunner();
	/**
	 * 获取缓存对象
	 * @param key
	 * @return
	 */
	public abstract Object getCache(String key);
	/**
	 * 放置缓存的对象
	 * @param key
	 * @param object
	 */
	public abstract void putCache(String key,Object object );

}

9.11、ExpressRunner(语法分析和计算的入口类)

package com.ql.util.express;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.ql.util.express.config.QLExpressTimer;
import com.ql.util.express.exception.QLCompileException;
import com.ql.util.express.exception.QLException;
import com.ql.util.express.exception.QLTimeOutException;
import com.ql.util.express.instruction.op.*;
import com.ql.util.express.parse.*;
import com.ql.util.express.rule.Condition;
import com.ql.util.express.rule.Rule;
import com.ql.util.express.rule.RuleManager;
import com.ql.util.express.rule.RuleResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ql.util.express.instruction.ForRelBreakContinue;
import com.ql.util.express.instruction.IOperateDataCache;
import com.ql.util.express.instruction.InstructionFactory;
import com.ql.util.express.instruction.OperateDataCacheImpl;

/**
 * 语法分析和计算的入口类
 * @author xuannan
 *
 */
public class ExpressRunner {

	private static final Log log = LogFactory.getLog(ExpressRunner.class);
	private static final String GLOBAL_DEFINE_NAME="全局定义";
	/**
	 * 是否输出所有的跟踪信息,同时还需要log级别是DEBUG级别
	 */
	private boolean isTrace = false;

	/**
	 * 是否使用逻辑短路特性增强质量的效率
	 */
	private boolean isShortCircuit = true;

	/**
	 * 是否需要高精度计算
	 */
	private boolean isPrecise = false;

	/**
	 * 一段文本对应的指令集的缓存
	 */
    private Map expressInstructionSetCache = new HashMap();

	/**
	 * 一段文本对应的规则的缓存
	 */
	private Map ruleCache = new HashMap();

    private ExpressLoader loader;
    private IExpressResourceLoader expressResourceLoader;
    /**
     * 语法定义的管理器
     */
	private NodeTypeManager manager;
	/**
	 * 操作符的管理器
	 */
	private OperatorFactory operatorManager;
	/**
	 * 语法分析器
	 */
	private ExpressParse parse ;

	/**
	 * 缺省的Class查找的包管理器
	 */
	ExpressPackage rootExpressPackage = new ExpressPackage(null);

	public AppendingClassMethodManager getAppendingClassMethodManager() {
		return appendingClassMethodManager;
	}

	private AppendingClassMethodManager appendingClassMethodManager;

	public AppendingClassFieldManager getAppendingClassFieldManager() {
		return appendingClassFieldManager;
	}

	private AppendingClassFieldManager appendingClassFieldManager;

	private ThreadLocal m_OperateDataObjectCache = new ThreadLocal(){
		protected IOperateDataCache initialValue() {
	        return new OperateDataCacheImpl(30);
	    }
	};
	public IOperateDataCache getOperateDataCache(){
		return this.m_OperateDataObjectCache.get();
	}

	public ExpressRunner(){
		this(false,false);
	}
	/**
	 *
	 * @param aIsPrecise 是否需要高精度计算支持
	 * @param aIstrace 是否跟踪执行指令的过程
	 */
	public ExpressRunner(boolean aIsPrecise,boolean aIstrace){
		this(aIsPrecise,aIstrace,new DefaultExpressResourceLoader(),null);
	}
	public ExpressRunner(boolean aIsPrecise,boolean aIstrace,NodeTypeManager aManager){
		this(aIsPrecise,aIstrace,new DefaultExpressResourceLoader(),aManager);
	}
	/**
	 *
	 * @param aIsPrecise 是否需要高精度计算支持
	 * @param aIstrace 是否跟踪执行指令的过程
	 * @param aExpressResourceLoader 表达式的资源装载器
	 */
	public ExpressRunner(boolean aIsPrecise,boolean aIstrace,IExpressResourceLoader aExpressResourceLoader,NodeTypeManager aManager){
		this.isTrace = aIstrace;
		this.isPrecise = aIsPrecise;
		this.expressResourceLoader = aExpressResourceLoader;
		if(aManager == null){
			manager = new NodeTypeManager();
		}else{
			manager = aManager;
		}
		this.operatorManager = new OperatorFactory(this.isPrecise);
		this.loader = new ExpressLoader(this);
		this.parse =  new ExpressParse(manager,this.expressResourceLoader,this.isPrecise);
		rootExpressPackage.addPackage("java.lang");
		rootExpressPackage.addPackage("java.util");
		this.addSystemFunctions();
        this.addSystemOperators();
	}
    
    private void addSystemOperators() {
	    try {
            this.addOperator("instanceof", new OperatorInstanceOf("instanceof"));
        }catch (Exception e){
	        throw new RuntimeException(e);
        }
    }
    
    public void addSystemFunctions(){
		  this.addFunction("max", new OperatorMinMax("max"));
		  this.addFunction("min", new OperatorMinMax("min"));
		  this.addFunction("round", new OperatorRound("round"));
		  this.addFunction("print", new OperatorPrint("print"));
		  this.addFunction("println", new OperatorPrintln("println"));
	}

	/**
	 * 获取语法定义的管理器
	 * @return
	 */
	public NodeTypeManager getNodeTypeManager(){
		return this.manager;
	}
	/**
	 * 获取操作符号管理器
	 * @return
	 */
	public OperatorFactory getOperatorFactory(){
		return this.operatorManager;
	}
	public IExpressResourceLoader getExpressResourceLoader(){
		return this.expressResourceLoader;
	}
	/**
	 * 添加宏定义 例如: macro 玄难 { abc(userinfo.userId);}
	 * @param macroName:玄难
	 * @param express :abc(userinfo.userId);
	 * @throws Exception
	 */
	public void addMacro(String macroName,String express) throws Exception{
		String macroExpress = "macro " + macroName  +" {" + express + "}";
		this.loader.parseInstructionSet(GLOBAL_DEFINE_NAME,macroExpress);
	}

	/**
	 * 装载表达式,但不执行,例如一些宏定义,或者自定义函数
	 * @param groupName
	 * @param express
	 * @throws Exception
	 */
	public void loadMutilExpress(String groupName,String express) throws Exception{
		if(groupName == null || groupName.trim().length() ==0){
			groupName = GLOBAL_DEFINE_NAME;
		}
		this.loader.parseInstructionSet(groupName,express);
	}
    /**
     * 装载文件中定义的Express
     * @param expressName
     * @throws Exception
     */
	public void loadExpress(String expressName) throws Exception {
		this.loader.loadExpress(expressName);
	}
	/**
	 * 添加函数定义
	 * @param name 函数名称
	 * @param op 对应的操作实现类
	 */
	public void addFunction(String name, OperatorBase op) {
		this.operatorManager.addOperator(name, op);
		this.manager.addFunctionName(name);
	};

	/**
	 * 添加函数定义扩展类的方法
	 * @param name
	 * @param bindingClass
     * @param op
     */
	public void addFunctionAndClassMethod(String name,ClassbindingClass, OperatorBase op) {
		this.addFunction(name,op);
		this.addClassMethod(name,bindingClass,op);

	};

	/**
	 * 添加类的方法
	 * @param field
	 * @param bindingClass
	 * @param op
	 */
	public void addClassField(String field,ClassbindingClass,Operator op)
	{
		this.addClassField(field,bindingClass,Object.class,op);
	}

	/**
	 * 添加类的方法
	 * @param field
	 * @param bindingClass
	 * @param returnType
	 * @param op
	 */
	public void addClassField(String field,ClassbindingClass,ClassreturnType,Operator op)
	{
		if(this.appendingClassFieldManager==null){
			this.appendingClassFieldManager = new AppendingClassFieldManager();
		}
		this.appendingClassFieldManager.addAppendingField(field, bindingClass,returnType,op);
	}

	/**
	 * 添加类的方法
	 * @param name
	 * @param bindingClass
     * @param op
     */
	public void addClassMethod(String name,ClassbindingClass,OperatorBase op)
	{
		if(this.appendingClassMethodManager==null){
			this.appendingClassMethodManager = new AppendingClassMethodManager();
		}
		this.appendingClassMethodManager.addAppendingMethod(name, bindingClass, op);
	}
	/**
	 * 获取函数定义,通过函数定义可以拿到参数的说明信息
	 * @param name 函数名称
	 * @return
	 */
	public OperatorBase getFunciton(String name){
		return this.operatorManager.getOperator(name);
	}
    /**
     * 添加一个类的函数定义,例如:Math.abs(double) 映射为表达式中的 "取绝对值(-5.0)"
     * @param name 函数名称
     * @param aClassName 类名称
     * @param aFunctionName 类中的方法名称
     * @param aParameterClassTypes 方法的参数类型名称
     * @param errorInfo 如果函数执行的结果是false,需要输出的错误信息
     * @throws Exception
     */
	public void addFunctionOfClassMethod(String name, String aClassName,
			String aFunctionName, Class[] aParameterClassTypes,
			String errorInfo) throws Exception {
		this.addFunction(name, new OperatorSelfDefineClassFunction(name,
				aClassName, aFunctionName, aParameterClassTypes,null,null, errorInfo));

	}
    
    /**
     * 添加一个类的函数定义,例如:Math.abs(double) 映射为表达式中的 "取绝对值(-5.0)"
     * @param name 函数名称
     * @param aClass 类
     * @param aFunctionName 类中的方法名称
     * @param aParameterClassTypes 方法的参数类型名称
     * @param errorInfo 如果函数执行的结果是false,需要输出的错误信息
     * @throws Exception
     */
    public void addFunctionOfClassMethod(String name, Class aClass,
                                         String aFunctionName, Class[] aParameterClassTypes,
                                         String errorInfo) throws Exception {
        this.addFunction(name, new OperatorSelfDefineClassFunction(name,
                aClass, aFunctionName, aParameterClassTypes,null,null, errorInfo));
        
    }
    
    /**
     * 添加一个类的函数定义,例如:Math.abs(double) 映射为表达式中的 "取绝对值(-5.0)"
     * @param name 函数名称
     * @param aClassName 类名称
     * @param aFunctionName 类中的方法名称
     * @param aParameterClassTypes 方法的参数类型名称
     * @param aParameterDesc 方法的参数说明
     * @param aParameterAnnotation 方法的参数注解
     * @param errorInfo 如果函数执行的结果是false,需要输出的错误信息
     * @throws Exception
     */
	public void addFunctionOfClassMethod(String name, String aClassName,
			String aFunctionName, Class[] aParameterClassTypes,
			String[] aParameterDesc,String[] aParameterAnnotation,
			String errorInfo) throws Exception {
		this.addFunction(name, new OperatorSelfDefineClassFunction(name,
				aClassName, aFunctionName, aParameterClassTypes,aParameterDesc,aParameterAnnotation, errorInfo));

	}
    /**
     * 添加一个类的函数定义,例如:Math.abs(double) 映射为表达式中的 "取绝对值(-5.0)"
     * @param name 函数名称
     * @param aClassName 类名称
     * @param aFunctionName 类中的方法名称
     * @param aParameterTypes 方法的参数类型名称
     * @param errorInfo 如果函数执行的结果是false,需要输出的错误信息
     * @throws Exception
     */
	public void addFunctionOfClassMethod(String name, String aClassName,
			String aFunctionName, String[] aParameterTypes, String errorInfo)
			throws Exception {
		this.addFunction(name, new OperatorSelfDefineClassFunction(name,
				aClassName, aFunctionName, aParameterTypes, null,null,errorInfo));
	}
    /**
     * 添加一个类的函数定义,例如:Math.abs(double) 映射为表达式中的 "取绝对值(-5.0)"
     * @param name 函数名称
     * @param aClassName 类名称
     * @param aFunctionName 类中的方法名称
     * @param aParameterTypes 方法的参数类型名称
     * @param aParameterDesc 方法的参数说明
     * @param aParameterAnnotation 方法的参数注解
     * @param errorInfo 如果函数执行的结果是false,需要输出的错误信息
     * @throws Exception
     */
	public void addFunctionOfClassMethod(String name, String aClassName,
			String aFunctionName, String[] aParameterTypes,
			String[] aParameterDesc,String[] aParameterAnnotation,
			String errorInfo)
			throws Exception {
		this.addFunction(name, new OperatorSelfDefineClassFunction(name,
				aClassName, aFunctionName, aParameterTypes, aParameterDesc,aParameterAnnotation,errorInfo));

	}
    /**
     * 用于将一个用户自己定义的对象(例如Spring对象)方法转换为一个表达式计算的函数
     * @param name
     * @param aServiceObject
     * @param aFunctionName
     * @param aParameterClassTypes
     * @param errorInfo
     * @throws Exception
     */
	public void addFunctionOfServiceMethod(String name, Object aServiceObject,
			String aFunctionName, Class[] aParameterClassTypes,
			String errorInfo) throws Exception {
		this.addFunction(name, new OperatorSelfDefineServiceFunction(name,
				aServiceObject, aFunctionName, aParameterClassTypes,null,null, errorInfo));

	}
    /**
     * 用于将一个用户自己定义的对象(例如Spring对象)方法转换为一个表达式计算的函数
     * @param name
     * @param aServiceObject
     * @param aFunctionName
     * @param aParameterClassTypes
     * @param aParameterDesc 方法的参数说明
     * @param aParameterAnnotation 方法的参数注解
     * @param errorInfo
     * @throws Exception
     */
	public void addFunctionOfServiceMethod(String name, Object aServiceObject,
			String aFunctionName, Class[] aParameterClassTypes,
			String[] aParameterDesc,String[] aParameterAnnotation,
			String errorInfo) throws Exception {
		this.addFunction(name, new OperatorSelfDefineServiceFunction(name,
				aServiceObject, aFunctionName, aParameterClassTypes,aParameterDesc,aParameterAnnotation, errorInfo));

	}
    /**
     * 用于将一个用户自己定义的对象(例如Spring对象)方法转换为一个表达式计算的函数
     * @param name
     * @param aServiceObject
     * @param aFunctionName
     * @param aParameterTypes
     * @param errorInfo
     * @throws Exception
     */
	public void addFunctionOfServiceMethod(String name, Object aServiceObject,
			String aFunctionName, String[] aParameterTypes, String errorInfo)
			throws Exception {
		this.addFunction(name, new OperatorSelfDefineServiceFunction(name,
				aServiceObject, aFunctionName, aParameterTypes,null,null, errorInfo));

	}
	public void addFunctionOfServiceMethod(String name, Object aServiceObject,
			String aFunctionName, String[] aParameterTypes,
			String[] aParameterDesc,String[] aParameterAnnotation,
			String errorInfo)
			throws Exception {
		this.addFunction(name, new OperatorSelfDefineServiceFunction(name,
				aServiceObject, aFunctionName, aParameterTypes,aParameterDesc,aParameterAnnotation, errorInfo));

	}
	/**
	 * 添加操作符号,此操作符号的优先级与 "*"相同,语法形式也是  data name data
	 * @param name
	 * @param op
	 * @throws Exception
	 */
	public void addOperator(String name,Operator op) throws Exception {
		 this.addOperator(name, "*", op);
	}
	/**
	 * 添加操作符号,此操作符号与给定的参照操作符号在优先级别和语法形式上一致
	 * @param name 操作符号名称
	 * @param aRefOpername 参照的操作符号,例如 "+","--"等
	 * @param op
	 * @throws Exception
	 */
	public void addOperator(String name,String aRefOpername,Operator op) throws Exception {
		this.manager.addOperatorWithLevelOfReference(name, aRefOpername);
		this.operatorManager.addOperator(name, op);
	}

	/**
	 * 添加操作符和关键字的别名,同时对操作符可以指定错误信息。
	 * 例如:addOperatorWithAlias("加","+",null)
	 * @param keyWordName
	 * @param realKeyWordName
	 * @param errorInfo
	 * @throws Exception
	 */
	public void addOperatorWithAlias(String keyWordName, String realKeyWordName,
			String errorInfo) throws Exception {
		if(errorInfo != null && errorInfo.trim().length() == 0){
			errorInfo = null;
		}
		//添加函数别名
		if(this.manager.isFunction(realKeyWordName)){
			this.manager.addFunctionName(keyWordName);
			this.operatorManager.addOperatorWithAlias(keyWordName, realKeyWordName, errorInfo);
			return;
		}
		NodeType realNodeType = this.manager.findNodeType(realKeyWordName);
		if(realNodeType == null){
			throw new QLException("关键字:" + realKeyWordName +"不存在");
		}
		boolean isExist = this.operatorManager.isExistOperator(realNodeType.getName());
		if(isExist == false &&  errorInfo != null){
			throw new QLException("关键字:" + realKeyWordName +"是通过指令来实现的,不能设置错误的提示信息,errorInfo 必须是 null");
		}
		if(isExist == false || errorInfo == null){
			//不需要新增操作符号,只需要建立一个关键子即可
			this.manager.addOperatorWithRealNodeType(keyWordName, realNodeType.getName());
		}else{
			this.manager.addOperatorWithLevelOfReference(keyWordName, realNodeType.getName());
			this.operatorManager.addOperatorWithAlias(keyWordName, realNodeType.getName(), errorInfo);
		}
	}
	/**
	 * 替换操作符处理
	 * @param name
	 */
    public OperatorBase replaceOperator(String name,OperatorBase op){
    	return this.operatorManager.replaceOperator(name, op);
    }

	public ExpressPackage getRootExpressPackage(){
		return this.rootExpressPackage;
	}
	  /**
	   * 清除缓存
	   */
	public void clearExpressCache() {
        synchronized (expressInstructionSetCache) {
            this.expressInstructionSetCache.clear();
        }
	}
	/**
	 * 根据表达式的名称进行执行
	 * @param name
	 * @param context
	 * @param errorList
	 * @param isTrace
	 * @param isCatchException
	 * @param aLog
	 * @return
	 * @throws Exception
	 */
	public Object executeByExpressName(String name,IExpressContext context, List errorList,
			boolean isTrace,boolean isCatchException, Log aLog) throws Exception {
		return  InstructionSetRunner.executeOuter(this,this.loader.getInstructionSet(name),this.loader,context, errorList,
			 	isTrace,isCatchException,aLog,false);

	}

	/**
	 * 执行指令集(兼容老接口,请不要自己管理指令缓存,直接使用execute(InstructionSet instructionSets,....... )
	 * 清理缓存可以使用clearExpressCache()函数
	 * @param instructionSets
	 * @param context
	 * @param errorList
	 * @param isTrace
	 * @param isCatchException
	 * @param aLog
	 * @return
	 * @throws Exception
	 */
	@Deprecated
	public Object execute(InstructionSet[] instructionSets,IExpressContext context, List errorList,
						  boolean isTrace,boolean isCatchException, Log aLog) throws Exception {
		return  InstructionSetRunner.executeOuter(this,instructionSets[0],this.loader,context, errorList,
				isTrace,isCatchException,aLog,false);
	}

	/**
	 * 执行指令集
	 * @param instructionSets
	 * @param context
	 * @param errorList
	 * @param isTrace
	 * @param isCatchException
	 * @param aLog
	 * @return
	 * @throws Exception
	 */
	public Object execute(InstructionSet instructionSets,IExpressContext context, List errorList,
			boolean isTrace,boolean isCatchException, Log aLog) throws Exception {
		return  InstructionSetRunner.executeOuter(this,instructionSets,this.loader,context, errorList,
				 	isTrace,isCatchException,aLog,false);
	}
	/**
	 * 执行一段文本
	 * @param expressString 程序文本
	 * @param context 执行上下文
	 * @param errorList 输出的错误信息List
	 * @param isCache 是否使用Cache中的指令集
	 * @param isTrace 是否输出详细的执行指令信息
	 * @param timeoutMillis 超时毫秒时间
	 * @return
	 * @throws Exception
	 */
	public Object execute(String expressString, IExpressContext context,
			List errorList, boolean isCache, boolean isTrace,long timeoutMillis) throws Exception {
		//设置超时毫秒时间
		QLExpressTimer.setTimer(timeoutMillis);
		try {
			return this.execute(expressString, context, errorList, isCache, isTrace, null);
		}finally {
			QLExpressTimer.reset();
		}
	}

	/**
	 * 执行一段文本
	 * @param expressString 程序文本
	 * @param context 执行上下文
	 * @param errorList 输出的错误信息List
	 * @param isCache 是否使用Cache中的指令集
	 * @param isTrace 是否输出详细的执行指令信息
	 * @return
	 * @throws Exception
	 */
	public Object execute(String expressString, IExpressContext context,
						  List errorList, boolean isCache, boolean isTrace) throws Exception {
		return this.execute(expressString, context, errorList, isCache, isTrace, null);
	}
	/**
	 * 执行一段文本
	 * @param expressString 程序文本
	 * @param context 执行上下文
	 * @param errorList 输出的错误信息List
	 * @param isCache 是否使用Cache中的指令集
	 * @param isTrace 是否输出详细的执行指令信息
	 * @param aLog 输出的log
	 * @return
	 * @throws Exception
	 */
	public Object execute(String expressString, IExpressContext context,
			List errorList, boolean isCache, boolean isTrace, Log aLog)
			throws Exception {
		InstructionSet parseResult = null;
		if (isCache == true) {
			parseResult = expressInstructionSetCache.get(expressString);
			if (parseResult == null) {
				synchronized (expressInstructionSetCache) {
					parseResult = expressInstructionSetCache.get(expressString);
					if (parseResult == null) {
						parseResult = this.parseInstructionSet(expressString);
						expressInstructionSetCache.put(expressString,
								parseResult);
					}
				}
			}
		} else {
			parseResult = this.parseInstructionSet(expressString);
		}
		return  InstructionSetRunner.executeOuter(this,parseResult,this.loader,context, errorList,
			 	isTrace,false,aLog,false);
	}

	public RuleResult executeRule(String expressString, IExpressContext context, boolean isCache, boolean isTrace)
			throws Exception {
		Rule rule = null;
		if (isCache == true) {
			rule = ruleCache.get(expressString);
			if (rule == null) {
				synchronized (ruleCache) {
					rule = ruleCache.get(expressString);
					if (rule == null) {
						rule = this.parseRule(expressString);
						ruleCache.put(expressString,
								rule);
					}
				}
			}
		} else {
			rule = this.parseRule(expressString);
		}
		return RuleManager.executeRule(this,rule,context,isCache,isTrace);
	}

	static Pattern patternRule = Pattern.compile("rule[\\s]+'([^']+)'[\\s]+name[\\s]+'([^']+)'[\\s]+");

	public Rule parseRule(String text)
			throws Exception {
		String ruleName = null;
		String ruleCode = null;
        Matcher matcher = patternRule.matcher(text);
        if(matcher.find()) {
            ruleCode = matcher.group(1);
            ruleName = matcher.group(2);
            text = text.substring(matcher.end());
        }

		Map selfDefineClass = new HashMap ();
		for(ExportItem  item : this.loader.getExportInfo()){
			if(item.getType().equals(InstructionSet.TYPE_CLASS)){
				selfDefineClass.put(item.getName(), item.getName());
			}
		}

//      分成两句话执行,用来保存中间的words结果
//		ExpressNode root = this.parse.parse(this.rootExpressPackage,text, isTrace,selfDefineClass);

		Word[] words = this.parse.splitWords(rootExpressPackage,text,isTrace,selfDefineClass);
		ExpressNode root =  this.parse.parse(rootExpressPackage,words,text,isTrace,selfDefineClass);
		Rule rule = RuleManager.createRule(root,words);
		rule.setCode(ruleCode);
		rule.setName(ruleName);
		return rule;
	}
    
    public Condition parseContition(String text)
            throws Exception {
        
        Map selfDefineClass = new HashMap ();
        for(ExportItem  item : this.loader.getExportInfo()){
            if(item.getType().equals(InstructionSet.TYPE_CLASS)){
                selfDefineClass.put(item.getName(), item.getName());
            }
        }
        
        Word[] words = this.parse.splitWords(rootExpressPackage,text,isTrace,selfDefineClass);
        ExpressNode root =  this.parse.parse(rootExpressPackage,words,text,isTrace,selfDefineClass);
        return RuleManager.createCondition(root,words);
    }

	/**
	 * 解析一段文本,生成指令集合
	 * @param text
	 * @return
	 * @throws Exception
	 */
	public InstructionSet parseInstructionSet(String text)
			throws Exception {
		try {
			Map selfDefineClass = new HashMap();
			for (ExportItem item : this.loader.getExportInfo()) {
				if (item.getType().equals(InstructionSet.TYPE_CLASS)) {
					selfDefineClass.put(item.getName(), item.getName());
				}
			}

			ExpressNode root = this.parse.parse(this.rootExpressPackage, text, isTrace, selfDefineClass);
			InstructionSet result = createInstructionSet(root, "main");
			if (this.isTrace && log.isDebugEnabled()) {
				log.debug(result);
			}
			return result;
		}catch (QLCompileException e){
			throw e;
		}catch (Exception e){
			throw new QLCompileException("编译异常:\n"+text,e);
		}
	}
	/**
	 * 输出全局定义信息
	 * @return
	 */
	public ExportItem[] getExportInfo(){
		return this.loader.getExportInfo();
	}

	/**
	 * 优先从本地指令集缓存获取指令集,没有的话生成并且缓存在本地
	 * @param expressString
	 * @return
	 * @throws Exception
	 */
	public InstructionSet getInstructionSetFromLocalCache(String expressString)
			throws Exception {
		InstructionSet parseResult = expressInstructionSetCache.get(expressString);
		if (parseResult == null) {
			synchronized (expressInstructionSetCache) {
				parseResult = expressInstructionSetCache.get(expressString);
				if (parseResult == null) {
					parseResult = this.parseInstructionSet(expressString);
					expressInstructionSetCache.put(expressString,
							parseResult);
				}
			}
		}
		return parseResult;
	}

	public InstructionSet createInstructionSet(ExpressNode root, String type)
			throws Exception {
		InstructionSet result = new InstructionSet(type);
		createInstructionSet(root, result);
		return result;
	}

	public void createInstructionSet(ExpressNode root, InstructionSet result)
			throws Exception {
		Stack forStack = new Stack();
		createInstructionSetPrivate(result, forStack, root, true);
		if (forStack.size() > 0) {
			throw new QLCompileException("For处理错误");
		}
	}

	public boolean createInstructionSetPrivate(InstructionSet result,
			Stack forStack, ExpressNode node,
			boolean isRoot) throws Exception {
		InstructionFactory factory = InstructionFactory
				.getInstructionFactory(node.getInstructionFactory());
		boolean hasLocalVar = factory.createInstruction(this,result, forStack, node, isRoot);
		return hasLocalVar;
	}
	/**
	 * 获取一个表达式需要的外部变量名称列表
	 * @param express
	 * @return
	 * @throws Exception
	 */
	public String[] getOutVarNames(String express) throws Exception{
		return this.parseInstructionSet(express).getOutAttrNames();
	}

	public String[] getOutFunctionNames(String express) throws Exception{
		return this.parseInstructionSet(express).getOutFunctionNames();
	}


	public boolean isShortCircuit() {
		return isShortCircuit;
	}
	public void setShortCircuit(boolean isShortCircuit) {
		this.isShortCircuit = isShortCircuit;
	}
    
    /**
     * 是否忽略charset类型的数据,而识别为string,比如'a' -》 "a"
     * 默认为不忽略,正常识别为String
     */
    public boolean isIgnoreConstChar() {
        return this.parse.isIgnoreConstChar();
    }
    public void setIgnoreConstChar(boolean ignoreConstChar) {
        this.parse.setIgnoreConstChar(ignoreConstChar);
    }
    
    /**
     * 提供简答的语法检查,保证可以在运行期本地环境编译成指令
     * @param text
     * @return
     */
    public boolean checkSyntax(String text)
    {
        return checkSyntax(text,false,null);
    }
    
    /**
     * 提供复杂的语法检查,(比如检查自定义的java类),不保证运行期在本地环境可以编译成指令
     * @param text
     * @param mockRemoteJavaClass
     * @param remoteJavaClassNames
     * @return
     */
    public boolean checkSyntax(String text,boolean mockRemoteJavaClass,List remoteJavaClassNames){

        try {
            Map selfDefineClass = new HashMap();
            for (ExportItem item : this.loader.getExportInfo()) {
                if (item.getType().equals(InstructionSet.TYPE_CLASS)) {
                    selfDefineClass.put(item.getName(), item.getName());
                }
            }
            Word[] words = this.parse.splitWords(rootExpressPackage,text,isTrace,selfDefineClass);
            ExpressNode root = this.parse.parse(this.rootExpressPackage, words,text, isTrace, selfDefineClass,mockRemoteJavaClass);
            InstructionSet result = createInstructionSet(root, "main");
            if (this.isTrace && log.isDebugEnabled()) {
                log.debug(result);
            }
            if(mockRemoteJavaClass && remoteJavaClassNames!=null) {
                remoteJavaClassNames.addAll(Arrays.asList(result.getVirClasses()));
            }
            return true;
        }catch (Exception e){
            log.error("checkSyntax has Exception",e);
            return false;
        }
    }
}

9.12、ExpressUtil(表达式工具类)

package com.ql.util.express;

import com.ql.util.express.config.QLExpressRunStrategy;
import com.ql.util.express.exception.QLException;
import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 表达式工具类
 * 
 * @author qhlhl2010@gmail.com
 * 
 */
@SuppressWarnings("unchecked")
public class ExpressUtil {
	public static final String DT_STRING = "String";
	public static final String DT_SHORT = "Short";
	public static final String DT_INTEGER = "Integer";
	public static final String DT_LONG = "Long";
	public static final String DT_DOUBLE = "Double";
	public static final String DT_FLOAT = "Float";
	public static final String DT_BYTE = "Byte";
	public static final String DT_CHAR = "Char";
	public static final String DT_BOOLEAN = "Boolean";
	public static final String DT_DATE = "Date";
	public static final String DT_TIME = "Time";
	public static final String DT_DATETIME = "DateTime";
	public static final String DT_OBJECT = "Object";

	public static final String DT_short = "short";
	public static final String DT_int = "int";
	public static final String DT_long = "long";
	public static final String DT_double = "double";
	public static final String DT_float = "float";
	public static final String DT_byte = "byte";
	public static final String DT_char = "char";
	public static final String DT_boolean = "boolean";

	public static Map methodCache = new ConcurrentHashMap();
	
	public static Class[][] classMatchs =new Class[][]{
			//原始数据类型
			{BigDecimal.class,double.class},{BigDecimal.class,float.class},{BigDecimal.class,long.class},{BigDecimal.class,int.class}, {BigDecimal.class,short.class},{BigDecimal.class,byte.class},
			{double.class,float.class},{double.class,long.class},{double.class,int.class}, {double.class,short.class},{double.class,byte.class},{double.class,BigDecimal.class},
			{float.class,long.class},  {float.class,int.class},  {float.class,short.class},{float.class,byte.class},{float.class,BigDecimal.class},
			{long.class,int.class},    {long.class,short.class}, {long.class,byte.class},
			{int.class,short.class},   {int.class,byte.class},
			{short.class,byte.class},			
			//---------
			{char.class,Character.class},{Character.class,char.class},
			{boolean.class,Boolean.class},{Boolean.class,boolean.class}
	};

	/**
	 * 获取简单的数据类型
	 * @param aClass
	 * @return
	 */
	public static Class getSimpleDataType(Class aClass) {
		if (aClass.isPrimitive()){
			if (Integer.class.equals(aClass))
				return Integer.TYPE;
			if (Short.class.equals(aClass))
				return Short.TYPE;
			if (Long.class.equals(aClass))
				return Long.TYPE;
			if (Double.class.equals(aClass))
				return Double.TYPE;
			if (Float.class.equals(aClass))
				return Float.TYPE;
			if (Byte.class.equals(aClass))
				return Byte.TYPE;
			if (Character.class.equals(aClass))
				return Character.TYPE;
			if (Boolean.class.equals(aClass))
				return Boolean.TYPE;
			return aClass;
		}else{
			return aClass;
		}
	}

	/**
	 * 是否可分配
	 * @param target
	 * @param source
	 * @return
	 */
    public static boolean isAssignable(Class target, Class source) {
    	if (target == source)
			return true;
    	if(target.isArray() &&  source.isArray()){
    		return isAssignable(target.getComponentType(),source.getComponentType());
    	}
    	return isAssignablePrivate(target,source);
    }

	/**
	 * 是否是私有权限
	 * @param target
	 * @param source
	 * @return
	 */
	public static boolean isAssignablePrivate(Class target, Class source) {
		if (target == source)
			return true;

		if (target == null)
			return false;
		if (source == null)//null转换
			return !target.isPrimitive();
		
		if (target.isAssignableFrom(source) == true){
			return true;
		}
		if(source.isPrimitive() && target == Object.class){
			return true;
		}
		
		if (target.isPrimitive() == false) {
			if (target == Byte.class)
				target = byte.class;
			else if (target == Short.class)
				target = short.class;
			else if (target == Integer.class)
				target = int.class;
			else if (target == Long.class)
				target = long.class;
			else if (target == Float.class)
				target = float.class;
			else if (target == Double.class)
				target = double.class;
		}
		if (source.isPrimitive() == false) {
			if (source == Byte.class)
				source = byte.class;
			else if (source == Short.class)
				source = short.class;
			else if (source == Integer.class)
				source = int.class;
			else if (source == Long.class)
				source = long.class;
			else if (source == Float.class)
				source = float.class;
			else if (source == Double.class)
				source = double.class;
		}
		if (target == source)// 转换后需要在判断一下
			return true;

		for (int i = 0; i < classMatchs.length; i++) {
			if (target == classMatchs[i][0] && source == classMatchs[i][1]) {
				return true;
			}
		}
		
		return false;
		
	}
	public static boolean isAssignableOld(Class lhsType, Class rhsType) {
		if (lhsType == null)
			return false;
		if (rhsType == null)
			return !lhsType.isPrimitive();

		if (lhsType.isPrimitive() && rhsType.isPrimitive()) {
			if (lhsType == rhsType)
				return true;

			if ((rhsType == Byte.TYPE)
					&& (lhsType == Short.TYPE || lhsType == Integer.TYPE
							|| lhsType == Long.TYPE || lhsType == Float.TYPE || lhsType == Double.TYPE))
				return true;

			if ((rhsType == Short.TYPE)
					&& (lhsType == Integer.TYPE || lhsType == Long.TYPE
							|| lhsType == Float.TYPE || lhsType == Double.TYPE))
				return true;

			if ((rhsType == Character.TYPE)
					&& (lhsType == Integer.TYPE || lhsType == Long.TYPE
							|| lhsType == Float.TYPE || lhsType == Double.TYPE))
				return true;

			if ((rhsType == Integer.TYPE)
					&& (lhsType == Long.TYPE || lhsType == Float.TYPE || lhsType == Double.TYPE))
				return true;

			if ((rhsType == Long.TYPE)
					&& (lhsType == Float.TYPE || lhsType == Double.TYPE))
				return true;

			if ((rhsType == Float.TYPE) && (lhsType == Double.TYPE))
				return true;
		} else if (lhsType.isAssignableFrom(rhsType))
			return true;

		return false;
	}

	public static boolean isSignatureAssignable(Class[] from, Class[] to) {
		for (int i = 0; i < from.length; i++)
			if (!isAssignable(to[i], from[i]))
				return false;
		return true;
	}

	public static int findMostSpecificSignature(Class[] idealMatch,
			Class[][] candidates) {
		Class[] bestMatch = null;
		int bestMatchIndex = -1;

		for (int i = candidates.length - 1; i >= 0; i--) {// 先从基类开始查找
			Class[] targetMatch = candidates[i];
			if (ExpressUtil.isSignatureAssignable(idealMatch, targetMatch)
					&& ((bestMatch == null) || ExpressUtil
							.isSignatureAssignable(targetMatch, bestMatch))) {
				bestMatch = targetMatch;
				bestMatchIndex = i;
			}
		}

		if (bestMatch != null)
			return bestMatchIndex;
		else
			return -1;
	}

	public static String createCacheKey(Class aBaseClass,
			String aMethodName, Class[] aTypes, boolean aPublicOnly,
			boolean aIsStatic) {
		StringBuilder builder = new StringBuilder();
//		builder.append(aPublicOnly).append("-").append(aIsStatic).append("-");
		builder.append(aBaseClass.getName()).append(".").append(aMethodName)
				.append(".");
		if (aTypes == null) {
			builder.append("null");
		} else {
			for (int i = 0; i < aTypes.length; i++) {
				if (i > 0) {
					builder.append(",");
				}
				if(aTypes[i]== null){
					builder.append("null");
				}else{
				   builder.append(aTypes[i].getName());
				}
			}
		}
//		builder.append(")");
		return builder.toString();

	}
    public static Method findMethodWithCache(Class baseClass, String methodName,
			Class[] types, boolean publicOnly, boolean isStatic){
    	String key = createCacheKey(baseClass, methodName, types, publicOnly, isStatic);
    	Object result = methodCache.get(key);
    	if(result == null){
    		result = findMethod(baseClass, methodName, types, publicOnly, isStatic);
    		if(result == null){
    			methodCache.put(key, void.class);    			
    		}else{
    			((Method)result).setAccessible(true);
    			methodCache.put(key,result); 
    		}
    	}else if(result == void.class){
    		result = null;
    	}
    	return (Method)result;
    }
    
	public static Method findMethod(Class baseClass, String methodName,
			Class[] types, boolean publicOnly, boolean isStatic) {
		List candidates = gatherMethodsRecursive(baseClass, methodName,
				types.length, publicOnly, isStatic, null /* candidates */);
		Method method = findMostSpecificMethod(types, (Method[]) candidates
				.toArray(new Method[0]));
		return method;
	}

	public static Constructor findConstructorWithCache(Class baseClass, Class[] types) {
	    	String key = createCacheKey(baseClass, "new", types, true, false);
	    	Constructor result = (Constructor)methodCache.get(key);
	    	if(result == null){
	    		result = findConstructor(baseClass,types);
	    		methodCache.put(key, result);
	    	}
	    	return result;
	}    	
	  
	private static Constructor findConstructor(Class baseClass, Class[] types) {
		Constructor[] constructors = baseClass.getConstructors();
		List> constructorList = new ArrayList>();
		List[]> listClass = new ArrayList[]>();
		for (int i = 0; i < constructors.length; i++) {
			if (constructors[i].getParameterTypes().length == types.length) {
				listClass.add(constructors[i].getParameterTypes());
				constructorList.add(constructors[i]);
			}
		}

		int match = findMostSpecificSignature(types, (Class[][]) listClass
				.toArray(new Class[0][]));
		return match == -1 ? null : constructorList.get(match);
	}

	public static Method findMostSpecificMethod(Class[] idealMatch,
			Method[] methods) {
		Class[][] candidateSigs = new Class[methods.length][];
		for (int i = 0; i < methods.length; i++)
			candidateSigs[i] = methods[i].getParameterTypes();

		int match = findMostSpecificSignature(idealMatch, candidateSigs);
		return match == -1 ? null : methods[match];

	}

	private static List gatherMethodsRecursive(Class baseClass,
			String methodName, int numArgs, boolean publicOnly,
			boolean isStatic, List candidates) {
		if (candidates == null)
			candidates = new ArrayList();

		addCandidates(baseClass.getDeclaredMethods(), methodName, numArgs,
				publicOnly, isStatic, candidates);

		Class[] intfs = baseClass.getInterfaces();
		for (int i = 0; i < intfs.length; i++)
			gatherMethodsRecursive(intfs[i], methodName, numArgs, publicOnly,
					isStatic, candidates);

		Class superclass = baseClass.getSuperclass();
		if (superclass != null)
			gatherMethodsRecursive(superclass, methodName, numArgs, publicOnly,
					isStatic, candidates);

		return candidates;
	}

	private static List addCandidates(Method[] methods, String methodName,
			int numArgs, boolean publicOnly, boolean isStatic, List candidates) {
		for (int i = 0; i < methods.length; i++) {
			Method m = methods[i];
			if (m.getName().equals(methodName)
					&& (m.getParameterTypes().length == numArgs)
					&& (publicOnly == false || isPublic(m)
							&& (isStatic == false || isStatic(m))))
				candidates.add(m);
		}
		return candidates;
	}

	public static boolean isPublic(Class c) {
		return Modifier.isPublic(c.getModifiers());
	}

	public static boolean isPublic(Method m) {
		return Modifier.isPublic(m.getModifiers());
	}

	public static boolean isStatic(Method m) {
		return Modifier.isStatic(m.getModifiers());
	}

	public static Class getJavaClass(String type) {
		int index = type.indexOf("[]");
		if (index < 0)
			return getJavaClassInner(type);

		StringBuilder arrayString = new StringBuilder();
		arrayString.append("[");
		String baseType = type.substring(0, index);
		while ((index = type.indexOf("[]", index + 2)) >= 0) {
			arrayString.append("[");
		}
		Class baseClass = getJavaClassInner(baseType);

		try {
			String baseName = "";
			if (baseClass.isPrimitive() == false) {
				return loadClass(arrayString.toString() + "L"
						+ baseClass.getName() + ";");
			} else {
				if (baseClass.equals(boolean.class)) {
					baseName = "Z";
				} else if (baseClass.equals(byte.class)) {
					baseName = "B";
				} else if (baseClass.equals(char.class)) {
					baseName = "C";
				} else if (baseClass.equals(double.class)) {
					baseName = "D";
				} else if (baseClass.equals(float.class)) {
					baseName = "F";
				} else if (baseClass.equals(int.class)) {
					baseName = "I";
				} else if (baseClass.equals(long.class)) {
					baseName = "J";
				} else if (baseClass.equals(short.class)) {
					baseName = "S";
				}
				return loadClass(arrayString.toString() + baseName);
			}
		} catch (ClassNotFoundException ex) {
			throw new RuntimeException(ex);
		}

	}

	public static Class getJavaClassInner(String type) {

		if (type.equals(DT_STRING))
			return String.class;
		if (type.equals(DT_SHORT))
			return Short.class;
		if (type.equals(DT_INTEGER))
			return Integer.class;
		if (type.equals(DT_LONG))
			return Long.class;
		if (type.equals(DT_DOUBLE))
			return Double.class;
		if (type.equals(DT_FLOAT))
			return Float.class;
		if (type.equals(DT_BYTE))
			return Byte.class;
		if (type.equals(DT_CHAR) || type.equals("Character"))
			return Character.class;
		if (type.equals(DT_BOOLEAN))
			return Boolean.class;
		if (type.equals(DT_DATE))
			return java.sql.Date.class;
		if (type.equals(DT_TIME))
			return java.sql.Time.class;
		if (type.equals(DT_DATETIME))
			return java.sql.Timestamp.class;
		if (type.equals(DT_OBJECT))
			return Object.class;
		if (type.equals(DT_short))
			return short.class;
		if (type.equals(DT_int))
			return int.class;
		if (type.equals(DT_long))
			return long.class;
		if (type.equals(DT_double))
			return double.class;
		if (type.equals(DT_float))
			return float.class;
		if (type.equals(DT_byte))
			return byte.class;
		if (type.equals(DT_char))
			return char.class;
		if (type.equals(DT_boolean))
			return boolean.class;
		try {
			return loadClass(type);
		} catch (ClassNotFoundException ex) {
			throw new RuntimeException(ex);
		}
	}

	public static String getClassName(Class className) {
		if(className == null){
			return null;
		}
		String name = className.getName();
		return getClassName(name);
	}

	private static String getClassName(String name) {
		String arrays = "";
		if (name.indexOf("[") >= 0) {
			int point = 0;
			while (name.charAt(point) == '[') {
				arrays = arrays + "[]";
				++point;
			}
			if (name.charAt(point) == 'L') {
				name = name.substring(point + 1, name.length() - 1);
			} else if (name.charAt(point) == 'Z') {
				name = "boolean";
			} else if (name.charAt(point) == 'B') {
				name = "byte";
			} else if (name.charAt(point) == 'C') {
				name = "char";
			} else if (name.charAt(point) == 'D') {
				name = "double";
			} else if (name.charAt(point) == 'F') {
				name = "float";
			} else if (name.charAt(point) == 'I') {
				name = "int";
			} else if (name.charAt(point) == 'J') {
				name = "long";
			} else if (name.charAt(point) == 'S') {
				name = "short";
			}
		}
		int index = name.lastIndexOf('.');
		if (index > 0 && name.substring(0, index).equals("java.lang") == true) {
			name = name.substring(index + 1);
		}
		name = name + arrays;
		return name;
	}
	public static Class loadClass(String name) throws ClassNotFoundException {
		return Class.forName(name);
	}

	/**
	 * 替换字符串中的参数 replaceString("$1强化$2实施$2",new String[]{"qq","ff"})
	 * ="qq 强化 ff 实施 ff"
	 * 
	 * @param str
	 * @param parameters
	 * @return
	 * @throws Exception
	 */
	public static String replaceString(String str, Object[] parameters)
			throws Exception {
		if (str == null || parameters == null || parameters.length == 0) {
			return str;
		}
		Pattern p = Pattern.compile("\\$\\d+");
		Matcher m = p.matcher(str);
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			int index = Integer.parseInt(m.group().substring(1)) - 1;
			if (index < 0 || index >= parameters.length) {
				throw new QLException("设置的参数位置$" + (index + 1) + "超过了范围 "
						+ parameters.length);
			}
			m.appendReplacement(sb, " " + parameters[index].toString() + " ");
		}
		m.appendTail(sb);
		return sb.toString();
	}

	public static Object getProperty(Object bean, Object name) {
		try {
		    if(bean==null && QLExpressRunStrategy.isAvoidNullPointer()){
		        return null;
            }
			if(bean.getClass().isArray() && name.equals("length")){
			   return Array.getLength(bean);
			}else if (bean instanceof Class) {
				if(name.equals("class")){
					return bean;
				}else{
					Field f = ((Class) bean).getDeclaredField(name.toString());
					return f.get(null);
				}
			}else if(bean instanceof Map ){
				return ((Map)bean).get(name);
		    }else {
				Object obj = PropertyUtils.getProperty(bean, name.toString());
				return obj;
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	public static Class getPropertyClass(Object bean, Object name) {
		try {
			if(bean.getClass().isArray() && name.equals("length")){
			   return int.class;
			}else if (bean instanceof Class) {
				if(name.equals("class")){
					return Class.class;
				}else{
					Field f = ((Class) bean).getDeclaredField(name.toString());
					return f.getType();
				}
			}else if(bean instanceof Map ){
				Object o = ((Map)bean).get(name);
				if(o == null){
					return null;
				}else{
					return o.getClass();
				}
		    }else {
				return PropertyUtils.getPropertyDescriptor(bean, name.toString()).getPropertyType();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	public static void setProperty(Object bean, Object name, Object value) {
		try {
			if (bean instanceof Class) {
				Field f = ((Class) bean).getDeclaredField(name.toString());
				f.set(null, value);
			}else if(bean instanceof Map ){
				((Map)bean).put(name, value);
		    } else {
		    	Class filedClass = PropertyUtils.getPropertyType(bean, name.toString());
				PropertyUtils.setProperty(bean, name.toString(),ExpressUtil.castObject(value, filedClass, false));
			}
		} catch (Exception e) {
			throw new RuntimeException("不能访问" + bean + "的property:" + name,e);
		}
	}

	  public static Object[] transferArray(Object[] values,Class[] types){
		  for(int i=0;i  type,boolean isForce){
		if (value == null)
			return null;
		if (value.getClass() == type || type.isAssignableFrom(value.getClass())) {
			return value;
		}
		if (value instanceof Number
				&& (type.isPrimitive() || Number.class.isAssignableFrom(type))) {
			return OperatorOfNumber.transfer((Number)value, type, isForce);
		}else if(type.isArray() && value.getClass().isArray()) {
			//需要对元素做兼容性,如果value的元素全部为null并且和声明的不一致,转化为所声明的类型
			Class valueType = value.getClass().getComponentType();
			Class declareType = type.getComponentType();
			if(declareType!=valueType){
				Object[] values = (Object[]) value;
				boolean allBlank = true;
				for(int i=0;i

9.13、IExpressContext(表达式计算的数据注入接口)

package com.ql.util.express;

/**
 * 表达式计算的数据注入接口
 * @author qhlhl2010@gmail.com
 *
 */
public interface IExpressContext {
    /**
     * 根据名称从属性列表中提取属性值。如果表达式中用到了Spring的对象,也是通过此方法获取
     * @param key 属性名称
     * @return
     */
    public V get(Object key);
    /**
     * 表达式计算的结果可以设置回调用系统,例如  userId = 3 + 4
     * @param name 属性名称
     * @param object 属性值
     */
    public V put(K name, V object);
}

9.14、IExpressResourceLoader(加载表达式资源接口)

package com.ql.util.express;

/**
 * 加载表达式资源接口
 * @author xuannan
 *
 */
public interface IExpressResourceLoader {
	/**
	 * 根据表达式名称获取表达式的内容
	 * @param expressName
	 * @return
	 * @throws Exception
	 */
	public String loadExpress(String expressName) throws Exception;
}

9.15、InstructionSet(表达式执行编译后形成的指令集合)

package com.ql.util.express;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;

import com.ql.util.express.config.QLExpressTimer;
import com.ql.util.express.exception.QLException;
import com.ql.util.express.instruction.detail.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ql.util.express.instruction.FunctionInstructionSet;
import com.ql.util.express.instruction.OperateDataCacheManager;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;



/**
 * 表达式执行编译后形成的指令集合
 * @author qhlhl2010@gmail.com
 *
 */

public class InstructionSet implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1841743860792681669L;
	
	private static final transient  Log log = LogFactory.getLog(InstructionSet.class);
	public static AtomicInteger uniqIndex = new AtomicInteger(1);
	public static String TYPE_MAIN ="main";
	public static String TYPE_CLASS ="VClass";
	public static String TYPE_FUNCTION ="function";
	public static String TYPE_MARCO ="marco";
	
	public static boolean printInstructionError = false;
	
	
	private String type ="main";
	private String name;
	private String globeName;
	
  /**
   * 指令
   */
  private Instruction[] instructionList = new Instruction[0];
  /**
   * 函数和宏定义
   */
  private Map functionDefine = new HashMap();
  //为了增加性能,开始的时候缓存为数组
  private Map cacheFunctionSet = null;
  private List exportVar = new ArrayList();
  /**
   * 函数参数定义
   */
  private List parameterList = new ArrayList();
  
  public static int getUniqClassIndex(){
	  return uniqIndex.getAndIncrement();
  }
  public InstructionSet(String aType){
	  this.type = aType;
  }

  public String[] getOutFunctionNames() throws Exception {
	  Map result = new TreeMap();
	  for (int i = 0; i < instructionList.length; i++) {
		  Instruction instruction = instructionList[i];
		  if (instruction instanceof InstructionCallSelfDefineFunction) {
			  String functionName = ((InstructionCallSelfDefineFunction)instruction).getFunctionName();
			  if(!functionDefine.containsKey(functionName)) {
				  result.put(functionName, null);
			  }
		  }
	  }
	  return result.keySet().toArray(new String[0]);

  }
    
    public String[] getVirClasses() throws Exception {
        Map result = new TreeMap();
        for (int i = 0; i < instructionList.length; i++) {
            Instruction instruction = instructionList[i];
            if (instruction instanceof InstructionNewVirClass) {
                String functionName = ((InstructionNewVirClass)instruction).getClassName();
                result.put(functionName, null);
            }
        }
        return result.keySet().toArray(new String[0]);
        
    }
  public String[] getOutAttrNames() throws Exception{
	  Map result = new TreeMap();
	  for(Instruction instruction:instructionList){
		   if(instruction instanceof InstructionLoadAttr){
			   if("null".equals(((InstructionLoadAttr)instruction).getAttrName())){
				   continue;
			   }
			   result.put(((InstructionLoadAttr)instruction).getAttrName(),null);
		   }
	  }
	 
	  //剔除本地变量定义和别名定义
		for (int i = 0; i < instructionList.length; i++) {
			Instruction instruction = instructionList[i];
			if (instruction instanceof InstructionOperator) {
				String opName = ((InstructionOperator) instruction)
						.getOperator().getName();
				if(opName != null){//addOperator(op)中op.name有可能为空
                    if (opName.equalsIgnoreCase("def")
                            || opName.equalsIgnoreCase("exportDef")) {
                        String varLocalName = (String) ((InstructionConstData) instructionList[i - 1])
                                .getOperateData().getObject(null);
                        result.remove(varLocalName);
                    } else if (opName.equalsIgnoreCase("alias")
                            || opName.equalsIgnoreCase("exportAlias")) {
                        String varLocalName = (String) ((InstructionConstData) instructionList[i - 2])
                                .getOperateData().getObject(null);
                        result.remove(varLocalName);
                    }
                }
			}
		}
	  return result.keySet().toArray(new String[0]);
  }

  
  /**
   * 添加指令,为了提高运行期的效率,指令集用数组存储
   * @param item
   * @return
   */
  private void addArrayItem(Instruction item){
	  Instruction[] newArray = new Instruction[this.instructionList.length + 1];
	  System.arraycopy(this.instructionList, 0, newArray, 0, this.instructionList.length);
	  newArray[this.instructionList.length] = item;
	  this.instructionList = newArray;
  }
  /**
   * 插入数据
   * @param aPoint
   * @param item
   */
  private void insertArrayItem(int aPoint,Instruction item){
	  Instruction[] newArray = new Instruction[this.instructionList.length + 1];
	  System.arraycopy(this.instructionList, 0, newArray, 0, aPoint);
	  System.arraycopy(this.instructionList, aPoint, newArray, aPoint + 1,this.instructionList.length - aPoint);
	  newArray[aPoint] = item;
	  this.instructionList = newArray;
  }

/**
 * 
 * @param environmen
 * @param context
 * @param errorList
 * @param isReturnLastData 是否最后的结果,主要是在执行宏定义的时候需要
 * @param aLog
 * @return
 * @throws Exception
 */
	public CallResult excute(RunEnvironment environmen,InstructionSetContext context,
			List errorList,boolean isReturnLastData,Log aLog)
			throws Exception {
		
		//将函数export到上下文中,这儿就是重入也没有关系,不需要考虑并发
		if(cacheFunctionSet == null){
			Map tempMap = new HashMap();
			for(FunctionInstructionSet s : this.functionDefine.values()){
				tempMap.put(s.name,s.instructionSet);
			}
			cacheFunctionSet = tempMap;
		}
		
		context.addSymbol(cacheFunctionSet);
		
		this.executeInnerOrigiInstruction(environmen, errorList, aLog);
		if (environmen.isExit() == false) {// 是在执行完所有的指令后结束的代码
			if (environmen.getDataStackSize() > 0) {
				OperateData tmpObject = environmen.pop();
				if (tmpObject == null) {
					environmen.quitExpress(null);
				} else {
					if(isReturnLastData == true){
						if(tmpObject.getType(context) != null && tmpObject.getType(context).equals(void.class)){
							environmen.quitExpress(null);
						}else{
						    environmen.quitExpress(tmpObject.getObject(context));
						}
					}else{
					    environmen.quitExpress(tmpObject);
					}
				}
			}
		}
		if (environmen.getDataStackSize() > 1) {
			throw new QLException("在表达式执行完毕后,堆栈中还存在多个数据");
		}
		CallResult result = OperateDataCacheManager.fetchCallResult(environmen.getReturnValue(), environmen.isExit());
		return result;
	}
	  public void executeInnerOrigiInstruction(RunEnvironment environmen,List errorList,Log aLog) throws Exception{
			Instruction instruction =null;
		try {
			while (environmen.programPoint < this.instructionList.length) {
				QLExpressTimer.assertTimeOut();
				instruction = this.instructionList[environmen.programPoint];
				instruction.setLog(aLog);// 设置log
				instruction.execute(environmen, errorList);
			}
		} catch (Exception e) {
			if (printInstructionError) {
				log.error("当前ProgramPoint = " + environmen.programPoint);
				log.error("当前指令" + instruction);
				log.error(e);
			}
			throw e;
		}
	}
  public int getInstructionLength(){
	  return this.instructionList.length;
  }
  public void addMacroDefine(String macroName,FunctionInstructionSet iset){
	  this.functionDefine.put(macroName, iset);
  }
  public FunctionInstructionSet getMacroDefine(String macroName){
	  return this.functionDefine.get(macroName);
  }
  public FunctionInstructionSet[] getFunctionInstructionSets(){
	  return this.functionDefine.values().toArray(new FunctionInstructionSet[0]);
  }
  public void addExportDef(ExportItem e){
	  this.exportVar.add(e);
  }
  public List getExportDef(){
	  List result = new ArrayList ();
	  result.addAll(this.exportVar);
	  return result;
  }

	
	public OperateDataLocalVar[] getParameters() {
		return this.parameterList.toArray(new OperateDataLocalVar[0]);
	}

	public void addParameter(OperateDataLocalVar localVar) {
		this.parameterList.add(localVar);
	}	
  public void addInstruction(Instruction instruction){
	  this.addArrayItem(instruction);
  }
  public void insertInstruction(int point,Instruction instruction){
	  this.insertArrayItem(point, instruction);
  } 
  public Instruction getInstruction(int point){
	  return this.instructionList[point];
  }
  public int getCurrentPoint(){
	  return this.instructionList.length - 1; 
  }
  
  public String getName() {
	return name;
}

public void setName(String name) {
	this.name = name;
}

public String getGlobeName() {
	return globeName;
}

public void setGlobeName(String globeName) {
	this.globeName = globeName;
}
public boolean hasMain(){
	return this.instructionList.length >0;
}
public String getType() {
	return type;
}
public void appendSpace(StringBuffer buffer,int level){
	for(int i=0;i 0){
				    	buffer.append(",");
				    }
					buffer.append(var.getType(null).getName()).append(" ").append(var.getName());
				}
				buffer.append("){\n");
				buffer.append(set.instructionSet.toString(level + 1));
				appendSpace(buffer,level);
				buffer.append("}\n");
			}
			for (int i = 0; i < this.instructionList.length; i++) {
				appendSpace(buffer,level);
				buffer.append(i + 1).append(":").append(this.instructionList[i])
						.append("\n");
			}
			return buffer.toString();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

	

9.16、InstructionSetContext(指令集上下文)

package com.ql.util.express;

import java.util.HashMap;
import java.util.Map;

import com.ql.util.express.exception.QLException;
import com.ql.util.express.instruction.OperateDataCacheManager;

/**
 * 指令集上下文
 */
public class InstructionSetContext  implements IExpressContext {
	/*
	 * 没有知道数据类型的变量定义是否传递到最外层的Context
	 */
	private boolean isExpandToParent = true;
	/**
	 * 表达式上下文
	 */
	private IExpressContext parent = null;
	/**
	 * 内容
	 */
	private Map content;
	/**
	 * 符号表
	 */
	private Map symbolTable =new HashMap();
	/**
	 * 表达式装载器
	 */
	private ExpressLoader expressLoader;
	/**
	 * 是否支持动态属性名字
	 */
	private boolean isSupportDynamicFieldName = false;

	/**
	 * 获取运行器
	 * @return
	 */
	public ExpressRunner getRunner() {
		return runner;
	}

	/**
	 * 表达式运行器
	 */
	private ExpressRunner runner;

	/**
	 * 构造函数指令集上下文
	 * @param aIsExpandToParent
	 * @param aRunner
	 * @param aParent
	 * @param aExpressLoader
	 * @param aIsSupportDynamicFieldName
	 */
	public InstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
	   this.initial(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
	}

	/**
	 * 初始化
	 * @param aIsExpandToParent
	 * @param aRunner
	 * @param aParent
	 * @param aExpressLoader
	 * @param aIsSupportDynamicFieldName
	 */
	public void initial(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
	    this.isExpandToParent = aIsExpandToParent;
		this.runner = aRunner;
		this.parent = aParent;
		this.expressLoader = aExpressLoader;
		this.isSupportDynamicFieldName = aIsSupportDynamicFieldName;		
	}

	/**
	 * 清除
	 */
    public void clear(){
    	isExpandToParent = true;    	
    	parent = null;
    	content = null;
    	expressLoader = null;    	
    	isSupportDynamicFieldName = false;
    	runner = null;   
    	symbolTable.clear();
    	
    }

	/**
	 * 导出符号
	 * @param varName
	 * @param aliasNameObject
	 * @throws Exception
	 */
	public void exportSymbol(String varName,Object aliasNameObject) throws Exception{
		if( this.parent != null && this.parent instanceof InstructionSetContext){
			((InstructionSetContext)this.parent).exportSymbol(varName, aliasNameObject);
		}else{
		    this.addSymbol(varName, aliasNameObject);
		}
	}

	/**
	 * 添加符号
	 * @param varName
	 * @param aliasNameObject
	 * @throws Exception
	 */
	public void addSymbol(String varName,Object aliasNameObject) throws Exception{
		if(this.symbolTable.containsKey(varName)){
			throw new QLException("变量" + varName + "已经存在,不能重复定义,也不能再从函数内部 exprot ");
		}
		this.symbolTable.put(varName,aliasNameObject);
	}

	/**
	 * 添加符号
	 * @param aliasNameObjects
	 * @throws Exception
	 */
	public void addSymbol(Map aliasNameObjects) throws Exception{
		this.symbolTable.putAll(aliasNameObjects);
	}
	
	public void setSupportDynamicFieldName(boolean isSupportDynamicFieldName) {
		this.isSupportDynamicFieldName = isSupportDynamicFieldName;
	}

	/**
	 * 是支持动态属性名字
	 * @return
	 */
	public boolean isSupportDynamicFieldName(){
		 return this.isSupportDynamicFieldName;
	}

	/**
	 * 获取表达式运行器
	 * @return
	 */
	public ExpressRunner getExpressRunner(){
		return this.runner;
	}

	/**
	 * 查找别名或者定义的符号
	 * @param varName
	 * @return
	 * @throws Exception
	 */
	public Object findAliasOrDefSymbol(String varName)throws Exception{
		Object result =  this.symbolTable.get(varName);
		if(result == null){
			if( this.parent != null && this.parent instanceof InstructionSetContext){
			    result = ((InstructionSetContext)this.parent).findAliasOrDefSymbol(varName);
			}else{
			    result = null;
			}
		}	
		return result;		
	}

	/**
	 * 获取符号
	 * @param varName
	 * @return
	 * @throws Exception
	 */
	public Object getSymbol(String varName) throws Exception{
		Object result = this.symbolTable.get(varName);
		if( result == null && this.expressLoader != null){
			result = this.expressLoader.getInstructionSet(varName);
		}
		if(result == null){
			if (this.isExpandToParent == true && this.parent != null
					&& this.parent instanceof InstructionSetContext) {
				result = ((InstructionSetContext) this.parent)
						.getSymbol(varName);
			} else {
				result = OperateDataCacheManager.fetchOperateDataAttr(varName, null);
				this.addSymbol(varName, result);
			}
		}	
		return result;
	}

	/**
	 * 获取表达式装载器
	 * @return
	 */
	public ExpressLoader getExpressLoader() {
		return expressLoader;
	}

	/**
	 * 获取表达式上下文
	 * @return
	 */
	public IExpressContext getParent(){
		return  this.parent;
	}

	/**
	 * 获取对象
	 * @param key 属性名称
	 * @return
	 */
	@Override
	public Object get(Object key){
		if(this.content != null && this.content.containsKey(key)){
			return this.content.get(key);
		}else if(this.isExpandToParent == true && this.parent != null){
			return this.parent.get(key);
		}
		return null;
	}

	/**
	 * 存放对象
	 * @param key
	 * @param value
	 * @return
	 */
	@Override
	public Object put(String key, Object value){
		if(this.content != null && this.content.containsKey(key) ){
			return this.content.put(key,value);
		}else if (this.isExpandToParent == false){
			if(this.content == null){
				this.content = new HashMap();
			}
			return this.content.put(key,value);
		}else if(this.parent != null){
			return this.parent.put(key,value);
		}else{
			throw new RuntimeException("没有定义局部变量:" + key +",而且没有全局上下文");
		}
	}

}

9.17、InstructionSetRunner(指令集运行器)

package com.ql.util.express;

import java.util.List;

import com.ql.util.express.config.QLExpressTimer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ql.util.express.instruction.OperateDataCacheManager;

/**
 * 指令集运行器
 */
public class InstructionSetRunner {
	private static final Log log = LogFactory.getLog(InstructionSetRunner.class);
	  public static Object executeOuter(ExpressRunner runner,InstructionSet sets,ExpressLoader loader,
				IExpressContext aContext, List errorList,
				boolean isTrace,boolean isCatchException,
				Log aLog,boolean isSupportDynamicFieldName) throws Exception{
		 try{

		 	//开始计时
			 QLExpressTimer.startTimer();

			 OperateDataCacheManager.push(runner);
			 return execute(runner,sets, loader, aContext, errorList, isTrace, isCatchException,true, aLog,isSupportDynamicFieldName);
		 }finally{
			 OperateDataCacheManager.resetCache(runner);
		 }
	  }

    /**
	 * 批量执行指令集合,指令集间可以共享 变量和函数
	 * @param runner
	 * @param sets
	 * @param loader
	 * @param aContext
	 * @param errorList
	 * @param isTrace
	 * @param isCatchException
	 * @param isReturnLastData
	 * @param aLog
	 * @param isSupportDynamicFieldName
     * @return
     * @throws Exception
     */
	  public static Object execute(ExpressRunner runner,InstructionSet sets,ExpressLoader loader,
				IExpressContext aContext, List errorList,
				boolean isTrace,boolean isCatchException,
				boolean isReturnLastData,Log aLog,boolean isSupportDynamicFieldName)
				throws Exception {
		  InstructionSetContext  context = OperateDataCacheManager.fetchInstructionSetContext (
					true,runner,aContext,loader,isSupportDynamicFieldName);
		  Object result = execute(sets,context,errorList,isTrace,isCatchException,isReturnLastData,aLog);
	      return result;
	  }

		public static Object execute(InstructionSet set,
				InstructionSetContext context, List errorList, boolean isTrace,boolean isCatchException,
				boolean isReturnLastData,Log aLog) throws Exception {
		
		RunEnvironment environmen = null;
		Object result = null;
		environmen = OperateDataCacheManager.fetRunEnvironment(set,
				(InstructionSetContext) context, isTrace);
		try {
			CallResult tempResult = set.excute(environmen, context, errorList,
					isReturnLastData, aLog);
			if (tempResult.isExit() == true) {
				result = tempResult.getReturnValue();
			}
		} catch (Exception e) {
			if (isCatchException == true) {
				if (aLog != null) {
					aLog.error(e.getMessage(), e);
				} else {
					log.error(e.getMessage(), e);
				}
			} else {
				throw e;
			}
		}
		return result;

		}
}

9.18、LocalExpressCacheRunner(作为表达式)

package com.ql.util.express;

import java.util.HashMap;
import java.util.Map;

/**
 * 作为表达式
 * @author tianqiao
 *
 */
public class LocalExpressCacheRunner extends ExpressRemoteCacheRunner{
	/**
	 * 表达式集合map
	 */
	private static Map expressMap = new HashMap ();
	/**
	 * 表达式运行器
	 */
	private ExpressRunner expressRunner;

	/**
	 * 本地表达式缓存运行器
	 * @param expressRunner
	 */
	public LocalExpressCacheRunner(ExpressRunner expressRunner){
		this.expressRunner = expressRunner;		
	}
	@Override
	public final Object getCache(String key) {
		return expressMap.get(key);
	}

	@Override
	public final void putCache(String key, Object object) {
		expressMap.put(key, object);		
	}

	@Override
	public final ExpressRunner getExpressRunner() {
		return this.expressRunner;
	}

}

9.19、OperateData(数据类型定义)

package com.ql.util.express;


import com.ql.util.express.exception.QLException;

/**
 * 数据类型定义
 * @author qhlhl2010@gmail.com
 *
 */

public class OperateData implements java.io.Serializable {
	private static final long serialVersionUID = 4749348640699065036L;	
	protected Object dataObject;
	protected Class type;

	public OperateData(Object obj, Class aType) {
		this.type = aType;
		this.dataObject = obj;
	}
	/**
	 * 给对象缓存接口使用
	 * @param obj
	 * @param aType
	 */
	public void initial(Object obj, Class aType) {
		this.type = aType;
		this.dataObject = obj;
	}
	public void clear(){
		this.dataObject = null;
		this.type = null;
	}
    public Class getDefineType(){
    	throw new RuntimeException(this.getClass().getName() + "必须实现方法:getDefineType");
    }
    public Class getOrgiType(){
    	return this.type;
    }
	public Class getType(InstructionSetContext parent) throws Exception {
		if (type != null)
			return type;

		Object obj = this.getObject(parent);
		if (obj == null)
			return null;
		else
			return obj.getClass();
	}

	public final Object getObject(InstructionSetContext context) throws Exception {
    	if(this.type != null && this.type.equals(void.class)){
    		throw new QLException("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句");
    	}
		return getObjectInner(context);
	}
    public Object getObjectInner(InstructionSetContext context) throws Exception{
    	return this.dataObject;
    }
    public void setObject(InstructionSetContext parent, Object object) throws Exception {
		throw new RuntimeException("必须在子类中实现此方法");
	}
	public String toJavaCode(){		
		if(this.getClass().equals(OperateData.class) == false){
			throw new RuntimeException(this.getClass().getName() + "没有实现:toJavaCode()");
		}
		String result ="new " + OperateData.class.getName() +"(";
		if(String.class.equals(this.type)){
			result = result + "\"" + this.dataObject + "\"";
		}else if(this.type.isPrimitive()){
			result = result + this.dataObject.getClass().getName() +".valueOf(\"" + this.dataObject + "\")";
		}else{
			result = result + "new " + this.dataObject.getClass().getName() + "(\"" + this.dataObject.toString() + "\")";
		}
		result = result + "," + type.getName() + ".class";
		result = result + ")";
		return result;
	}
	public String toString() {
		if( this.dataObject == null)
			return this.type + ":null";
		else{
			if(this.dataObject instanceof Class){
				return ExpressUtil.getClassName((Class)this.dataObject);
			}else{
			    return this.dataObject.toString();
			}
		}
	}
	public void toResource(StringBuilder builder,int level){
		if(this.dataObject != null){
			builder.append(this.dataObject.toString());
		}else{
			builder.append("null");
		}
	}
}

9.20、Operator(操作符的基类)

package com.ql.util.express;

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.op.OperatorBase;

import java.util.Date;

/**
 * 操作符的基类
 *
 * @author xuannan
 */
public abstract class Operator extends OperatorBase {
    
    public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception {
        Object[] parameters = new Object[list.length];
        for (int i = 0; i < list.length; i++) {
            if(list.get(i)==null && QLExpressRunStrategy.isAvoidNullPointer()){
                parameters[i] = null;
            }else {
                parameters[i] = list.get(i).getObject(context);
            }
        }
        Object result = this.executeInner(parameters);
        if (result != null && result.getClass().equals(OperateData.class)) {
            throw new QLException("操作符号定义的返回类型错误:" + this.getAliasName());
        }
        if (result == null) {
            //return new OperateData(null,null);
            return OperateDataCacheManager.fetchOperateData(null, null);
        } else {
            //return new OperateData(result,ExpressUtil.getSimpleDataType(result.getClass()));
            return OperateDataCacheManager.fetchOperateData(result, ExpressUtil.getSimpleDataType(result.getClass()));
        }
    }
    
    public abstract Object executeInner(Object[] list) throws Exception;
    
    /**
     * 进行对象是否相等的比较
     * @param op1
     * @param op2
     * @return
     * @throws Exception
     */
    public static boolean objectEquals(Object op1, Object op2) throws Exception{
        if (op1 == null && op2 == null) {
            return true;
        }
        if (op1 == null || op2 == null) {
            return false;
        }
        
        //Character的值比较
        if(op1 instanceof Character || op2 instanceof Character){
            int compareResult = 0;
            if (op1 instanceof Character && op2 instanceof Character) {
                return ((Character) op1).equals((Character) op2);
            }else if (op1 instanceof Number) {
                compareResult = OperatorOfNumber.compareNumber((Number) op1, (int) ((Character) op2).charValue());
                return compareResult==0;
            } else if (op2 instanceof Number) {
                compareResult = OperatorOfNumber.compareNumber((int) ((Character) op1).charValue(), (Number) op2);
                return compareResult==0;
            }
        }
        //数值的值比较
        if (op1 instanceof Number && op2 instanceof Number) {
            //数字比较
            int compareResult = OperatorOfNumber.compareNumber((Number) op1, (Number) op2);
            return compareResult==0;
        }
        //调用原始Object的比较
        return op1.equals(op2);
    }
    /**
     * 进行对象比较
     *
     * @param op1
     * @param op2
     * @return 0 等于 ,负数 小于 , 正数 大于
     * @throws Exception
     */
    public static int compareData(Object op1, Object op2) throws Exception {
        
        if(op1 == op2){
            return 0;
        }
        
        int compareResult = -1;
        
        if (op1 instanceof String) {
            compareResult = ((String) op1).compareTo(op2.toString());
        } else if (op2 instanceof String) {
            compareResult = op1.toString().compareTo((String) op2);
        } else if (op1 instanceof Character || op2 instanceof Character) {
            if (op1 instanceof Character && op2 instanceof Character) {
                compareResult = ((Character) op1).compareTo((Character) op2);
            } else if (op1 instanceof Number) {
                compareResult = OperatorOfNumber.compareNumber((Number) op1, (int) ((Character) op2).charValue());
            } else if (op2 instanceof Number) {
                compareResult = OperatorOfNumber.compareNumber((int) ((Character) op1).charValue(), (Number) op2);
            } else {
                throw new QLException(op1 + "和" + op2 + "不能执行compare 操作");
            }
        } else if (op1 instanceof Number && op2 instanceof Number) {
            //数字比较
            compareResult = OperatorOfNumber.compareNumber((Number) op1, (Number) op2);
        } else if ((op1 instanceof Boolean) && (op2 instanceof Boolean)) {
            if (((Boolean) op1).booleanValue() == ((Boolean) op2).booleanValue())
                compareResult = 0;
            else
                compareResult = -1;
        } else if ((op1 instanceof Date) && (op2 instanceof Date)) {
            compareResult = ((Date) op1).compareTo((Date) op2);
        } else
            throw new QLException(op1 + "和" + op2 + "不能执行compare 操作");
        return compareResult;
    }
    
}

9.21、OperatorOfNumber(数值的操作)

package com.ql.util.express;

import com.ql.util.express.exception.QLException;

import java.math.BigDecimal;

/**
 * 数字运行函数集合
 * @author qhlhl2010@gmail.com
 *
 */

interface NumberType{
	public int NUMBER_TYPE_BYTE = 1;
	public int NUMBER_TYPE_SHORT = 2;
	public int NUMBER_TYPE_INT = 3;
	public int NUMBER_TYPE_LONG = 4;
	public int NUMBER_TYPE_FLOAT = 5;
	public int NUMBER_TYPE_DOUBLE = 6;
	public int NUMBER_TYPE_BIGDECIMAL = 7;
}

/**
 * 数值的操作
 * @author xiaochengxinyizhan
 */
public class OperatorOfNumber {
	public static double round(double v, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException(
					"The scale must be a positive integer or zero");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 获取数据类型精度顺序
	 * @param aClass
	 * @return
	 */
    public static int getSeq(Class aClass){
    	if(aClass == Byte.class || aClass == byte.class) return NumberType.NUMBER_TYPE_BYTE;
    	if(aClass == Short.class || aClass == short.class) return NumberType.NUMBER_TYPE_SHORT;
    	if(aClass == Integer.class || aClass == int.class) return NumberType.NUMBER_TYPE_INT;
    	if(aClass == Long.class || aClass == long.class) return NumberType.NUMBER_TYPE_LONG;
    	if(aClass == Float.class || aClass == float.class) return NumberType.NUMBER_TYPE_FLOAT;
    	if(aClass == Double.class || aClass == double.class) return NumberType.NUMBER_TYPE_DOUBLE;
    	if(aClass == BigDecimal.class) return NumberType.NUMBER_TYPE_BIGDECIMAL;
    	throw new RuntimeException("不能处理的数据类型:" + aClass.getName());
    }
	/**
	 * 进行数据类型转换
	 * @param value
	 * @param type
	 * @return
	 */
	public static Number transfer(Number value,Class type,boolean isForce){
		if (isForce == true || value instanceof BigDecimal == false) {
			if (type.equals(byte.class) || type.equals(Byte.class)) {
				return ((Number) value).byteValue();
			} else if (type.equals(short.class) || type.equals(Short.class)) {
				return ((Number) value).shortValue();
			} else if (type.equals(int.class) || type.equals(Integer.class)) {
				return ((Number) value).intValue();
			} else if (type.equals(long.class) || type.equals(Long.class)) {
				return ((Number) value).longValue();
			} else if (type.equals(float.class) || type.equals(Float.class)) {
				return ((Number) value).floatValue();
			} else if (type.equals(double.class)
					|| type.equals(Double.class)) {
				return ((Number) value).doubleValue();
			} else if (type.equals(BigDecimal.class)) {
				return new BigDecimal(value.toString());
			}else{
				throw new RuntimeException("没有处理的数据类型:" + type.getName());
			}
		} else {
			if (type.equals(byte.class) || type.equals(Byte.class)) {
				if(((BigDecimal)value).scale() >0 ){
					throw new RuntimeException("有小数位,不能转化为:"+ type.getName());
				}
				return ((Number) value).byteValue();
			} else if (type.equals(short.class) || type.equals(Short.class)) {
				if(((BigDecimal)value).scale() >0 ){
					throw new RuntimeException("有小数位,不能转化为:"+ type.getName());
				}
				return ((Number) value).shortValue();
			} else if (type.equals(int.class) || type.equals(Integer.class)) {
				if(((BigDecimal)value).scale() >0 ){
					throw new RuntimeException("有小数位,不能转化为:"+ type.getName());
				}
				return ((Number) value).intValue();
			} else if (type.equals(long.class) || type.equals(Long.class)) {
				if(((BigDecimal)value).scale() >0 ){
					throw new RuntimeException("有小数位,不能转化为:"+ type.getName());
				}
				return ((Number) value).longValue();
			} else if (type.equals(float.class) || type.equals(Float.class)) {
				return ((Number) value).floatValue();
			} else if (type.equals(double.class)
					|| type.equals(Double.class)) {
				return ((Number) value).doubleValue();
			}else{
				throw new RuntimeException("没有处理的数据类型:" + type.getName());
			}	
		}
	}

	/**
	 * 比较数值
	 * @param op1
	 * @param op2
	 * @return
	 */
	public static int compareNumber(Number op1, Number op2){
		int type1 = OperatorOfNumber.getSeq(op1.getClass());
		int type2 = OperatorOfNumber.getSeq(op2.getClass());
		int type = type1 >  type2 ? type1:type2;
		if(type == 1)  {
			byte o1 =	((Number)op1).byteValue();
			byte o2 =  ((Number)op2).byteValue();
			if(o1 == o2) return 0;
			if(o1 < o2) return -1;
			return 1;
		}
		if(type == 2) {
			short o1 =	((Number)op1).shortValue();
			short o2 =  ((Number)op2).shortValue();
			if(o1 == o2) return 0;
			if(o1 < o2) return -1;
			return 1;
		}
		if(type == 3) {
			int o1 =	((Number)op1).intValue();
			int o2 =  ((Number)op2).intValue();
			if(o1 == o2) return 0;
			if(o1 < o2) return -1;
			return 1;
		}
		if(type == 4) {
			long o1 =	((Number)op1).longValue();
			long o2 =  ((Number)op2).longValue();
			if(o1 == o2) return 0;
			if(o1 < o2) return -1;
			return 1;
		}
		if(type == 5) {
			float o1 =	((Number)op1).floatValue();
			float o2 =  ((Number)op2).floatValue();
			if(o1 == o2) return 0;
			if(o1 < o2) return -1;
			return 1;
		}
		if(type == 6){
			double o1 =	((Number)op1).doubleValue();
			double o2 =  ((Number)op2).doubleValue();
			if(o1 == o2) return 0;
			if(o1 < o2) return -1;
			return 1;
		}
		if(type == 7){
			BigDecimal o1 =	new BigDecimal(op1.toString());
			BigDecimal o2 = new BigDecimal(op2.toString());
			return o1.compareTo(o2);
		}
		throw new RuntimeException("比较操作错误:op1=" + op1.toString() +",op2=" + op2.toString());

	}

	/**
	 * 添加
	 * @param op1
	 * @param op2
	 * @param isPrecise
	 * @return
	 * @throws Exception
	 */
	public static Object add(Object op1, Object op2,boolean isPrecise) throws Exception {
		if(op1 == null){
			op1 = "null";
		}
		if(op2 == null){
			op2 = "null";
		}
		if (op1 instanceof String || op2 instanceof String) {				
			return op1.toString() + op2.toString();
		}
		if(isPrecise==true){
			return PreciseNumberOperator.addPrecise((Number)op1,(Number)op2);
		}else{
			return NormalNumberOperator.addNormal((Number)op1,(Number)op2);
		}
	}

	/**
	 * 截取
	 * @param op1
	 * @param op2
	 * @param isPrecise
	 * @return
	 * @throws Exception
	 */
	public static Number subtract(Object op1, Object op2,boolean isPrecise) throws Exception {
		if(isPrecise==true){
			return PreciseNumberOperator.subtractPrecise((Number)op1,(Number)op2);
		}else{
			return NormalNumberOperator.subtractNormal((Number)op1,(Number)op2);
		}
	}

	/**
	 * 乘法
	 * @param op1
	 * @param op2
	 * @param isPrecise
	 * @return
	 * @throws Exception
	 */
	public static Number multiply(Object op1, Object op2,boolean isPrecise) throws Exception {
		if(isPrecise==true){
			return PreciseNumberOperator.multiplyPrecise((Number)op1,(Number)op2);
		}else{
			return NormalNumberOperator.multiplyNormal((Number)op1,(Number)op2);
		}
	}

	/**
	 * 减法
	 * @param op1
	 * @param op2
	 * @param isPrecise
	 * @return
	 * @throws Exception
	 */
	public static Number divide(Object op1, Object op2,boolean isPrecise) throws Exception {
		if(isPrecise==true){
			return PreciseNumberOperator.dividePrecise((Number)op1,(Number)op2);
		}else{
			return NormalNumberOperator.divideNormal((Number)op1,(Number)op2);
		}
	}	
	  public static Object modulo(Object op1,Object op2) throws Exception{
		  return NormalNumberOperator.moduloNormal((Number)op1,(Number)op2);		  
	  }
}

/**
 * 正常的数值操作
 */
class NormalNumberOperator {

	
	/**
	 * 普通的加法运算	
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
	public static Number addNormal(Number op1, Number op2) throws Exception {
		int type1 = OperatorOfNumber.getSeq(op1.getClass());
		int type2 = OperatorOfNumber.getSeq(op2.getClass());
		int type = type1 >  type2 ? type1:type2;
		if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() + op2.byteValue();
		if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() + op2.shortValue();
		if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() + op2.intValue();
		if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() + op2.longValue();
		if(type == NumberType.NUMBER_TYPE_FLOAT) return op1.floatValue() + op2.floatValue();
		if(type == NumberType.NUMBER_TYPE_DOUBLE) return op1.doubleValue() + op2.doubleValue();
		if(type == NumberType.NUMBER_TYPE_BIGDECIMAL) return new BigDecimal(op1.toString()).add(new BigDecimal(op2.toString()));		
		throw new QLException("不支持的对象执行了\"+\"操作");
	}


	/**
	 * 普通的减法操作
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
	 public  static  Number subtractNormal(Number op1,Number op2) throws Exception{
			int type1 = OperatorOfNumber.getSeq(op1.getClass());
			int type2 = OperatorOfNumber.getSeq(op2.getClass());
			int type = type1 >  type2 ? type1:type2;
			if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() - op2.byteValue();
			if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() - op2.shortValue();
			if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() - op2.intValue();
			if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() - op2.longValue();
			if(type == NumberType.NUMBER_TYPE_FLOAT) return op1.floatValue() - op2.floatValue();
			if(type == NumberType.NUMBER_TYPE_DOUBLE) return op1.doubleValue() - op2.doubleValue();
			if(type == NumberType.NUMBER_TYPE_BIGDECIMAL) return new BigDecimal(op1.toString()).subtract(new BigDecimal(op2.toString()));
			throw new QLException("不支持的对象执行了\"-\"操作");
	    }

	/**
	 * 普通的乘法操作
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
	    public static Number multiplyNormal(Number op1,Number op2) throws Exception {
			int type1 = OperatorOfNumber.getSeq(op1.getClass());
			int type2 = OperatorOfNumber.getSeq(op2.getClass());
			int type = type1 >  type2 ? type1:type2;
			if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() * op2.byteValue();
			if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() * op2.shortValue();
			if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() * op2.intValue();
			if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() * op2.longValue();
			if(type == NumberType.NUMBER_TYPE_FLOAT) return op1.floatValue() * op2.floatValue();
			if(type == NumberType.NUMBER_TYPE_DOUBLE) return op1.doubleValue() * op2.doubleValue();
			if(type == NumberType.NUMBER_TYPE_BIGDECIMAL) return new BigDecimal(op1.toString()).multiply(new BigDecimal(op2.toString()));
			throw new QLException("不支持的对象执行了\"*\"操作");
	    }

	/**
	 * 普通的除法操作
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
	   public static Number divideNormal(Number op1,Number op2) throws Exception{
			int type1 = OperatorOfNumber.getSeq(op1.getClass());
			int type2 = OperatorOfNumber.getSeq(op2.getClass());
			int type = type1 >  type2 ? type1:type2;
			if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() / op2.byteValue();
			if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() / op2.shortValue();
			if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() / op2.intValue();
			if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() / op2.longValue();
			if(type == NumberType.NUMBER_TYPE_FLOAT) return op1.floatValue() / op2.floatValue();
			if(type == NumberType.NUMBER_TYPE_DOUBLE) return op1.doubleValue() / op2.doubleValue();
			if(type == NumberType.NUMBER_TYPE_BIGDECIMAL) return new BigDecimal(op1.toString()).divide(new BigDecimal(op2.toString()), BigDecimal.ROUND_HALF_UP);
			throw new QLException("不支持的对象执行了\"/\"操作");
	    }

	/**
	 * 普通的取模运算
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
    public static Number moduloNormal(Number op1,Number op2) throws Exception{
			int type1 = OperatorOfNumber.getSeq(op1.getClass());
			int type2 = OperatorOfNumber.getSeq(op2.getClass());
			int type = type1 >  type2 ? type1:type2;
			if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() % op2.byteValue();
			if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() % op2.shortValue();
			if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() % op2.intValue();
			if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() % op2.longValue();
			throw new QLException("不支持的对象执行了\"mod\"操作");
     }
}

/**
 * 高精度计算
 * @author xuannan
 */
class PreciseNumberOperator {
	
	public static int DIVIDE_PRECISION = 10;

	/**
	 * 添加高精度
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
	public static Number addPrecise(Number op1, Number op2) throws Exception {
		BigDecimal result =  null;
		if(op1 instanceof BigDecimal){
			if(op2 instanceof BigDecimal){
				result =  ((BigDecimal)op1).add((BigDecimal)op2);
			}else{
				result =  ((BigDecimal)op1).add(new BigDecimal(op2.toString()));
			}
		}else{
			if(op2 instanceof BigDecimal){
				result =  new BigDecimal(op1.toString()).add((BigDecimal)op2);
			}else{
				result =  new BigDecimal(op1.toString()).add(new BigDecimal(op2.toString()));
			}
		}
		if(result.scale() ==0){
			long tempLong =  result.longValue();
			if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
				return (int)tempLong;
			}else{
				return tempLong;
			}
		}else{
			return result;
		}
		
	}

	/**
	 * 减法高精度
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
	public static Number subtractPrecise(Number op1, Number op2) throws Exception {
		BigDecimal result =  null;
		if(op1 instanceof BigDecimal){
			if(op2 instanceof BigDecimal){
				result = ((BigDecimal)op1).subtract((BigDecimal)op2);
			}else{
				result = ((BigDecimal)op1).subtract(new BigDecimal(op2.toString()));
			}
		}else{
			if(op2 instanceof BigDecimal){
				result = new BigDecimal(op1.toString()).subtract((BigDecimal)op2);
			}else{
				result = new BigDecimal(op1.toString()).subtract(new BigDecimal(op2.toString()));
			}
		}
		if(result.scale() ==0){
			long tempLong =  result.longValue();
			if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
				return (int)tempLong;
			}else{
				return tempLong;
			}
		}else{
			return result;
		}
	}

	/**
	 * 乘法高精度
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
	public static Number multiplyPrecise(Number op1, Number op2) throws Exception {
		BigDecimal result =  null;
		if(op1 instanceof BigDecimal){
			if(op2 instanceof BigDecimal){
				result = ((BigDecimal)op1).multiply((BigDecimal)op2);
			}else{
				result = ((BigDecimal)op1).multiply(new BigDecimal(op2.toString()));
			}
		}else{
			if(op2 instanceof BigDecimal){
				result = new BigDecimal(op1.toString()).multiply((BigDecimal)op2);
			}else{
				result = new BigDecimal(op1.toString()).multiply(new BigDecimal(op2.toString()));
			}
		}
		if(result.scale() ==0){
			long tempLong =  result.longValue();
			if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
				return (int)tempLong;
			}else{
				return tempLong;
			}
		}else{
			return result;
		}
	}

	/**
	 * 除法高精度
	 * @param op1
	 * @param op2
	 * @return
	 * @throws Exception
	 */
	public static Number dividePrecise(Number op1, Number op2) throws Exception {
		BigDecimal result =  null;
		if(op1 instanceof BigDecimal){
			if(op2 instanceof BigDecimal){
				result = ((BigDecimal)op1).divide((BigDecimal)op2, DIVIDE_PRECISION, BigDecimal.ROUND_HALF_UP);
			}else{
				result = ((BigDecimal)op1).divide(new BigDecimal(op2.toString()), DIVIDE_PRECISION, BigDecimal.ROUND_HALF_UP);
			}
		}else{
			if(op2 instanceof BigDecimal){
				result = new BigDecimal(op1.toString()).divide((BigDecimal)op2, DIVIDE_PRECISION, BigDecimal.ROUND_HALF_UP);
			}else{
				result = new BigDecimal(op1.toString()).divide(new BigDecimal(op2.toString()), DIVIDE_PRECISION, BigDecimal.ROUND_HALF_UP);
			}
		}
		if(result.scale() ==0){
			long tempLong =  result.longValue();
			if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
				return (int)tempLong;
			}else{
				return tempLong;
			}
		}else{
			return result;
		}
	}
}

9.22、RunEnvironment(运行环境)

package com.ql.util.express;


import com.ql.util.express.exception.QLException;

/**
 * 运行环境
 * @author xiaochengxinyizhan
 */
public final class RunEnvironment {
		private static int INIT_DATA_LENTH = 15;
	    private boolean isTrace = false;	
		private int point = -1;
	    protected int programPoint = 0;
		private OperateData[] dataContainer;
		private ArraySwap arraySwap = new ArraySwap();
		
		private boolean isExit = false;
		private Object returnValue = null; 
		
		private InstructionSet instructionSet;
		private InstructionSetContext context;
		
		
		public RunEnvironment(InstructionSet aInstructionSet,InstructionSetContext  aContext,boolean aIsTrace){
			dataContainer = new OperateData[INIT_DATA_LENTH];
			this.instructionSet = aInstructionSet;
			this.context = aContext;
			this.isTrace = aIsTrace;
		}
		
		public void initial(InstructionSet aInstructionSet,InstructionSetContext  aContext,boolean aIsTrace){
			this.instructionSet = aInstructionSet;
			this.context = aContext;
			this.isTrace = aIsTrace;
		}
		public void clear(){
		    isTrace = false;	
			point = -1;
		    programPoint = 0;
			
			isExit = false;
			returnValue = null; 
			
			instructionSet = null;
			context = null;
			
		}
		public InstructionSet getInstructionSet() {
			return instructionSet;
		}


		public InstructionSetContext getContext(){
			return this.context;
		}
		public void setContext(InstructionSetContext aContext){
			this.context = aContext;
		}

		public boolean isExit() {
			return isExit;
		}
		public Object getReturnValue() {
			return returnValue;
		}
		public void setReturnValue(Object value){
			this.returnValue = value;
		}
		public void quitExpress(Object aReturnValue){
			this.isExit = true;
			this.returnValue = aReturnValue;
		}
		public void quitExpress(){
			this.isExit = true;
			this.returnValue = null;
		}
		public boolean isTrace(){
			return this.isTrace;
		}
		public int getProgramPoint() {
			return programPoint;
		}
		public void programPointAddOne() {
			programPoint ++ ;
		}
		public void gotoLastWhenReturn(){
			programPoint = this.instructionSet.getInstructionLength();
		}
	    public int getDataStackSize(){
	    	return this.point + 1;
	    }
		public void push(OperateData data){
			this.point++;
			if(this.point >= this.dataContainer.length){
			   ensureCapacity(this.point + 1);
			}
			this.dataContainer[point] = data;
		}
		public OperateData peek(){
			if(point <0){
				throw new RuntimeException("系统异常,堆栈指针错误");
			}
			return this.dataContainer[point];		
		}
		public OperateData pop(){
			if(point <0)
				throw new RuntimeException("系统异常,堆栈指针错误");
			OperateData result = this.dataContainer[point];
			this.point--;
			return result;
		}
		public void clearDataStack(){
			this.point = -1;
		}
		public void gotoWithOffset(int aOffset ){
			this.programPoint = this.programPoint + aOffset;
		}
	/**
	 * 此方法是调用最频繁的,因此尽量精简代码,提高效率 
	 * @param context
	 * @param len
	 * @return
	 * @throws Exception
	 */
		public ArraySwap popArray(InstructionSetContext context,int len) throws Exception {
			int start = point - len + 1;
			this.arraySwap.swap(this.dataContainer,start,len);
			point = point - len;
			return this.arraySwap;
		}
		
		public OperateData[] popArrayOld(InstructionSetContext context,int len) throws Exception {
			int start = point - len + 1;
			OperateData[] result = new OperateData[len];
			System.arraycopy(this.dataContainer,start, result,0, len);
			point = point - len;
			return result;
		}
		
		public OperateData[] popArrayBackUp(InstructionSetContext context,int len) throws Exception {
			int start = point - len + 1;
			if(start <0){
				throw new QLException("堆栈溢出,请检查表达式是否错误");
			}
			OperateData[] result = new OperateData[len];
			for (int i = 0 ; i < len; i++) {
				result[i] = this.dataContainer[start + i];
				if(void.class.equals(result[i].getType(context))){
					throw new QLException("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句");
				}
			}
			point = point - len;
			return result;
		}

		public void ensureCapacity(int minCapacity) {
			int oldCapacity = this.dataContainer.length;
			if (minCapacity > oldCapacity) {
				int newCapacity = (oldCapacity * 3) / 2 + 1;
				if (newCapacity < minCapacity){
					newCapacity = minCapacity;
				}
				OperateData[] tempList = new OperateData[newCapacity];
				System.arraycopy(this.dataContainer,0,tempList,0,oldCapacity);
				this.dataContainer = tempList;
			}
		}
	}

十、小结

借鉴的学习内容是在充分掌握Java基础上进行了一些简单的运算和语法的封装。模拟java的编译器形成自己的一套语法规则,值得学习。做的不好的地方,其实是基于老项目的维护,有些魔法数字以及无注释,代码不规整等内容

  • 1、线程安全,引擎运算过程中的产生的临时变量都是threadlocal类型。

  • 2、高效执行,比较耗时的脚本编译过程可以缓存在本地机器,运行时的临时变量创建采用了缓冲池的技术,和groovy性能相当。