├── README.md ├── config └── rule.xml ├── deploy └── lib │ ├── commons-beanutils-1.8.2.jar │ ├── commons-lang-2.4.jar │ └── commons-logging-1.1.1.jar ├── pom.xml └── src └── main └── java └── com └── ql └── util └── express ├── CacheObject.java ├── CallResult.java ├── DefaultContext.java ├── DefaultExpressResourceLoader.java ├── ExportItem.java ├── ExpressClassLoader.java ├── ExpressLoader.java ├── ExpressRemoteCacheRunner.java ├── ExpressRunner.java ├── ExpressUtil.java ├── IExpressContext.java ├── IExpressResourceLoader.java ├── InstructionSet.java ├── InstructionSetContext.java ├── InstructionSetRunner.java ├── LocalExpressCacheRunner.java ├── OperateData.java ├── Operator.java ├── OperatorOfNumber.java ├── Rule.java ├── RuleContext.java ├── RuleRunner.java ├── RunEnvironment.java ├── dao └── RuleMapper.java ├── instruction ├── BlockInstructionFactory.java ├── BreakInstructionFactory.java ├── CallFunctionInstructionFactory.java ├── CastInstructionFactory.java ├── ConstDataInstructionFactory.java ├── ContinueInstructionFactory.java ├── DefineInstructionFactory.java ├── ForInstructionFactory.java ├── ForRelBreakContinue.java ├── FunctionInstructionFactory.java ├── FunctionInstructionSet.java ├── IOperateDataCache.java ├── IfInstructionFactory.java ├── InInstructionFactory.java ├── InstructionFactory.java ├── KeyValueInstructionFactory.java ├── LoadAttrInstructionFactory.java ├── MacroInstructionFactory.java ├── MethodCallInstructionFactory.java ├── NewInstructionFactory.java ├── NewVClassInstructionFactory.java ├── NullInstructionFactory.java ├── OperateDataCacheImpl.java ├── OperateDataCacheImpl4Orig.java ├── OperateDataCacheManager.java ├── OperatorInstructionFactory.java ├── detail │ ├── Instruction.java │ ├── InstructionCallMacro.java │ ├── InstructionCallSelfDefineFunction.java │ ├── InstructionClearDataStack.java │ ├── InstructionCloseNewArea.java │ ├── InstructionConstData.java │ ├── InstructionGoTo.java │ ├── InstructionGoToWithCondition.java │ ├── InstructionGoToWithNotNull.java │ ├── InstructionLoadAttr.java │ ├── InstructionNewVirClass.java │ ├── InstructionOpenNewArea.java │ ├── InstructionOperator.java │ └── InstructionReturn.java ├── op │ ├── CanClone.java │ ├── OperatorAddReduce.java │ ├── OperatorAlias.java │ ├── OperatorAnd.java │ ├── OperatorAnonymousNewArray.java │ ├── OperatorAnonymousNewList.java │ ├── OperatorAnonymousNewMap.java │ ├── OperatorArray.java │ ├── OperatorBase.java │ ├── OperatorCast.java │ ├── OperatorDef.java │ ├── OperatorDoubleAddReduce.java │ ├── OperatorEqualsLessMore.java │ ├── OperatorEvaluate.java │ ├── OperatorExportAlias.java │ ├── OperatorExportDef.java │ ├── OperatorFactory.java │ ├── OperatorField.java │ ├── OperatorIf.java │ ├── OperatorIn.java │ ├── OperatorKeyValue.java │ ├── OperatorLike.java │ ├── OperatorMacro.java │ ├── OperatorMethod.java │ ├── OperatorMinMax.java │ ├── OperatorMultiDiv.java │ ├── OperatorNew.java │ ├── OperatorNor.java │ ├── OperatorNot.java │ ├── OperatorNullOp.java │ ├── OperatorOr.java │ ├── OperatorPrint.java │ ├── OperatorPrintln.java │ ├── OperatorRound.java │ ├── OperatorSelfDefineClassFunction.java │ └── OperatorSelfDefineServiceFunction.java └── opdata │ ├── OperateClass.java │ ├── OperateDataAlias.java │ ├── OperateDataArrayItem.java │ ├── OperateDataAttr.java │ ├── OperateDataField.java │ ├── OperateDataKeyValue.java │ ├── OperateDataLocalVar.java │ └── OperateDataVirClass.java ├── match ├── IDataNode.java ├── INodeType.java ├── INodeTypeManager.java ├── NodeTypeManagerTestImpl.java ├── QLMatchResult.java ├── QLMatchResultTree.java ├── QLPattern.java └── QLPatternNode.java └── parse ├── ExpressNode.java ├── ExpressPackage.java ├── ExpressParse.java ├── KeyWordDefine4Java.java ├── KeyWordDefine4SQL.java ├── NodeType.java ├── NodeTypeManager.java ├── Word.java └── WordSplit.java /README.md: -------------------------------------------------------------------------------- 1 | config/rule.xml是规则引擎的配置文件,如果使用spring,请import进spring上下文配置文件里; 2 | 3 | 规则引擎采用了jboss drools的设计思路: 4 | 5 | 规则=规则执行条件+规则执行内容+规则分组 + 规则优先级 6 | 7 | 规则的执行内容和执行条件建议以java脚本的形式存在数据库中,比如我使用了mysql,那么建表语句如下: 8 | 9 | create table `rule` ( 10 | 11 | `id` int(10) unsigned not null auto_increment comment '规则主键', 12 | 13 | `rule_name` varchar(50) not null default '' comment '规则名称', 14 | 15 | `priority` int(4) not null default 0 comment '规则优先级,越大优先级越高', 16 | 17 | `group_type` tinyint not null default 0 comment '分组类型 1:占位', 18 | 19 | `group_name` varchar(50) not null default '' comment '分组名称', 20 | 21 | `match_condition` varchar(100) not null default 'true' comment '规则进入条件', 22 | 23 | `execute_content` varchar(1000) not null default '' comment '规则执行内容', 24 | 25 | `del_flag` tinyint(4) not null default 0 comment '是否删除 0 未删除 1已删除', 26 | 27 | `op_time` timestamp not null default current_timestamp on update current_timestamp comment '操作时间', 28 | 29 | primary key (`id`), 30 | 31 | index (`group_type`) 32 | 33 | )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='wanglei@2014-11-25 规则配置表'; 34 | 35 | 规则会被缓存在服务部署的机器内存里,所以需要提供一个后门用于刷新缓存,API如下: 36 | 37 | RuleRunner.java 38 | 39 | /** 40 | * 41 | *Description:刷新规则内容
42 | * 43 | *@author wanglei
44 | *@taskId

45 | */ 46 | 47 | public synchronized void refreshRules() { 48 | 49 | ruleList = ruleMapper.getRuleList(); 50 | 51 | rulesCache = new HashMap>(); 52 | 53 | } 54 | 55 | 后续会考虑使用memcache这种分布式的缓存,目前有没有使用,因为觉得有点杀鸡用牛刀。 56 | 57 | 最近发现阿里的diamond真是特别好用,如果公司有接入diamond的话,可以考虑直接用diamond存储规则,不过这样一来RuleManager就得再写一个了,也许这里应该最初就设计成一个工厂或者模板的模式。 58 | 59 | 规则的解析基于taocode的qlexpress,我这里做了简单的封装,以适应于我的项目,关于qlexpress,参考: 60 | 61 | http://code.taobao.org/p/QLExpress/wiki/index/ 62 | -------------------------------------------------------------------------------- /config/rule.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /deploy/lib/commons-beanutils-1.8.2.jar: -------------------------------------------------------------------------------- 1 | PK 2 | spi; META-INF/PK 3 | rpi;|x`鄅?META-INF/MANIFEST.MF -------------------------------------------------------------------------------- /deploy/lib/commons-lang-2.4.jar: -------------------------------------------------------------------------------- 1 | PK 2 | i -------------------------------------------------------------------------------- /deploy/lib/commons-logging-1.1.1.jar: -------------------------------------------------------------------------------- 1 | PK 2 | s7 META-INF/PK 3 | s7櫨"骢META-INF/MANIFEST.MF峇蒵 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.tuniu.common 6 | jar 7 | 1.0.0 8 | rule 9 | 10 | 1.6 11 | UTF-8 12 | 13 | 14 | 15 | 16 | commons-beanutils 17 | commons-beanutils 18 | 1.8.2 19 | 20 | 21 | log4j 22 | log4j 23 | 1.2.16 24 | 25 | 26 | commons-logging 27 | commons-logging 28 | 1.1.1 29 | 30 | 31 | commons-lang 32 | commons-lang 33 | 2.4 34 | 35 | 36 | junit 37 | junit 38 | 4.4 39 | test 40 | 41 | 42 | org.unitils 43 | unitils 44 | 2.4 45 | test 46 | 47 | 48 | org.springframework 49 | spring 50 | 2.5.6 51 | test 52 | 53 | 54 | org.mybatis 55 | mybatis 56 | 3.2.3 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.apache.maven.plugins 64 | maven-compiler-plugin 65 | 66 | 1.6 67 | 1.6 68 | 69 | 70 | 71 | maven-source-plugin 72 | 2.1 73 | 74 | true 75 | 76 | 77 | 78 | compile 79 | 80 | jar 81 | 82 | 83 | 84 | 85 | 86 | 87 | rule 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/CacheObject.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 简单的缓存对象 7 | * @author tianqiao 8 | * 9 | */ 10 | public class CacheObject implements Serializable{ 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = -145121001676214513L; 16 | 17 | private String expressName; 18 | 19 | private String text; 20 | 21 | private InstructionSet instructionSet; 22 | 23 | public String getExpressName() { 24 | return expressName; 25 | } 26 | 27 | public void setExpressName(String name) { 28 | this.expressName = name; 29 | } 30 | 31 | public String getText() { 32 | return text; 33 | } 34 | 35 | public void setText(String text) { 36 | this.text = text; 37 | } 38 | 39 | public InstructionSet getInstructionSet() { 40 | return instructionSet; 41 | } 42 | 43 | public void setInstructionSet(InstructionSet instructionSet) { 44 | this.instructionSet = instructionSet; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/CallResult.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | public class CallResult{ 4 | private Object returnValue; 5 | private boolean isExit; 6 | public CallResult(Object aReturnValue,boolean aIsExit){ 7 | this.initial(aReturnValue, aIsExit); 8 | } 9 | public void initial(Object aReturnValue,boolean aIsExit){ 10 | this.returnValue = aReturnValue; 11 | this.isExit = aIsExit; 12 | } 13 | public void clear(){ 14 | this.returnValue = null; 15 | this.isExit = false; 16 | } 17 | public Object getReturnValue() { 18 | return returnValue; 19 | } 20 | public boolean isExit() { 21 | return isExit; 22 | } 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/DefaultContext.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.util.HashMap; 4 | 5 | 6 | @SuppressWarnings("serial") 7 | public class DefaultContext extends HashMap implements IExpressContext { 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/DefaultExpressResourceLoader.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | 7 | public class DefaultExpressResourceLoader implements IExpressResourceLoader { 8 | public String loadExpress(String expressName) throws Exception { 9 | expressName = expressName.replace('.', '/') + ".ql"; 10 | InputStream in = Thread.currentThread().getContextClassLoader() 11 | .getResourceAsStream(expressName); 12 | if (in == null) { 13 | throw new Exception("不能找到表达式文件:" + expressName); 14 | } 15 | BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 16 | StringBuilder builder = new StringBuilder(); 17 | String tmpStr = null; 18 | while ((tmpStr = reader.readLine()) != null) { 19 | builder.append(tmpStr).append("\n"); 20 | } 21 | reader.close(); 22 | in.close(); 23 | return builder.toString(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/ExportItem.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 输出给其它指令共享使用的对象 7 | * @author xuannan 8 | * 9 | */ 10 | public class ExportItem implements Serializable{ 11 | private static final long serialVersionUID = 5440012774123494760L; 12 | public static String TYPE_ALIAS ="alias"; 13 | public static String TYPE_DEF ="def"; 14 | public static String TYPE_FUNCTION ="function"; 15 | public static String TYPE_MACRO ="macro"; 16 | String globeName; 17 | String name; 18 | String type;//def,alias 19 | String desc;//类名或者别名 20 | public ExportItem(String aName,String aType,String aDesc){ 21 | this.globeName = aName; 22 | this.name = aName; 23 | this.type =aType; 24 | this.desc = aDesc; 25 | } 26 | public ExportItem(String aGlobeName,String aName,String aType,String aDesc){ 27 | this.globeName = aGlobeName; 28 | this.name = aName; 29 | this.type =aType; 30 | this.desc = aDesc; 31 | } 32 | public String toString(){ 33 | return this.globeName + "["+ this.type +":" + this.name +" " + this.desc + "]"; 34 | } 35 | public String getGlobeName() { 36 | return globeName; 37 | } 38 | public void setGlobeName(String globeName) { 39 | this.globeName = globeName; 40 | } 41 | public String getName() { 42 | return name; 43 | } 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | public String getType() { 48 | return type; 49 | } 50 | public void setType(String type) { 51 | this.type = type; 52 | } 53 | public String getDesc() { 54 | return desc; 55 | } 56 | public void setDesc(String desc) { 57 | this.desc = desc; 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/ExpressClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.lang.reflect.Array; 4 | import java.lang.reflect.Method; 5 | 6 | public class ExpressClassLoader extends ClassLoader { 7 | public ExpressClassLoader(ClassLoader parent){ 8 | super(parent); 9 | } 10 | public Class loadClass(String name, byte[] code) { 11 | return this.defineClass(name, code, 0, code.length); 12 | } 13 | 14 | public synchronized Class loadClass(String name, boolean resolve) 15 | throws ClassNotFoundException { 16 | //System.out.print("开始查找 类" + name + "。。。。。。。。。。。"); 17 | Class clasz = findLoadedClass(this, name); 18 | if (clasz != null) { 19 | //System.out.println(clasz.getClassLoader()); 20 | return clasz; 21 | } 22 | if (clasz == null) { 23 | clasz = parentLoadClass(this, name); 24 | } 25 | if (clasz == null && name.startsWith("[")) { // 进行数组处理 26 | int index = name.indexOf("L"); 27 | String str = name.substring(0, index); 28 | String componentClassName = name.substring(index + 1, 29 | name.length() - 1); 30 | int[] dimes = new int[str.length()]; 31 | for (int i = 0; i < dimes.length; i++) { 32 | dimes[i] = 0; 33 | } 34 | try { 35 | Class componentType = this.loadClass(componentClassName); 36 | clasz = Array.newInstance(componentType, dimes).getClass(); 37 | } catch (Exception e) { 38 | // 不错处理 39 | } 40 | } 41 | 42 | if (clasz == null) 43 | throw new ClassNotFoundException(name); 44 | return clasz; 45 | } 46 | 47 | public static Class findLoadedClass(ClassLoader loader, String name) 48 | throws ClassNotFoundException { 49 | Method m = null; 50 | try { 51 | m = ClassLoader.class.getDeclaredMethod("findLoadedClass", 52 | new Class[] { String.class }); 53 | m.setAccessible(true); 54 | Class result = (Class) m.invoke(loader, new Object[] { name }); 55 | if (result == null) { 56 | result = (Class) m.invoke(loader.getClass().getClassLoader(), 57 | new Object[] { name }); 58 | } 59 | if (result == null) { 60 | result = (Class) m.invoke(Thread.currentThread() 61 | .getContextClassLoader(), new Object[] { name }); 62 | } 63 | return result; 64 | } catch (Exception ex) { 65 | throw new ClassNotFoundException(ex.getMessage()); 66 | } finally { 67 | if (m != null) { 68 | m.setAccessible(false); 69 | } 70 | } 71 | } 72 | 73 | public static Class parentLoadClass(ClassLoader loader, String name) 74 | throws ClassNotFoundException { 75 | // 如果存在这个类,则直接返回 76 | Class clasz = null; 77 | if (clasz == null) { 78 | try { 79 | clasz = loader.getClass().getClassLoader().loadClass(name); 80 | } catch (Throwable e) { 81 | } 82 | } 83 | if (clasz == null) 84 | try { 85 | clasz = Thread.currentThread().getContextClassLoader() 86 | .loadClass(name); 87 | } catch (Throwable e) { 88 | } 89 | return clasz; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/ExpressLoader.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.util.Map; 4 | import java.util.TreeMap; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | import com.ql.util.express.instruction.FunctionInstructionSet; 8 | 9 | 10 | /** 11 | * 表达式装载器 12 | * 13 | * @author xuannan 14 | * 15 | */ 16 | public class ExpressLoader { 17 | private ConcurrentHashMap expressInstructionSetCache = new ConcurrentHashMap(); 18 | ExpressRunner creator; 19 | public ExpressLoader(ExpressRunner aCreator){ 20 | this.creator = aCreator; 21 | } 22 | public InstructionSet loadExpress(String expressName) 23 | throws Exception { 24 | return parseInstructionSet(expressName,this.creator.getExpressResourceLoader().loadExpress(expressName)); 25 | } 26 | 27 | public void addInstructionSet(String expressName, InstructionSet set) 28 | throws Exception { 29 | synchronized (expressInstructionSetCache) { 30 | if (expressInstructionSetCache.containsKey(expressName)) { 31 | throw new Exception("表达式定义重复:" + expressName); 32 | } 33 | expressInstructionSetCache.put(expressName, set); 34 | } 35 | } 36 | 37 | public InstructionSet parseInstructionSet(String expressName, 38 | String expressString) throws Exception { 39 | InstructionSet parseResult = null; 40 | if (expressInstructionSetCache.containsKey(expressName)) { 41 | throw new Exception("表达式定义重复:" + expressName); 42 | } 43 | synchronized (expressInstructionSetCache) { 44 | parseResult = this.creator.parseInstructionSet(expressString); 45 | parseResult.setName(expressName); 46 | parseResult.setGlobeName(expressName); 47 | // 需要将函数和宏定义都提取出来 48 | for (FunctionInstructionSet item : parseResult 49 | .getFunctionInstructionSets()) { 50 | this.addInstructionSet(item.name, item.instructionSet); 51 | item.instructionSet.setName(item.name); 52 | item.instructionSet.setGlobeName(expressName+ "." + item.name); 53 | } 54 | if(parseResult.hasMain()){ 55 | this.addInstructionSet(expressName, parseResult); 56 | } 57 | } 58 | return parseResult; 59 | } 60 | public void clear(){ 61 | this.expressInstructionSetCache.clear(); 62 | } 63 | public InstructionSet getInstructionSet(String expressName) { 64 | return expressInstructionSetCache.get(expressName); 65 | } 66 | public ExportItem[] getExportInfo(){ 67 | Map result = new TreeMap(); 68 | for(InstructionSet item:expressInstructionSetCache.values()){ 69 | for(ExportItem var:item.getExportDef()){ 70 | var.setGlobeName(item.getGlobeName() + "." + var.name); 71 | result.put(var.getGlobeName(),var); 72 | } 73 | result.put(item.getGlobeName(),new ExportItem(item.getGlobeName(), item.getName(),item.getType(),item.toString())); 74 | } 75 | return (ExportItem[])result.values().toArray(new ExportItem[0]); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/ExpressRemoteCacheRunner.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.logging.Log; 6 | 7 | /** 8 | * 远程缓存对象 9 | * @author tianqiao 10 | * 11 | */ 12 | public abstract class ExpressRemoteCacheRunner { 13 | 14 | 15 | 16 | public void loadCache(String expressName,String text){ 17 | InstructionSet instructionSet; 18 | try { 19 | instructionSet = getExpressRunner().parseInstructionSet(text); 20 | CacheObject cache = new CacheObject(); 21 | cache.setExpressName(expressName); 22 | cache.setText(text); 23 | cache.setInstructionSet(instructionSet); 24 | this.putCache(expressName, cache); 25 | } catch (Exception e) { 26 | throw new RuntimeException("解析指令并缓存过程出现错误.",e); 27 | } 28 | } 29 | 30 | 31 | public Object execute(String name,IExpressContext context, List errorList, 32 | boolean isTrace,boolean isCatchException, Log aLog){ 33 | try { 34 | CacheObject cache = (CacheObject) this.getCache(name); 35 | if(cache==null){ 36 | throw new RuntimeException("未获取到缓存对象."); 37 | } 38 | return getExpressRunner().execute(new InstructionSet[] {cache.getInstructionSet()}, context, errorList, isTrace, isCatchException, aLog); 39 | } catch (Exception e) { 40 | throw new RuntimeException("获取缓存信息,并且执行指令集出现错误.",e); 41 | } 42 | } 43 | 44 | /** 45 | * 获取执行器ExpressRunner 46 | * @return 47 | */ 48 | public abstract ExpressRunner getExpressRunner(); 49 | /** 50 | * 获取缓存对象 51 | * @param key 52 | * @return 53 | */ 54 | public abstract Object getCache(String key); 55 | /** 56 | * 放置缓存的对象 57 | * @param key 58 | * @param object 59 | */ 60 | public abstract void putCache(String key,Object object ); 61 | 62 | } 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/IExpressContext.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | /** 4 | * 表达式计算的数据注入接口 5 | * @author qhlhl2010@gmail.com 6 | * 7 | */ 8 | public interface IExpressContext { 9 | /** 10 | * 根据名称从属性列表中提取属性值。如果表达式中用到了Spring的对象,也是通过此方法获取 11 | * @param name 属性名称 12 | * @return 13 | * @throws Exception 14 | */ 15 | public V get(Object key); 16 | /** 17 | * 表达式计算的结果可以设置回调用系统,例如 userId = 3 + 4 18 | * @param name 属性名称 19 | * @param object 属性值 20 | * @throws Exception 21 | */ 22 | public V put(K name, V object); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/IExpressResourceLoader.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | /** 4 | * 加载表达式资源接口 5 | * @author xuannan 6 | * 7 | */ 8 | public interface IExpressResourceLoader { 9 | /** 10 | * 根据表达式名称获取表达式的内容 11 | * @param expressName 12 | * @return 13 | * @throws Exception 14 | */ 15 | public String loadExpress(String expressName) throws Exception; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/InstructionSetContext.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.ql.util.express.instruction.OperateDataCacheManager; 7 | 8 | public class InstructionSetContext implements IExpressContext { 9 | /* 10 | * 没有知道数据类型的变量定义是否传递到最外层的Context 11 | */ 12 | private boolean isExpandToParent = true; 13 | 14 | private IExpressContext parent = null; 15 | private Map content; 16 | /** 17 | * 符号表 18 | */ 19 | private Map symbolTable; 20 | 21 | private ExpressLoader expressLoader; 22 | 23 | private boolean isSupportDynamicFieldName = false; 24 | private ExpressRunner runner; 25 | 26 | public InstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){ 27 | this.initial(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName); 28 | } 29 | public void initial(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){ 30 | this.isExpandToParent = aIsExpandToParent; 31 | this.runner = aRunner; 32 | this.parent = aParent; 33 | this.expressLoader = aExpressLoader; 34 | this.isSupportDynamicFieldName = aIsSupportDynamicFieldName; 35 | } 36 | public void clear(){ 37 | isExpandToParent = true; 38 | parent = null; 39 | content = null; 40 | symbolTable = null; 41 | expressLoader = null; 42 | isSupportDynamicFieldName = false; 43 | runner = null; 44 | } 45 | public void exportSymbol(String varName,Object aliasNameObject) throws Exception{ 46 | if( this.parent != null && this.parent instanceof InstructionSetContext){ 47 | ((InstructionSetContext)this.parent).exportSymbol(varName, aliasNameObject); 48 | }else{ 49 | this.addSymbol(varName, aliasNameObject); 50 | } 51 | } 52 | public void addSymbol(String varName,Object aliasNameObject) throws Exception{ 53 | if(this.symbolTable == null){ 54 | this.symbolTable = new HashMap(); 55 | } 56 | if(this.symbolTable.containsKey(varName)){ 57 | throw new Exception("变量" + varName + "已经存在,不能重复定义,也不能再从函数内部 exprot "); 58 | } 59 | this.symbolTable.put(varName,aliasNameObject); 60 | } 61 | 62 | public void setSupportDynamicFieldName(boolean isSupportDynamicFieldName) { 63 | this.isSupportDynamicFieldName = isSupportDynamicFieldName; 64 | } 65 | public boolean isSupportDynamicFieldName(){ 66 | return this.isSupportDynamicFieldName; 67 | } 68 | public ExpressRunner getExpressRunner(){ 69 | return this.runner; 70 | } 71 | public Object findAliasOrDefSymbol(String varName)throws Exception{ 72 | Object result = null; 73 | if(this.symbolTable != null){ 74 | result = this.symbolTable.get(varName); 75 | } 76 | if(result == null){ 77 | if( this.parent != null && this.parent instanceof InstructionSetContext){ 78 | result = ((InstructionSetContext)this.parent).findAliasOrDefSymbol(varName); 79 | }else{ 80 | result = null; 81 | } 82 | } 83 | return result; 84 | } 85 | public Object getSymbol(String varName) throws Exception{ 86 | Object result = null; 87 | if(this.symbolTable != null){ 88 | result = this.symbolTable.get(varName); 89 | } 90 | if( result == null && this.expressLoader != null){ 91 | result = this.expressLoader.getInstructionSet(varName); 92 | } 93 | if(result == null){ 94 | if (this.isExpandToParent == true && this.parent != null 95 | && this.parent instanceof InstructionSetContext) { 96 | result = ((InstructionSetContext) this.parent) 97 | .getSymbol(varName); 98 | } else { 99 | result = OperateDataCacheManager.fetchOperateDataAttr(varName, null); 100 | this.addSymbol(varName, result); 101 | } 102 | } 103 | return result; 104 | } 105 | 106 | public ExpressLoader getExpressLoader() { 107 | return expressLoader; 108 | } 109 | 110 | public IExpressContext getParent(){ 111 | return this.parent; 112 | } 113 | public Object get(Object key){ 114 | if(this.content != null && this.content.containsKey(key)){ 115 | return this.content.get(key); 116 | }else if(this.isExpandToParent == true && this.parent != null){ 117 | return this.parent.get(key); 118 | } 119 | return null; 120 | } 121 | public Object put(String key, Object value){ 122 | if(this.content != null && this.content.containsKey(key) ){ 123 | return this.content.put(key,value); 124 | }else if (this.isExpandToParent == false){ 125 | if(this.content == null){ 126 | this.content = new HashMap(); 127 | } 128 | return this.content.put(key,value); 129 | }else if(this.parent != null){ 130 | return this.parent.put(key,value); 131 | }else{ 132 | throw new RuntimeException("没有定义局部变量:" + key +",而且没有全局上下文"); 133 | } 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/InstructionSetRunner.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.logging.Log; 6 | import org.apache.commons.logging.LogFactory; 7 | 8 | import com.ql.util.express.instruction.OperateDataCacheManager; 9 | 10 | public class InstructionSetRunner { 11 | private static final Log log = LogFactory.getLog(InstructionSetRunner.class); 12 | public static Object executeOuter(ExpressRunner runner,InstructionSet[] sets,ExpressLoader loader, 13 | IExpressContext aContext, List errorList, 14 | boolean isTrace,boolean isCatchException, 15 | Log aLog,boolean isSupportDynamicFieldName) throws Exception{ 16 | try{ 17 | //OperateDataCacheManager.resetCache(); 18 | return execute(runner,sets, loader, aContext, errorList, isTrace, isCatchException,true, aLog,isSupportDynamicFieldName); 19 | }finally{ 20 | OperateDataCacheManager.resetCache(); 21 | } 22 | } 23 | 24 | /** 25 | * 批量执行指令集合,指令集间可以共享 变量和函数 26 | * @param sets 27 | * @param aOperatorManager 28 | * @param aContext 29 | * @param errorList 30 | * @param aFunctionCacheMananger 31 | * @param isTrace 32 | * @return 33 | * @throws Exception 34 | */ 35 | public static Object execute(ExpressRunner runner,InstructionSet[] sets,ExpressLoader loader, 36 | IExpressContext aContext, List errorList, 37 | boolean isTrace,boolean isCatchException, 38 | boolean isReturnLastData,Log aLog,boolean isSupportDynamicFieldName) 39 | throws Exception { 40 | InstructionSetContext context = OperateDataCacheManager.fetchInstructionSetContext ( 41 | true,runner,aContext,loader,isSupportDynamicFieldName); 42 | Object result = execute(sets,context,errorList,isTrace,isCatchException,isReturnLastData,aLog); 43 | return result; 44 | } 45 | 46 | public static Object execute(InstructionSet[] sets, 47 | InstructionSetContext context, List errorList, boolean isTrace,boolean isCatchException, 48 | boolean isReturnLastData,Log aLog) throws Exception { 49 | RunEnvironment environmen = null; 50 | Object result = null; 51 | for (int i = 0; i < sets.length; i++) { 52 | InstructionSet tmpSet = sets[i]; 53 | environmen = OperateDataCacheManager.fetRunEnvironment(tmpSet, 54 | (InstructionSetContext ) context, isTrace); 55 | try { 56 | CallResult tempResult = tmpSet.excute(environmen, context, 57 | errorList, i == sets.length - 1,isReturnLastData,aLog); 58 | if (tempResult.isExit() == true) { 59 | result = tempResult.getReturnValue(); 60 | break; 61 | } 62 | } catch (Exception e) { 63 | if(isCatchException == true){ 64 | if (aLog != null){ 65 | aLog.error(e.getMessage(), e); 66 | }else{ 67 | log.error(e.getMessage(),e); 68 | } 69 | }else{ 70 | throw e; 71 | } 72 | } 73 | } 74 | return result; 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/LocalExpressCacheRunner.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 作为表达式 8 | * @author tianqiao 9 | * 10 | */ 11 | public class LocalExpressCacheRunner extends ExpressRemoteCacheRunner{ 12 | 13 | private static Map expressMap = new HashMap (); 14 | 15 | private ExpressRunner expressRunner; 16 | 17 | public LocalExpressCacheRunner(ExpressRunner expressRunner){ 18 | this.expressRunner = expressRunner; 19 | } 20 | @Override 21 | public final Object getCache(String key) { 22 | return expressMap.get(key); 23 | } 24 | 25 | @Override 26 | public final void putCache(String key, Object object) { 27 | expressMap.put(key, object); 28 | } 29 | 30 | @Override 31 | public final ExpressRunner getExpressRunner() { 32 | return this.expressRunner; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/OperateData.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | 4 | /** 5 | * 数据类型定义 6 | * @author qhlhl2010@gmail.com 7 | * 8 | */ 9 | 10 | public class OperateData implements java.io.Serializable { 11 | private static final long serialVersionUID = 4749348640699065036L; 12 | protected Object dataObject; 13 | protected Class type; 14 | 15 | public OperateData(Object obj, Class aType) { 16 | this.type = aType; 17 | this.dataObject = obj; 18 | } 19 | /** 20 | * 给对象缓存接口使用 21 | * @param obj 22 | * @param aType 23 | */ 24 | public void initial(Object obj, Class aType) { 25 | this.type = aType; 26 | this.dataObject = obj; 27 | } 28 | public void clear(){ 29 | this.dataObject = null; 30 | this.type = null; 31 | } 32 | public Class getDefineType(){ 33 | throw new RuntimeException(this.getClass().getName() + "必须实现方法:getDefineType"); 34 | } 35 | public Class getOrgiType(){ 36 | return this.type; 37 | } 38 | public Class getType(InstructionSetContext parent) throws Exception { 39 | if (type != null) 40 | return type; 41 | 42 | Object obj = this.getObject(parent); 43 | if (obj == null) 44 | return null; 45 | else 46 | return obj.getClass(); 47 | } 48 | 49 | public final Object getObject(InstructionSetContext context) throws Exception { 50 | if(this.type != null && this.type.equals(void.class)){ 51 | throw new Exception("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句"); 52 | } 53 | return getObjectInner(context); 54 | } 55 | public Object getObjectInner(InstructionSetContext context) throws Exception{ 56 | return this.dataObject; 57 | } 58 | public void setObject(InstructionSetContext parent, Object object) throws Exception { 59 | throw new RuntimeException("必须在子类中实现此方法"); 60 | } 61 | public String toJavaCode(){ 62 | if(this.getClass().equals(OperateData.class) == false){ 63 | throw new RuntimeException(this.getClass().getName() + "没有实现:toJavaCode()"); 64 | } 65 | String result ="new " + OperateData.class.getName() +"("; 66 | if(String.class.equals(this.type)){ 67 | result = result + "\"" + this.dataObject + "\""; 68 | }else if(this.type.isPrimitive()){ 69 | result = result + this.dataObject.getClass().getName() +".valueOf(\"" + this.dataObject + "\")"; 70 | }else{ 71 | result = result + "new " + this.dataObject.getClass().getName() + "(\"" + this.dataObject.toString() + "\")"; 72 | } 73 | result = result + "," + type.getName() + ".class"; 74 | result = result + ")"; 75 | return result; 76 | } 77 | public String toString() { 78 | if( this.dataObject == null) 79 | return this.type + ":null"; 80 | else{ 81 | if(this.dataObject instanceof Class){ 82 | return ExpressUtil.getClassName((Class)this.dataObject); 83 | }else{ 84 | return this.dataObject.toString(); 85 | } 86 | } 87 | } 88 | public void toResource(StringBuilder builder,int level){ 89 | if(this.dataObject != null){ 90 | builder.append(this.dataObject.toString()); 91 | }else{ 92 | builder.append("null"); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/Operator.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import com.ql.util.express.instruction.OperateDataCacheManager; 4 | import com.ql.util.express.instruction.op.OperatorBase; 5 | 6 | /** 7 | * 操作符的基类 8 | * @author xuannan 9 | * 10 | */ 11 | public abstract class Operator extends OperatorBase{ 12 | 13 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception{ 14 | Object[] parameters = new Object[list.length]; 15 | for(int i = 0;i 37 | * @throws Exception 38 | */ 39 | public static int compareData(Object op1,Object op2) throws Exception{ 40 | int compareResult = -1; 41 | 42 | if(op1 instanceof String){ 43 | compareResult = ((String)op1).compareTo(op2.toString()); 44 | }else if(op2 instanceof String){ 45 | compareResult = op1.toString().compareTo((String)op2); 46 | }else if(op1 instanceof Number && op2 instanceof Number){ 47 | //数字比较 48 | compareResult = OperatorOfNumber.compareNumber((Number)op1, (Number)op2); 49 | } 50 | else if ((op1 instanceof Boolean) && (op2 instanceof Boolean)) 51 | { 52 | if (((Boolean)op1).booleanValue() ==((Boolean)op2).booleanValue()) 53 | compareResult =0; 54 | else 55 | compareResult =-1; 56 | } 57 | else 58 | throw new Exception(op1 + "和" + op2 +"不能执行compare 操作"); 59 | return compareResult; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/Rule.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | /** 4 | * 自定义规则内容
5 | * 6 | * @author wanglei
7 | * @version 1.0
8 | * @taskId
9 | * @CreateDate 2015年1月26日
10 | */ 11 | public class Rule { 12 | private Integer id; 13 | 14 | private String ruleName; 15 | 16 | // 优先级,越大执行优先级越高 17 | private Integer priority; 18 | 19 | private Integer groupType; 20 | 21 | private String groupName; 22 | 23 | // 规则匹配判断条件-表达式 24 | private String matchCondition; 25 | 26 | // 规则匹配执行内容-表达式 27 | private String executeContent; 28 | 29 | public Integer getId() { 30 | return id; 31 | } 32 | 33 | public void setId(Integer id) { 34 | this.id = id; 35 | } 36 | 37 | public String getRuleName() { 38 | return ruleName; 39 | } 40 | 41 | public void setRuleName(String ruleName) { 42 | this.ruleName = ruleName; 43 | } 44 | 45 | public Integer getPriority() { 46 | return priority; 47 | } 48 | 49 | public void setPriority(Integer priority) { 50 | this.priority = priority; 51 | } 52 | 53 | public Integer getGroupType() { 54 | return groupType; 55 | } 56 | 57 | public void setGroupType(Integer groupType) { 58 | this.groupType = groupType; 59 | } 60 | 61 | public String getGroupName() { 62 | return groupName; 63 | } 64 | 65 | public void setGroupName(String groupName) { 66 | this.groupName = groupName; 67 | } 68 | 69 | public String getMatchCondition() { 70 | return matchCondition; 71 | } 72 | 73 | public void setMatchCondition(String matchCondition) { 74 | this.matchCondition = matchCondition; 75 | } 76 | 77 | public String getExecuteContent() { 78 | return executeContent; 79 | } 80 | 81 | public void setExecuteContent(String executeContent) { 82 | this.executeContent = executeContent; 83 | } 84 | 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/RuleContext.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | /** 3 | * 4 | * 规则上下文
5 | * 6 | * @author wanglei
7 | * @version 1.0
8 | * @taskId
9 | * @CreateDate 2015年1月24日
10 | */ 11 | public class RuleContext extends DefaultContext { 12 | /** 13 | * serialVersionUID
14 | */ 15 | private static final long serialVersionUID = 20150124L; 16 | private Integer groupType; 17 | private String groupName; 18 | public Integer getGroupType() { 19 | return groupType; 20 | } 21 | public void setGroupType(Integer groupType) { 22 | this.groupType = groupType; 23 | } 24 | public String getGroupName() { 25 | return groupName; 26 | } 27 | public void setGroupName(String groupName) { 28 | this.groupName = groupName; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/RuleRunner.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import javax.annotation.Resource; 11 | 12 | import com.ql.util.express.dao.RuleMapper; 13 | 14 | /** 15 | * 16 | * 规则调度-执行
17 | * 18 | * @author wanglei
19 | * @version 1.0
20 | * @taskId
21 | * @CreateDate 2015年1月26日
22 | */ 23 | public class RuleRunner{ 24 | //表达式执行器 25 | private ExpressRunner expressRunner = new ExpressRunner(); 26 | //全部规则 27 | private List ruleList; 28 | //各种组别的规则的缓存 29 | private Map> rulesCache = new HashMap>(); 30 | @Resource 31 | private RuleMapper ruleMapper; 32 | /** 33 | * 34 | * Description:规则调度
35 | * 36 | * @author wanglei
37 | * @taskId
38 | * @param ruleList 39 | * @param ruleContext 40 | * @return 41 | * @throws Exception
42 | */ 43 | public boolean dispatch(RuleContext ruleContext) throws Exception { 44 | // 延迟初始化 45 | if(null == ruleList) { 46 | synchronized(this) { 47 | if(null == ruleList) { 48 | ruleList = ruleMapper.getRuleList(); 49 | } 50 | } 51 | } 52 | //如果规则为空,则返回true 53 | if(null == ruleList || 0 ==ruleList.size()) { 54 | return true; 55 | } 56 | //如果规则不为空,且规则上下文为null,返回false 57 | if(null == ruleContext) { 58 | return false; 59 | } 60 | //获取并缓存基于组别的适应的规则 61 | List rules = this.obtainRulesWithCache(ruleContext.getGroupType()); 62 | //匹配并执行匹配的规则 63 | this.executeRules(rules, ruleContext); 64 | return true; 65 | } 66 | 67 | /** 68 | * 69 | * Description:筛选并对规则按照优先级排序
70 | * 71 | * @author wanglei
72 | * @taskId
73 | * @param ruleList 74 | * @param groupType 75 | * @return
76 | */ 77 | private List obtainRulesWithCache(Integer groupType) { 78 | List rules = rulesCache.get(groupType); 79 | if(null == rules) { 80 | rules = new ArrayList(); 81 | //筛选规则 82 | for(Rule rule : ruleList) { 83 | if(groupType == rule.getGroupType()) { 84 | rules.add(rule); 85 | } 86 | } 87 | //按照优先级排序 88 | Collections.sort(rules, new Comparator(){ 89 | @Override 90 | public int compare(Object o1, Object o2) { 91 | Rule rule1 = (Rule)o1; 92 | Rule rule2 = (Rule)o2; 93 | return rule1.getGroupType().compareTo(rule2.getGroupType()); 94 | } 95 | }); 96 | rulesCache.put(groupType, rules); 97 | } 98 | return rules; 99 | } 100 | 101 | /** 102 | * 103 | * Description:规则匹配并执行
104 | * 105 | * @author wanglei
106 | * @taskId
107 | * @param rules 108 | * @param ruleContext 109 | * @throws Exception
110 | */ 111 | private void executeRules(List rules,RuleContext ruleContext) throws Exception { 112 | for(Rule rule : rules) { 113 | //如果规则匹配,则执行 114 | Boolean result = (Boolean)expressRunner.execute(rule.getMatchCondition(), ruleContext, null, true, false); 115 | if(result) { 116 | expressRunner.execute(rule.getExecuteContent(), ruleContext, null, true, false); 117 | } 118 | } 119 | } 120 | 121 | /** 122 | * 123 | * Description:刷新规则内容
124 | * 125 | * @author wanglei
126 | * @taskId

127 | */ 128 | public synchronized void refreshRules() { 129 | ruleList = ruleMapper.getRuleList(); 130 | rulesCache = new HashMap>(); 131 | } 132 | 133 | public List getRuleList() { 134 | return ruleList; 135 | } 136 | 137 | public void setRuleList(List ruleList) { 138 | this.ruleList = ruleList; 139 | } 140 | 141 | public ExpressRunner getExpressRunner() { 142 | return expressRunner; 143 | } 144 | 145 | public void setExpressRunner(ExpressRunner expressRunner) { 146 | this.expressRunner = expressRunner; 147 | } 148 | 149 | public RuleMapper getRuleMapper() { 150 | return ruleMapper; 151 | } 152 | 153 | public void setRuleMapper(RuleMapper ruleMapper) { 154 | this.ruleMapper = ruleMapper; 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/RunEnvironment.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express; 2 | 3 | 4 | 5 | public class RunEnvironment { 6 | private static int INIT_DATA_LENTH = 15; 7 | private boolean isTrace = false; 8 | private int point = -1; 9 | private int programPoint = 0; 10 | private OperateData[] dataContainer; 11 | 12 | private boolean isExit = false; 13 | private Object returnValue = null; 14 | 15 | private InstructionSet instructionSet; 16 | private InstructionSetContext context; 17 | 18 | 19 | public RunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){ 20 | dataContainer = new OperateData[INIT_DATA_LENTH]; 21 | this.instructionSet = aInstructionSet; 22 | this.context = aContext; 23 | this.isTrace = aIsTrace; 24 | } 25 | 26 | public void initial(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){ 27 | dataContainer = new OperateData[INIT_DATA_LENTH]; 28 | this.instructionSet = aInstructionSet; 29 | this.context = aContext; 30 | this.isTrace = aIsTrace; 31 | } 32 | public void clear(){ 33 | isTrace = false; 34 | point = -1; 35 | programPoint = 0; 36 | dataContainer = null; 37 | 38 | isExit = false; 39 | returnValue = null; 40 | 41 | instructionSet = null; 42 | context = null; 43 | 44 | } 45 | public InstructionSet getInstructionSet() { 46 | return instructionSet; 47 | } 48 | 49 | 50 | public InstructionSetContext getContext(){ 51 | return this.context; 52 | } 53 | public void setContext(InstructionSetContext aContext){ 54 | this.context = aContext; 55 | } 56 | 57 | public boolean isExit() { 58 | return isExit; 59 | } 60 | public Object getReturnValue() { 61 | return returnValue; 62 | } 63 | public void setReturnValue(Object value){ 64 | this.returnValue = value; 65 | } 66 | public void quitExpress(Object aReturnValue){ 67 | this.isExit = true; 68 | this.returnValue = aReturnValue; 69 | } 70 | public void quitExpress(){ 71 | this.isExit = true; 72 | this.returnValue = null; 73 | } 74 | public boolean isTrace(){ 75 | return this.isTrace; 76 | } 77 | public int getProgramPoint() { 78 | return programPoint; 79 | } 80 | public void programPointAddOne() { 81 | programPoint ++ ; 82 | } 83 | public int getDataStackSize(){ 84 | return this.point + 1; 85 | } 86 | public void push(OperateData data){ 87 | this.point++; 88 | if(this.point >= this.dataContainer.length){ 89 | ensureCapacity(this.point + 1); 90 | } 91 | this.dataContainer[point] = data; 92 | } 93 | public OperateData peek(){ 94 | if(point <0){ 95 | throw new RuntimeException("系统异常,堆栈指针错误"); 96 | } 97 | return this.dataContainer[point]; 98 | } 99 | public OperateData pop(){ 100 | if(point <0) 101 | throw new RuntimeException("系统异常,堆栈指针错误"); 102 | OperateData result = this.dataContainer[point]; 103 | this.point--; 104 | return result; 105 | } 106 | public void clearDataStack(){ 107 | this.point = -1; 108 | } 109 | public void gotoWithOffset(int aOffset ){ 110 | this.programPoint = this.programPoint + aOffset; 111 | } 112 | /** 113 | * 此方法是调用最频繁的,因此尽量精简代码,提高效率 114 | * @param context 115 | * @param len 116 | * @return 117 | * @throws Exception 118 | */ 119 | public OperateData[] popArray(InstructionSetContext context,int len) throws Exception { 120 | int start = point - len + 1; 121 | OperateData[] result = new OperateData[len]; 122 | System.arraycopy(this.dataContainer,start, result,0, len); 123 | point = point - len; 124 | return result; 125 | } 126 | public OperateData[] popArrayBackUp(InstructionSetContext context,int len) throws Exception { 127 | int start = point - len + 1; 128 | if(start <0){ 129 | throw new Exception("堆栈溢出,请检查表达式是否错误"); 130 | } 131 | OperateData[] result = new OperateData[len]; 132 | for (int i = 0 ; i < len; i++) { 133 | result[i] = this.dataContainer[start + i]; 134 | if(void.class.equals(result[i].getType(context))){ 135 | throw new Exception("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句"); 136 | } 137 | } 138 | point = point - len; 139 | return result; 140 | } 141 | 142 | public void ensureCapacity(int minCapacity) { 143 | int oldCapacity = this.dataContainer.length; 144 | if (minCapacity > oldCapacity) { 145 | int newCapacity = (oldCapacity * 3) / 2 + 1; 146 | if (newCapacity < minCapacity){ 147 | newCapacity = minCapacity; 148 | } 149 | OperateData[] tempList = new OperateData[newCapacity]; 150 | System.arraycopy(this.dataContainer,0,tempList,0,oldCapacity); 151 | this.dataContainer = tempList; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/dao/RuleMapper.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.dao; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.ibatis.annotations.Select; 6 | 7 | import com.ql.util.express.Rule; 8 | /** 9 | * 10 | * 从数据库中获取规则mapper
11 | * 12 | * @author wanglei
13 | * @version 1.0
14 | * @taskId
15 | * @CreateDate 2015年1月26日
16 | */ 17 | public interface RuleMapper { 18 | @Select({"select id,rule_name ruleName,priority,group_type groupType,group_name groupName,match_condition matchCondition,execute_content executeContent from rule where del_flag=0"}) 19 | public List getRuleList(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/BlockInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionClearDataStack; 8 | import com.ql.util.express.instruction.detail.InstructionCloseNewArea; 9 | import com.ql.util.express.instruction.detail.InstructionOpenNewArea; 10 | import com.ql.util.express.parse.ExpressNode; 11 | 12 | public class BlockInstructionFactory extends InstructionFactory { 13 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 14 | Stack forStack, ExpressNode node,boolean isRoot) 15 | throws Exception { 16 | if (node.isTypeEqualsOrChild("STAT_SEMICOLON") 17 | &&result.getCurrentPoint() >=0 && result.getInstruction(result.getCurrentPoint()) instanceof InstructionClearDataStack == false) { 18 | result.addInstruction(new InstructionClearDataStack()); 19 | } 20 | 21 | int tmpPoint = result.getCurrentPoint()+1; 22 | boolean returnVal = false; 23 | boolean hasDef = false; 24 | for(ExpressNode tmpNode : node.getChildren()){ 25 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false); 26 | hasDef = hasDef || tmpHas; 27 | } 28 | if (hasDef == true&& isRoot == false 29 | && node.getTreeType().isEqualsOrChild("STAT_BLOCK")){ 30 | result.insertInstruction(tmpPoint,new InstructionOpenNewArea()); 31 | result.insertInstruction(result.getCurrentPoint() + 1,new InstructionCloseNewArea()); 32 | returnVal = false; 33 | }else{ 34 | returnVal = hasDef; 35 | } 36 | return returnVal; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/BreakInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionGoTo; 8 | import com.ql.util.express.parse.ExpressNode; 9 | 10 | public class BreakInstructionFactory extends InstructionFactory { 11 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 12 | Stack forStack, ExpressNode node,boolean isRoot) 13 | throws Exception { 14 | InstructionGoTo breakInstruction = new InstructionGoTo(result.getCurrentPoint()+1); 15 | breakInstruction.name = "break"; 16 | forStack.peek().breakList.add(breakInstruction); 17 | result.addInstruction(breakInstruction); 18 | return false; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/CallFunctionInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionCallSelfDefineFunction; 8 | import com.ql.util.express.instruction.detail.InstructionOperator; 9 | import com.ql.util.express.instruction.op.OperatorBase; 10 | import com.ql.util.express.parse.ExpressNode; 11 | 12 | 13 | public class CallFunctionInstructionFactory extends InstructionFactory{ 14 | public boolean createInstruction(ExpressRunner aCompile, 15 | InstructionSet result, Stack forStack, 16 | ExpressNode node, boolean isRoot) throws Exception { 17 | ExpressNode[] children = node.getChildren(); 18 | String functionName = children[0].getValue(); 19 | boolean returnVal = false; 20 | children = node.getChildren(); 21 | for (int i = 1; i < children.length; i++) { 22 | boolean tmpHas = aCompile.createInstructionSetPrivate(result, 23 | forStack, children[i], false); 24 | returnVal = returnVal || tmpHas; 25 | } 26 | 27 | OperatorBase op = aCompile.getOperatorFactory().getOperator( 28 | functionName); 29 | int opNum = children.length -1; 30 | if (op != null) { 31 | result.addInstruction(new InstructionOperator(op,opNum )); 32 | } else { 33 | result.addInstruction(new InstructionCallSelfDefineFunction( 34 | functionName,opNum)); 35 | } 36 | return returnVal; 37 | } 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/CastInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionOperator; 8 | import com.ql.util.express.instruction.op.OperatorBase; 9 | import com.ql.util.express.parse.ExpressNode; 10 | 11 | 12 | public class CastInstructionFactory extends InstructionFactory{ 13 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack forStack, ExpressNode node,boolean isRoot) 14 | throws Exception { 15 | boolean returnVal = false; 16 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node); 17 | ExpressNode[] children = node.getChildren(); 18 | if(children.length ==0){ 19 | throw new Exception("扩展类型不存在"); 20 | }else if(children.length > 2) { 21 | throw new Exception("扩展操作只能有一个类型为Class的操作数"); 22 | }else if(children[0].getNodeType().isEqualsOrChild("CONST_CLASS") == false){ 23 | throw new Exception("扩展操作只能有一个类型为Class的操作数,当前的数据类型是:" + children[0].getNodeType().getName()); 24 | } 25 | 26 | for(int i =0;i < children.length;i++){ 27 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,children[i],false); 28 | returnVal = returnVal || tmpHas; 29 | } 30 | result.addInstruction(new InstructionOperator(op,children.length)); 31 | return returnVal; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/ConstDataInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.OperateData; 8 | import com.ql.util.express.instruction.detail.InstructionConstData; 9 | import com.ql.util.express.instruction.opdata.OperateClass; 10 | import com.ql.util.express.parse.ExpressNode; 11 | 12 | public class ConstDataInstructionFactory extends InstructionFactory { 13 | public OperateData genOperateData(ExpressNode node) { 14 | if (node.isTypeEqualsOrChild("CONST_CLASS")) { 15 | return new OperateClass(node.getValue(), (Class) node.getObjectValue()); 16 | } else { 17 | return new OperateData(node.getObjectValue(), node.getObjectValue().getClass()); 18 | } 19 | } 20 | 21 | public boolean createInstruction(ExpressRunner aCompile, 22 | InstructionSet result, Stack forStack, 23 | ExpressNode node, boolean isRoot) throws Exception { 24 | result.addInstruction(new InstructionConstData(genOperateData(node))); 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/ContinueInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionGoTo; 8 | import com.ql.util.express.parse.ExpressNode; 9 | 10 | public class ContinueInstructionFactory extends InstructionFactory { 11 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 12 | Stack forStack, ExpressNode node,boolean isRoot) 13 | throws Exception { 14 | InstructionGoTo continueInstruction = new InstructionGoTo(result.getCurrentPoint()+1); 15 | continueInstruction.name = "continue"; 16 | forStack.peek().continueList.add(continueInstruction); 17 | result.addInstruction(continueInstruction); 18 | return false; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/DefineInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.ExpressUtil; 7 | import com.ql.util.express.InstructionSet; 8 | import com.ql.util.express.instruction.detail.InstructionOperator; 9 | import com.ql.util.express.instruction.op.OperatorBase; 10 | import com.ql.util.express.parse.ExpressNode; 11 | 12 | 13 | class DefineInstructionFactory extends InstructionFactory{ 14 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack forStack, ExpressNode node,boolean isRoot) 15 | throws Exception { 16 | boolean returnVal = false; 17 | ExpressNode[] children = node.getChildren(); 18 | int [] finishPoint = new int[children.length]; 19 | int arrayDimeCount =0; 20 | String tempStr=""; 21 | for(int i = children.length - 2;i>0;i--){ 22 | ExpressNode tmpNode = children[i]; 23 | if(tmpNode.isTypeEqualsOrChild("[]")){ 24 | arrayDimeCount = arrayDimeCount +1; 25 | node.getLeftChildren().remove(i); 26 | tempStr = tempStr +"[]"; 27 | }else{ 28 | throw new Exception("不正确的类型定义"); 29 | } 30 | } 31 | if(arrayDimeCount > 0){ 32 | node.getLeftChildren().get(0).setValue(node.getLeftChildren().get(0).getValue() + tempStr); 33 | node.getLeftChildren().get(0).setOrgiValue(node.getLeftChildren().get(0).getOrgiValue() + tempStr); 34 | Object objValue = node.getLeftChildren().get(0).getObjectValue(); 35 | if(objValue instanceof Class){ 36 | Class tmpClass = ExpressUtil.getJavaClass(ExpressUtil.getClassName((Class)objValue) + tempStr); 37 | node.getLeftChildren().get(0).setObjectValue(tmpClass); 38 | }else{ 39 | node.getLeftChildren().get(0).setObjectValue(node.getLeftChildren().get(0).getObjectValue()+ tempStr); 40 | } 41 | } 42 | 43 | children = node.getChildren(); 44 | for(int i =0;i < children.length;i++){ 45 | ExpressNode tmpNode = children[i]; 46 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false); 47 | returnVal = returnVal || tmpHas; 48 | finishPoint[i] = result.getCurrentPoint(); 49 | } 50 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node); 51 | result.addInstruction(new InstructionOperator(op, children.length)); 52 | returnVal = true; 53 | return returnVal; 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/ForInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionCloseNewArea; 8 | import com.ql.util.express.instruction.detail.InstructionGoTo; 9 | import com.ql.util.express.instruction.detail.InstructionGoToWithCondition; 10 | import com.ql.util.express.instruction.detail.InstructionOpenNewArea; 11 | import com.ql.util.express.parse.ExpressNode; 12 | 13 | public class ForInstructionFactory extends InstructionFactory { 14 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 15 | Stack forStack, ExpressNode node,boolean isRoot) 16 | throws Exception { 17 | if(node.getChildren().length < 2){ 18 | throw new Exception("for 操作符至少需要2个操作数 " ); 19 | }else if(node.getChildren().length > 2){ 20 | throw new Exception("for 操作符最多只有2个操作数 " ); 21 | } 22 | if(node.getChildren()[0].getChildren()!= null && node.getChildren()[0].getChildren().length > 3){ 23 | throw new Exception("循环语句的设置不合适:" + node.getChildren()[0]); 24 | } 25 | //生成作用域开始指令 26 | result.addInstruction(new InstructionOpenNewArea()); 27 | forStack.push(new ForRelBreakContinue()); 28 | 29 | //生成条件语句部分指令 30 | ExpressNode conditionNode = node.getChildren()[0]; 31 | int nodePoint = 0; 32 | if (conditionNode.getChildren() != null && conditionNode.getChildren().length == 3){//变量定义,判断,自增都存在 33 | int tempPoint = result.getCurrentPoint(); 34 | aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[0],false); 35 | if(result.getCurrentPoint() > tempPoint){ 36 | nodePoint = nodePoint + 1; 37 | } 38 | } 39 | //循环的开始的位置 40 | int loopStartPoint = result.getCurrentPoint()+ 1; 41 | 42 | //有条件语句 43 | InstructionGoToWithCondition conditionInstruction=null; 44 | if(conditionNode.getChildren() != null 45 | && (conditionNode.getChildren().length == 1 46 | || conditionNode.getChildren().length == 2 47 | || conditionNode.getChildren().length == 3) 48 | ) { 49 | aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[nodePoint],false); 50 | //跳转的位置需要根据后续的指令情况决定 51 | conditionInstruction = new InstructionGoToWithCondition(false,-1,true); 52 | result.insertInstruction(result.getCurrentPoint()+1,conditionInstruction); 53 | nodePoint = nodePoint+ 1; 54 | } 55 | int conditionPoint = result.getCurrentPoint(); 56 | //生成循环体的代码 57 | aCompile.createInstructionSetPrivate(result,forStack,node.getChildren()[1],false); 58 | 59 | int selfAddPoint = result.getCurrentPoint()+1; 60 | //生成自增代码指令 61 | if(conditionNode.getChildren()!= null &&( 62 | conditionNode.getChildren().length == 2 || conditionNode.getChildren().length == 3 63 | )){ 64 | aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[nodePoint],false); 65 | } 66 | //增加一个无条件跳转 67 | InstructionGoTo reStartGoto = new InstructionGoTo(loopStartPoint - (result.getCurrentPoint() + 1)); 68 | result.addInstruction(reStartGoto); 69 | 70 | //修改条件判断的跳转位置 71 | if(conditionInstruction != null){ 72 | conditionInstruction.setOffset( result.getCurrentPoint() - conditionPoint + 1); 73 | } 74 | 75 | //修改Break和Continue指令的跳转位置,循环出堆 76 | ForRelBreakContinue rel = forStack.pop(); 77 | for(InstructionGoTo item:rel.breakList){ 78 | item.setOffset(result.getCurrentPoint() - item.getOffset()) ; 79 | } 80 | for(InstructionGoTo item:rel.continueList){ 81 | item.setOffset(selfAddPoint - item.getOffset() - 1); 82 | } 83 | 84 | //生成作用域结束指令 85 | result.addInstruction(new InstructionCloseNewArea()); 86 | 87 | return false; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/ForRelBreakContinue.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.ql.util.express.instruction.detail.InstructionGoTo; 7 | 8 | public class ForRelBreakContinue{ 9 | List breakList = new ArrayList(); 10 | List continueList = new ArrayList(); 11 | 12 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/FunctionInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar; 8 | import com.ql.util.express.parse.ExpressNode; 9 | 10 | public class FunctionInstructionFactory extends InstructionFactory { 11 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 12 | Stack forStack, ExpressNode node,boolean isRoot) 13 | throws Exception { 14 | ExpressNode[] children = node.getChildren(); 15 | if(children.length != 3){ 16 | throw new Exception("funciton 操作符需要3个操作数 " ); 17 | } 18 | String functionName =children[0].getValue(); 19 | ExpressNode[] varDefines = children[1].getChildren(); 20 | int point =0; 21 | 22 | String instructionSetType =""; 23 | if (node.isTypeEqualsOrChild("class")) { 24 | instructionSetType = InstructionSet.TYPE_CLASS; 25 | } else { 26 | instructionSetType = InstructionSet.TYPE_FUNCTION; 27 | } 28 | InstructionSet functionSet = new InstructionSet(instructionSetType); 29 | 30 | while(point varClass = (Class)varDefines[point].getChildren()[0].getObjectValue(); 35 | String varName = varDefines[point].getChildren()[1].getValue(); 36 | OperateDataLocalVar tmpVar = new OperateDataLocalVar(varName,varClass); 37 | functionSet.addParameter(tmpVar); 38 | point = point + 1; 39 | } 40 | 41 | ExpressNode functionRoot = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("FUNCTION_DEFINE"),"function-" + functionName); 42 | for(ExpressNode tempNode : children[2].getChildren()){ 43 | functionRoot.addLeftChild(tempNode); 44 | } 45 | aCompile.createInstructionSet(functionRoot,functionSet); 46 | result.addMacroDefine(functionName, new FunctionInstructionSet(functionName,instructionSetType,functionSet)); 47 | return false; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/FunctionInstructionSet.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.io.Serializable; 4 | 5 | import com.ql.util.express.InstructionSet; 6 | 7 | 8 | public class FunctionInstructionSet implements Serializable{ 9 | private static final long serialVersionUID = 8735208809492617401L; 10 | public String name; 11 | public String type; 12 | public InstructionSet instructionSet; 13 | public FunctionInstructionSet(String aName,String aType,InstructionSet aInstructionSet){ 14 | this.name = aName; 15 | this.type = aType; 16 | this.instructionSet = aInstructionSet; 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/IOperateDataCache.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import com.ql.util.express.CallResult; 4 | import com.ql.util.express.ExpressLoader; 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.IExpressContext; 7 | import com.ql.util.express.InstructionSet; 8 | import com.ql.util.express.InstructionSetContext; 9 | import com.ql.util.express.OperateData; 10 | import com.ql.util.express.RunEnvironment; 11 | import com.ql.util.express.instruction.opdata.OperateDataArrayItem; 12 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 13 | import com.ql.util.express.instruction.opdata.OperateDataField; 14 | import com.ql.util.express.instruction.opdata.OperateDataKeyValue; 15 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar; 16 | 17 | interface IOperateDataCache { 18 | public OperateData fetchOperateData(Object obj, Class aType); 19 | public OperateDataAttr fetchOperateDataAttr(String name, Class aType); 20 | public OperateDataLocalVar fetchOperateDataLocalVar(String name, Class aType); 21 | public OperateDataField fetchOperateDataField(Object aFieldObject,String aFieldName); 22 | public OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject,int aIndex); 23 | public OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue); 24 | public RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace); 25 | public CallResult fetchCallResult(Object aReturnValue,boolean aIsExit); 26 | public InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName); 27 | public void resetCache(); 28 | public long getFetchCount(); 29 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/IfInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionGoTo; 8 | import com.ql.util.express.instruction.detail.InstructionGoToWithCondition; 9 | import com.ql.util.express.parse.ExpressNode; 10 | 11 | public class IfInstructionFactory extends InstructionFactory { 12 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 13 | Stack forStack, ExpressNode node,boolean isRoot) 14 | throws Exception { 15 | ExpressNode[] oldChildren = node.getChildren(); 16 | if(oldChildren.length < 2){ 17 | throw new Exception("if 操作符至少需要2个操作数 " ); 18 | }else if(oldChildren.length > 5){ 19 | throw new Exception("if 操作符最多只有5个操作数 " ); 20 | } 21 | ExpressNode[] children = new ExpressNode[3]; 22 | int point = 0; 23 | for(int i=0;i forStack, 15 | ExpressNode node, boolean isRoot) throws Exception { 16 | ExpressNode[] children = node.getChildren(); 17 | if (children[1].isTypeEqualsOrChild("CHILD_EXPRESS")) { 18 | node.getLeftChildren().remove(1); 19 | ExpressNode[] parameterList = children[1].getChildren(); 20 | for (int i = 0; i < parameterList.length; i++) { 21 | node.getLeftChildren().add(parameterList[i]); 22 | } 23 | } 24 | 25 | boolean returnVal = false; 26 | children = node.getChildren(); 27 | for (int i = 0; i < children.length; i++) { 28 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false); 29 | returnVal = returnVal || tmpHas; 30 | } 31 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node); 32 | result.addInstruction(new InstructionOperator(op, children.length)); 33 | return returnVal; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/InstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Stack; 6 | 7 | import com.ql.util.express.ExpressRunner; 8 | import com.ql.util.express.InstructionSet; 9 | import com.ql.util.express.parse.ExpressNode; 10 | 11 | public abstract class InstructionFactory { 12 | private static Map instructionFactory = new HashMap(); 13 | 14 | public static InstructionFactory getInstructionFactory(String factory) { 15 | try { 16 | InstructionFactory result = instructionFactory.get(factory); 17 | if (result == null) { 18 | result = (InstructionFactory) Class.forName(factory) 19 | .newInstance(); 20 | } 21 | return result; 22 | } catch (Exception e) { 23 | throw new RuntimeException(e); 24 | } 25 | } 26 | public abstract boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 27 | Stack forStack, ExpressNode node,boolean isRoot) 28 | throws Exception; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/KeyValueInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionOperator; 8 | import com.ql.util.express.instruction.op.OperatorBase; 9 | import com.ql.util.express.parse.ExpressNode; 10 | 11 | 12 | class KeyValueInstructionFactory extends InstructionFactory{ 13 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack forStack, ExpressNode node,boolean isRoot) 14 | throws Exception { 15 | boolean returnVal = false; 16 | ExpressNode[] children = node.getChildren(); 17 | if( node.getParent() != null && node.getParent().isTypeEqualsOrChild("STATEMENT")){ 18 | children[0].setNodeType(aCompile.getNodeTypeManager().findNodeType("CONST_STRING")); 19 | children[0].setTreeType(aCompile.getNodeTypeManager().findNodeType("CONST")); 20 | children[0].setObjectValue(children[0].getValue()); 21 | } 22 | if( node.getParent() != null && node.getParent().isTypeEqualsOrChild("STATEMENT") && children[1].isTypeEqualsOrChild("STAT_BLOCK")){ 23 | returnVal = new MacroInstructionFactory().createInstruction(aCompile, result, forStack, node, isRoot); 24 | } else if (node.getParent() != null&& node.getParent().isTypeEqualsOrChild("STATEMENT")) { 25 | for(int i =0;i < children.length;i++){ 26 | ExpressNode tmpNode = children[i]; 27 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false); 28 | returnVal = returnVal || tmpHas; 29 | } 30 | OperatorBase op = aCompile.getOperatorFactory().newInstance("alias"); 31 | result.addInstruction(new InstructionOperator(op, children.length)); 32 | returnVal = true; 33 | }else{ 34 | for(int i =0;i < children.length;i++){ 35 | ExpressNode tmpNode = children[i]; 36 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false); 37 | returnVal = returnVal || tmpHas; 38 | } 39 | 40 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node); 41 | result.addInstruction(new InstructionOperator(op,children.length)); 42 | } 43 | return returnVal; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/LoadAttrInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionCallMacro; 8 | import com.ql.util.express.instruction.detail.InstructionLoadAttr; 9 | import com.ql.util.express.parse.ExpressNode; 10 | 11 | 12 | public class LoadAttrInstructionFactory extends InstructionFactory { 13 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 14 | Stack forStack, ExpressNode node,boolean isRoot) 15 | throws Exception{ 16 | FunctionInstructionSet functionSet = result.getMacroDefine(node.getValue()); 17 | if(functionSet != null){//是宏定义 18 | result.insertInstruction(result.getCurrentPoint()+1, new InstructionCallMacro(node.getValue())); 19 | }else{ 20 | result.addInstruction(new InstructionLoadAttr(node.getValue())); 21 | if(node.getChildren().length >0){ 22 | throw new Exception("表达式设置错误"); 23 | } 24 | } 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/MacroInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.parse.ExpressNode; 8 | 9 | public class MacroInstructionFactory extends InstructionFactory { 10 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 11 | Stack forStack, ExpressNode node,boolean isRoot) 12 | throws Exception { 13 | ExpressNode[] children = node.getChildren(); 14 | String macroName =children[0].getValue(); 15 | ExpressNode macroRoot = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("FUNCTION_DEFINE"),"macro-" + macroName); 16 | for(ExpressNode tempNode : children[1].getChildren()){ 17 | macroRoot.addLeftChild(tempNode); 18 | } 19 | InstructionSet macroInstructionSet = aCompile.createInstructionSet(macroRoot,InstructionSet.TYPE_MARCO); 20 | result.addMacroDefine(macroName, new FunctionInstructionSet(macroName,"macro",macroInstructionSet)); 21 | return false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/MethodCallInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionOperator; 8 | import com.ql.util.express.instruction.op.OperatorBase; 9 | import com.ql.util.express.parse.ExpressNode; 10 | 11 | 12 | public class MethodCallInstructionFactory extends InstructionFactory { 13 | public boolean createInstruction(ExpressRunner aCompile, 14 | InstructionSet result, Stack forStack, 15 | ExpressNode node, boolean isRoot) throws Exception { 16 | boolean returnVal = false; 17 | ExpressNode[] children = node.getChildren(); 18 | for (int i = 0; i < children.length; i++) { 19 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false); 20 | returnVal = returnVal || tmpHas; 21 | } 22 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node); 23 | result.addInstruction(new InstructionOperator(op, children.length)); 24 | return returnVal; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/NewInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.ExpressUtil; 7 | import com.ql.util.express.InstructionSet; 8 | import com.ql.util.express.instruction.detail.InstructionOperator; 9 | import com.ql.util.express.instruction.op.OperatorBase; 10 | import com.ql.util.express.parse.ExpressNode; 11 | 12 | 13 | public class NewInstructionFactory extends InstructionFactory{ 14 | public boolean createInstruction(ExpressRunner aCompile, 15 | InstructionSet result, Stack forStack, 16 | ExpressNode node, boolean isRoot) throws Exception { 17 | OperatorBase op = aCompile.getOperatorFactory().newInstance("new"); 18 | ExpressNode[] children = node.getChildren(); 19 | if (node.isTypeEqualsOrChild("NEW_ARRAY")) { 20 | String tempStr = children[0].getValue(); 21 | for (int i = 0; i < children.length - 1; i++) { 22 | tempStr = tempStr + "[]"; 23 | } 24 | children[0].setValue(tempStr); 25 | children[0].setOrgiValue(tempStr); 26 | children[0].setObjectValue(ExpressUtil.getJavaClass(tempStr)); 27 | }else if (node.isTypeEqualsOrChild("anonymousNewArray")) { 28 | op = aCompile.getOperatorFactory().newInstance("anonymousNewArray"); 29 | } 30 | 31 | boolean returnVal = false; 32 | children = node.getChildren();// 需要重新获取数据 33 | for (int i = 0; i < children.length; i++) { 34 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false); 35 | returnVal = returnVal || tmpHas; 36 | } 37 | result.addInstruction(new InstructionOperator(op, children.length)); 38 | return returnVal; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/NewVClassInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.instruction.detail.InstructionNewVirClass; 8 | import com.ql.util.express.parse.ExpressNode; 9 | 10 | 11 | public class NewVClassInstructionFactory extends InstructionFactory{ 12 | public boolean createInstruction(ExpressRunner aCompile, 13 | InstructionSet result, Stack forStack, 14 | ExpressNode node, boolean isRoot) throws Exception { 15 | ExpressNode[] children = node.getChildren(); 16 | boolean returnVal = false; 17 | String virClassName = children[0].getValue(); 18 | for (int i = 1; i < children.length; i++) { 19 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false); 20 | returnVal = returnVal || tmpHas; 21 | } 22 | result.addInstruction(new InstructionNewVirClass(virClassName, children.length -1)); 23 | return returnVal; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/NullInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.InstructionSet; 7 | import com.ql.util.express.parse.ExpressNode; 8 | 9 | public class NullInstructionFactory extends InstructionFactory { 10 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result, 11 | Stack forStack, ExpressNode node,boolean isRoot) 12 | throws Exception { 13 | return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/OperateDataCacheImpl4Orig.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import com.ql.util.express.CallResult; 4 | import com.ql.util.express.ExpressLoader; 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.IExpressContext; 7 | import com.ql.util.express.InstructionSet; 8 | import com.ql.util.express.InstructionSetContext; 9 | import com.ql.util.express.OperateData; 10 | import com.ql.util.express.RunEnvironment; 11 | import com.ql.util.express.instruction.opdata.OperateDataArrayItem; 12 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 13 | import com.ql.util.express.instruction.opdata.OperateDataField; 14 | import com.ql.util.express.instruction.opdata.OperateDataKeyValue; 15 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar; 16 | 17 | 18 | class OperateDataCacheImpl4Orig implements IOperateDataCache { 19 | 20 | public OperateData fetchOperateData(Object obj, Class aType) { 21 | return new OperateData(obj,aType); 22 | } 23 | public OperateDataAttr fetchOperateDataAttr(String name, Class aType) { 24 | return new OperateDataAttr(name, aType); 25 | } 26 | public OperateDataLocalVar fetchOperateDataLocalVar(String name, Class aType) { 27 | return new OperateDataLocalVar(name, aType); 28 | } 29 | public OperateDataField fetchOperateDataField(Object aFieldObject,String aFieldName){ 30 | return new OperateDataField(aFieldObject, aFieldName); 31 | } 32 | public OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject,int aIndex){ 33 | return new OperateDataArrayItem(aArrayObject, aIndex); 34 | } 35 | public OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue){ 36 | return new OperateDataKeyValue(aKey, aValue); 37 | } 38 | 39 | public RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){ 40 | return new RunEnvironment(aInstructionSet, aContext, aIsTrace); 41 | } 42 | public CallResult fetchCallResult(Object aReturnValue,boolean aIsExit){ 43 | return new CallResult(aReturnValue, aIsExit); 44 | } 45 | public InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){ 46 | return new InstructionSetContext(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName); 47 | } 48 | 49 | public void resetCache(){ 50 | 51 | } 52 | public long getFetchCount(){ 53 | return 0; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/OperateDataCacheManager.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import com.ql.util.express.CallResult; 4 | import com.ql.util.express.ExpressLoader; 5 | import com.ql.util.express.ExpressRunner; 6 | import com.ql.util.express.IExpressContext; 7 | import com.ql.util.express.InstructionSet; 8 | import com.ql.util.express.InstructionSetContext; 9 | import com.ql.util.express.OperateData; 10 | import com.ql.util.express.RunEnvironment; 11 | import com.ql.util.express.instruction.opdata.OperateDataArrayItem; 12 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 13 | import com.ql.util.express.instruction.opdata.OperateDataField; 14 | import com.ql.util.express.instruction.opdata.OperateDataKeyValue; 15 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar; 16 | 17 | 18 | public class OperateDataCacheManager { 19 | 20 | private static ThreadLocal m_OperateDataObjectCache = new ThreadLocal(){ 21 | protected IOperateDataCache initialValue() { 22 | return new OperateDataCacheImpl(30); 23 | //return new OperateDataCacheImpl4Orig(); 24 | } 25 | }; 26 | public static IOperateDataCache getOperateDataCache(){ 27 | return m_OperateDataObjectCache.get(); 28 | } 29 | public static OperateData fetchOperateData(Object obj, Class aType) { 30 | return getOperateDataCache().fetchOperateData(obj, aType); 31 | } 32 | public static OperateDataAttr fetchOperateDataAttr(String name, Class aType) { 33 | return getOperateDataCache().fetchOperateDataAttr(name, aType); 34 | } 35 | public static OperateDataLocalVar fetchOperateDataLocalVar(String name, Class aType) { 36 | return getOperateDataCache().fetchOperateDataLocalVar(name, aType); 37 | } 38 | public static OperateDataField fetchOperateDataField(Object aFieldObject,String aFieldName){ 39 | return getOperateDataCache().fetchOperateDataField(aFieldObject, aFieldName); 40 | } 41 | public static OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject,int aIndex){ 42 | return getOperateDataCache().fetchOperateDataArrayItem(aArrayObject, aIndex); 43 | } 44 | public static OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue){ 45 | return getOperateDataCache().fetchOperateDataKeyValue(aKey, aValue); 46 | } 47 | 48 | public static RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){ 49 | return getOperateDataCache().fetRunEnvironment(aInstructionSet, aContext, aIsTrace); 50 | } 51 | public static CallResult fetchCallResult(Object aReturnValue,boolean aIsExit){ 52 | return getOperateDataCache().fetchCallResult(aReturnValue, aIsExit); 53 | } 54 | public static InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){ 55 | return getOperateDataCache().fetchInstructionSetContext(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName); 56 | } 57 | 58 | public static long getFetchCount(){ 59 | return getOperateDataCache().getFetchCount(); 60 | } 61 | 62 | public static void resetCache(){ 63 | getOperateDataCache().resetCache(); 64 | } 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/OperatorInstructionFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction; 2 | 3 | import java.util.Stack; 4 | 5 | import com.ql.util.express.ExportItem; 6 | import com.ql.util.express.ExpressRunner; 7 | import com.ql.util.express.InstructionSet; 8 | import com.ql.util.express.instruction.detail.InstructionGoToWithCondition; 9 | import com.ql.util.express.instruction.detail.InstructionGoToWithNotNull; 10 | import com.ql.util.express.instruction.detail.InstructionOperator; 11 | import com.ql.util.express.instruction.detail.InstructionReturn; 12 | import com.ql.util.express.instruction.op.OperatorBase; 13 | import com.ql.util.express.parse.ExpressNode; 14 | 15 | 16 | class OperatorInstructionFactory extends InstructionFactory{ 17 | public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack forStack, ExpressNode node,boolean isRoot) 18 | throws Exception { 19 | boolean returnVal = false; 20 | ExpressNode[] children = node.getChildren(); 21 | int [] finishPoint = new int[children.length]; 22 | for(int i =0;i < children.length;i++){ 23 | ExpressNode tmpNode = children[i]; 24 | boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false); 25 | returnVal = returnVal || tmpHas; 26 | finishPoint[i] = result.getCurrentPoint(); 27 | } 28 | 29 | if(node.isTypeEqualsOrChild("return")){ 30 | result.addInstruction(new InstructionReturn(children.length > 0)); 31 | }else{ 32 | OperatorBase op = aCompile.getOperatorFactory().newInstance(node); 33 | result.addInstruction(new InstructionOperator(op,children.length)); 34 | if(node.isTypeEqualsOrChild("&&") && aCompile.isShortCircuit()){ 35 | result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithCondition(false,result.getCurrentPoint() - finishPoint[0] + 1,false)); 36 | }else if(node.isTypeEqualsOrChild("||") && aCompile.isShortCircuit()){ 37 | result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithCondition(true,result.getCurrentPoint() - finishPoint[0] + 1,false)); 38 | }else if(node.isTypeEqualsOrChild("nor") ){ 39 | result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithNotNull(result.getCurrentPoint() - finishPoint[0] + 1,false)); 40 | }else if(node.isTypeEqualsOrChild("def") || node.isTypeEqualsOrChild("alias")){ 41 | returnVal = true; 42 | }else if(node.isTypeEqualsOrChild("exportDef")){ 43 | //添加对外的变量声明 44 | result.addExportDef(new ExportItem(children[1].toString(),ExportItem.TYPE_DEF,"还没有实现")); 45 | }else if(node.isTypeEqualsOrChild("exportAlias")){ 46 | result.addExportDef(new ExportItem(children[0].toString(),ExportItem.TYPE_ALIAS,"还没有实现")); 47 | } 48 | } 49 | return returnVal; 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/Instruction.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.logging.Log; 6 | import org.apache.commons.logging.LogFactory; 7 | 8 | import com.ql.util.express.RunEnvironment; 9 | 10 | 11 | public abstract class Instruction implements java.io.Serializable { 12 | 13 | private static final long serialVersionUID = 1361458333068300443L; 14 | protected static transient Log staticLog = LogFactory.getLog(Instruction.class); 15 | protected static transient Log log = staticLog; 16 | public void setLog(Log aLog) { 17 | if (aLog != null) { 18 | this.log = aLog; 19 | } 20 | } 21 | public abstract void execute(RunEnvironment environment, List errorList) 22 | throws Exception; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionCallMacro.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.InstructionSet; 6 | import com.ql.util.express.InstructionSetRunner; 7 | import com.ql.util.express.OperateData; 8 | import com.ql.util.express.RunEnvironment; 9 | import com.ql.util.express.instruction.OperateDataCacheManager; 10 | 11 | 12 | public class InstructionCallMacro extends Instruction{ 13 | private static final long serialVersionUID = -5760553701305043649L; 14 | String name; 15 | public InstructionCallMacro(String aName){ 16 | this.name = aName; 17 | } 18 | 19 | public void execute(RunEnvironment environment,List errorList)throws Exception{ 20 | if(environment.isTrace()&&log.isDebugEnabled()){ 21 | log.debug(this); 22 | } 23 | Object functionSet = environment.getContext().getSymbol(this.name); 24 | 25 | Object result =InstructionSetRunner.execute( 26 | environment.getContext().getExpressRunner(), 27 | new InstructionSet[]{(InstructionSet)functionSet}, 28 | environment.getContext().getExpressLoader(), 29 | environment.getContext(), 30 | errorList, 31 | environment.isTrace(), 32 | false,false,this.log, 33 | environment.getContext().isSupportDynamicFieldName()); 34 | if(result instanceof OperateData){ 35 | environment.push((OperateData)result); 36 | }else{ 37 | environment.push(OperateDataCacheManager.fetchOperateData(result,null)); 38 | } 39 | 40 | environment.programPointAddOne(); 41 | } 42 | public String toString(){ 43 | return "call macro " + this.name ; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionCallSelfDefineFunction.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.logging.Log; 6 | 7 | import com.ql.util.express.InstructionSet; 8 | import com.ql.util.express.InstructionSetContext; 9 | import com.ql.util.express.InstructionSetRunner; 10 | import com.ql.util.express.OperateData; 11 | import com.ql.util.express.RunEnvironment; 12 | import com.ql.util.express.instruction.OperateDataCacheManager; 13 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 14 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar; 15 | 16 | public class InstructionCallSelfDefineFunction extends Instruction{ 17 | private static final long serialVersionUID = 8315682251443515151L; 18 | String functionName; 19 | int opDataNumber; 20 | public InstructionCallSelfDefineFunction(String name,int aOpDataNumber){ 21 | this.functionName = name; 22 | this.opDataNumber =aOpDataNumber; 23 | } 24 | 25 | public void execute(RunEnvironment environment, List errorList) 26 | throws Exception { 27 | OperateData[] parameters = environment.popArray( 28 | environment.getContext(), this.opDataNumber); 29 | if (environment.isTrace() && log.isDebugEnabled()) { 30 | String str = this.functionName + "("; 31 | for (int i = 0; i < parameters.length; i++) { 32 | if (i > 0) { 33 | str = str + ","; 34 | } 35 | if (parameters[i] instanceof OperateDataAttr) { 36 | str = str 37 | + parameters[i] 38 | + ":" 39 | + parameters[i].getObject(environment 40 | .getContext()); 41 | } else { 42 | str = str + parameters[i]; 43 | } 44 | } 45 | str = str + ")"; 46 | log.debug(str); 47 | } 48 | 49 | Object function = environment.getContext().getSymbol(functionName); 50 | if (function == null || function instanceof InstructionSet == false) { 51 | throw new Exception("在Runner的操作符定义和自定义函数中都没有找到\"" 52 | + this.functionName + "\"的定义"); 53 | } 54 | InstructionSet functionSet = (InstructionSet)function; 55 | OperateData result = InstructionCallSelfDefineFunction 56 | .executeSelfFunction(environment, functionSet, parameters, 57 | errorList, this.log); 58 | environment.push(result); 59 | environment.programPointAddOne(); 60 | } 61 | public static OperateData executeSelfFunction(RunEnvironment environment,InstructionSet functionSet, 62 | OperateData[] parameters,List errorList,Log log)throws Exception{ 63 | InstructionSetContext context = OperateDataCacheManager.fetchInstructionSetContext ( 64 | true,environment.getContext().getExpressRunner(),environment.getContext(),environment.getContext().getExpressLoader(),environment.getContext().isSupportDynamicFieldName()); 65 | OperateDataLocalVar[] vars = functionSet.getParameters(); 66 | for(int i=0;i errorList)throws Exception{ 11 | //目前的模式,不需要执行任何操作 12 | if(environment.isTrace() && log.isDebugEnabled()){ 13 | log.debug(this); 14 | } 15 | environment.clearDataStack(); 16 | environment.programPointAddOne(); 17 | } 18 | public String toString(){ 19 | return "clearDataStack"; 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionCloseNewArea.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.InstructionSetContext; 6 | import com.ql.util.express.RunEnvironment; 7 | 8 | public class InstructionCloseNewArea extends Instruction{ 9 | private static final long serialVersionUID = -996832248972683705L; 10 | public void execute(RunEnvironment environment,List errorList)throws Exception{ 11 | //目前的模式,不需要执行任何操作 12 | if(environment.isTrace() && log.isDebugEnabled()){ 13 | log.debug(this); 14 | } 15 | environment.setContext((InstructionSetContext )environment.getContext().getParent()); 16 | environment.programPointAddOne(); 17 | } 18 | public String toString(){ 19 | return "closeNewArea"; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionConstData.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.OperateData; 6 | import com.ql.util.express.RunEnvironment; 7 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 8 | 9 | public class InstructionConstData extends Instruction { 10 | private static final long serialVersionUID = 745531116947232321L; 11 | OperateData operateData; 12 | 13 | public InstructionConstData(OperateData data) { 14 | this.operateData = data; 15 | } 16 | public OperateData getOperateData(){ 17 | return this.operateData; 18 | } 19 | public void execute(RunEnvironment environment, List errorList) 20 | throws Exception { 21 | if (environment.isTrace() && log.isDebugEnabled()) { 22 | if (this.operateData instanceof OperateDataAttr) { 23 | log.debug(this + ":" 24 | + this.operateData.getObject(environment.getContext())); 25 | } else { 26 | log.debug(this); 27 | } 28 | } 29 | environment.push(this.operateData); 30 | environment.programPointAddOne(); 31 | } 32 | public String toString() { 33 | if (this.operateData instanceof OperateDataAttr) { 34 | return "LoadData attr:" + this.operateData.toString(); 35 | } else { 36 | return "LoadData " + this.operateData.toString(); 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionGoTo.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.RunEnvironment; 6 | 7 | public class InstructionGoTo extends Instruction{ 8 | private static final long serialVersionUID = 198094562177756098L; 9 | /** 10 | * 跳转指令的偏移量 11 | */ 12 | int offset; 13 | public String name; 14 | 15 | public InstructionGoTo(int aOffset){ 16 | this.offset = aOffset; 17 | } 18 | 19 | public void execute(RunEnvironment environment,List errorList) throws Exception { 20 | if(environment.isTrace() && log.isDebugEnabled() ){ 21 | log.debug(this); 22 | } 23 | environment.gotoWithOffset(this.offset); 24 | } 25 | public String toString(){ 26 | String result = (this.name ==null?"":this.name +":") + "GoTo "; 27 | if(this.offset >=0){ 28 | result = result +"+"; 29 | } 30 | result = result + this.offset + " "; 31 | return result; 32 | } 33 | 34 | public int getOffset() { 35 | return offset; 36 | } 37 | 38 | public void setOffset(int offset) { 39 | this.offset = offset; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionGoToWithCondition.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.OperateData; 6 | import com.ql.util.express.RunEnvironment; 7 | import com.ql.util.express.instruction.OperateDataCacheManager; 8 | 9 | public class InstructionGoToWithCondition extends Instruction{ 10 | private static final long serialVersionUID = -4817805156872407837L; 11 | /** 12 | * 跳转指令的偏移量 13 | */ 14 | int offset; 15 | boolean condition; 16 | boolean isPopStackData; 17 | public InstructionGoToWithCondition(boolean aCondition,int aOffset,boolean aIsPopStackData){ 18 | this.offset = aOffset; 19 | this.condition = aCondition; 20 | this.isPopStackData = aIsPopStackData; 21 | } 22 | 23 | public void execute(RunEnvironment environment,List errorList)throws Exception{ 24 | Object o = null; 25 | if(this.isPopStackData == false){ 26 | o = environment.peek().getObject(environment.getContext()); 27 | if(o == null){ 28 | environment.pop(); 29 | environment.push(OperateDataCacheManager.fetchOperateData(false,boolean.class)); 30 | } 31 | }else{ 32 | o = environment.pop().getObject(environment.getContext()); 33 | } 34 | boolean r = false; 35 | if(o == null){ 36 | r = false; 37 | }else if(o instanceof Boolean){ 38 | r = ((Boolean)o).booleanValue(); 39 | }else{ 40 | throw new Exception("指令错误:" + o + " 不是Boolean"); 41 | } 42 | if (r == this.condition) { 43 | if (environment.isTrace() && log.isDebugEnabled()) { 44 | log.debug("goto +" + this.offset); 45 | } 46 | environment.gotoWithOffset(this.offset); 47 | } else { 48 | if (environment.isTrace() && log.isDebugEnabled()) { 49 | log.debug("programPoint ++ "); 50 | } 51 | environment.programPointAddOne(); 52 | } 53 | } 54 | 55 | 56 | public String toString(){ 57 | String result = "GoToIf[" + this.condition +",isPop=" + this.isPopStackData +"] " ; 58 | if(this.offset >=0){ 59 | result = result +"+"; 60 | } 61 | result = result + this.offset; 62 | return result; 63 | } 64 | 65 | public int getOffset() { 66 | return offset; 67 | } 68 | 69 | public void setOffset(int offset) { 70 | this.offset = offset; 71 | } 72 | 73 | public boolean isCondition() { 74 | return condition; 75 | } 76 | 77 | public void setCondition(boolean condition) { 78 | this.condition = condition; 79 | } 80 | 81 | public boolean isPopStackData() { 82 | return isPopStackData; 83 | } 84 | 85 | public void setPopStackData(boolean isPopStackData) { 86 | this.isPopStackData = isPopStackData; 87 | } 88 | 89 | 90 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionGoToWithNotNull.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.RunEnvironment; 6 | 7 | public class InstructionGoToWithNotNull extends Instruction{ 8 | private static final long serialVersionUID = -2314675800146495935L; 9 | /** 10 | * 跳转指令的偏移量 11 | */ 12 | int offset; 13 | boolean isPopStackData; 14 | public InstructionGoToWithNotNull(int aOffset,boolean aIsPopStackData){ 15 | this.offset = aOffset; 16 | this.isPopStackData = aIsPopStackData; 17 | } 18 | 19 | public void execute(RunEnvironment environment,List errorList)throws Exception{ 20 | Object o = null; 21 | if(this.isPopStackData == false){ 22 | o = environment.peek().getObject(environment.getContext()); 23 | }else{ 24 | o = environment.pop().getObject(environment.getContext()); 25 | } 26 | if (o != null) { 27 | if (environment.isTrace() && log.isDebugEnabled()) { 28 | log.debug("goto +" + this.offset); 29 | } 30 | environment.gotoWithOffset(this.offset); 31 | } else { 32 | if (environment.isTrace() && log.isDebugEnabled()) { 33 | log.debug("programPoint ++ "); 34 | } 35 | environment.programPointAddOne(); 36 | } 37 | } 38 | 39 | 40 | public String toString(){ 41 | String result = "GoToIf[NOTNULL,isPop=" + this.isPopStackData +"] " ; 42 | if(this.offset >=0){ 43 | result = result +"+"; 44 | } 45 | result = result + this.offset; 46 | return result; 47 | } 48 | 49 | public int getOffset() { 50 | return offset; 51 | } 52 | 53 | public void setOffset(int offset) { 54 | this.offset = offset; 55 | } 56 | 57 | public boolean isPopStackData() { 58 | return isPopStackData; 59 | } 60 | 61 | public void setPopStackData(boolean isPopStackData) { 62 | this.isPopStackData = isPopStackData; 63 | } 64 | 65 | 66 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionLoadAttr.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.InstructionSet; 6 | import com.ql.util.express.RunEnvironment; 7 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 8 | 9 | public class InstructionLoadAttr extends Instruction{ 10 | private static final long serialVersionUID = -2761666977949467250L; 11 | String attrName; 12 | public InstructionLoadAttr(String aName){ 13 | this.attrName = aName; 14 | } 15 | public String getAttrName(){ 16 | return this.attrName; 17 | } 18 | public void execute(RunEnvironment environment,List errorList)throws Exception{ 19 | Object o = environment.getContext().getSymbol(this.attrName); 20 | if(o != null && o instanceof InstructionSet){//是函数,则执行 21 | if(environment.isTrace() && log.isDebugEnabled()){ 22 | log.debug("指令转换: LoadAttr -- >CallMacro "); 23 | } 24 | InstructionCallMacro macro = new InstructionCallMacro(this.attrName); 25 | macro.setLog(this.log); 26 | macro.execute(environment, errorList); 27 | //注意,此处不能在增加指令,因为在InstructionCallMacro已经调用 environment.programPointAddOne(); 28 | }else{ 29 | if(environment.isTrace() && log.isDebugEnabled()){ 30 | log.debug(this +":" + ((OperateDataAttr)o).getObject(environment.getContext())); 31 | } 32 | environment.push((OperateDataAttr)o); 33 | environment.programPointAddOne(); 34 | } 35 | } 36 | 37 | public String toString(){ 38 | return "LoadAttr:" +this.attrName; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionNewVirClass.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.OperateData; 6 | import com.ql.util.express.RunEnvironment; 7 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 8 | import com.ql.util.express.instruction.opdata.OperateDataVirClass; 9 | 10 | public class InstructionNewVirClass extends Instruction { 11 | private static final long serialVersionUID = -4174411242319009814L; 12 | String className; 13 | int opDataNumber; 14 | 15 | public InstructionNewVirClass(String name, int aOpDataNumber) { 16 | this.className = name; 17 | this.opDataNumber = aOpDataNumber; 18 | } 19 | 20 | public void execute(RunEnvironment environment, List errorList) 21 | throws Exception { 22 | OperateData[] parameters = environment.popArray( 23 | environment.getContext(), this.opDataNumber); 24 | if (environment.isTrace() && log.isDebugEnabled()) { 25 | String str = "new VClass("; 26 | for (int i = 0; i < parameters.length; i++) { 27 | if (i > 0) { 28 | str = str + ","; 29 | } 30 | if (parameters[i] instanceof OperateDataAttr) { 31 | str = str + parameters[i] + ":" 32 | + parameters[i].getObject(environment.getContext()); 33 | } else { 34 | str = str + parameters[i]; 35 | } 36 | } 37 | str = str + ")"; 38 | log.debug(str); 39 | } 40 | OperateDataVirClass result = new OperateDataVirClass(className); 41 | environment.push(result); 42 | environment.programPointAddOne(); 43 | result.initialInstance(environment.getContext(), parameters, errorList, 44 | environment.isTrace(), this.log); 45 | } 46 | 47 | public String toString() { 48 | return "new VClass[" + this.className + "] OPNUMBER[" 49 | + this.opDataNumber + "]"; 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionOpenNewArea.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.InstructionSetContext; 6 | import com.ql.util.express.RunEnvironment; 7 | import com.ql.util.express.instruction.OperateDataCacheManager; 8 | 9 | public class InstructionOpenNewArea extends Instruction{ 10 | private static final long serialVersionUID = -118527079334123637L; 11 | public void execute(RunEnvironment environment,List errorList)throws Exception{ 12 | //目前的模式,不需要执行任何操作 13 | if(environment.isTrace() && log.isDebugEnabled()){ 14 | log.debug(this); 15 | } 16 | InstructionSetContext parentContext = environment.getContext(); 17 | environment.setContext(OperateDataCacheManager.fetchInstructionSetContext ( 18 | true, 19 | parentContext.getExpressRunner(), 20 | parentContext, 21 | parentContext.getExpressLoader(), 22 | parentContext.isSupportDynamicFieldName())); 23 | environment.programPointAddOne(); 24 | } 25 | public String toString(){ 26 | return "openNewArea"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionOperator.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.logging.Log; 6 | 7 | import com.ql.util.express.OperateData; 8 | import com.ql.util.express.RunEnvironment; 9 | import com.ql.util.express.instruction.op.OperatorBase; 10 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 11 | 12 | public class InstructionOperator extends Instruction{ 13 | private static final long serialVersionUID = -1217916524030161947L; 14 | OperatorBase operator; 15 | int opDataNumber; 16 | public InstructionOperator(OperatorBase aOperator,int aOpDataNumber){ 17 | this.operator = aOperator; 18 | this.opDataNumber =aOpDataNumber; 19 | } 20 | public OperatorBase getOperator(){ 21 | return this.operator; 22 | } 23 | public void execute(RunEnvironment environment,List errorList) throws Exception{ 24 | execute(this.operator,this.opDataNumber, environment, errorList, this.log); 25 | } 26 | public static void execute(OperatorBase aOperator,int aOpNum,RunEnvironment environment,List errorList,Log log) throws Exception{ 27 | OperateData[] parameters = environment.popArray(environment.getContext(),aOpNum); 28 | if(environment.isTrace() && log.isDebugEnabled()){ 29 | String str = aOperator.toString() + "("; 30 | for(int i=0;i 0){ 32 | str = str + ","; 33 | } 34 | if(parameters[i] instanceof OperateDataAttr){ 35 | str = str + parameters[i] + ":" + parameters[i].getObject(environment.getContext()); 36 | }else{ 37 | str = str + parameters[i]; 38 | } 39 | } 40 | str = str + ")"; 41 | log.debug(str); 42 | } 43 | 44 | OperateData result = aOperator.execute(environment.getContext(),parameters, errorList); 45 | environment.push(result); 46 | environment.programPointAddOne(); 47 | } 48 | public String toString(){ 49 | String result = "OP : " + this.operator.toString() + " OPNUMBER[" + this.opDataNumber +"]"; 50 | return result; 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/detail/InstructionReturn.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.detail; 2 | 3 | import java.util.List; 4 | 5 | import com.ql.util.express.RunEnvironment; 6 | 7 | public class InstructionReturn extends Instruction{ 8 | private static final long serialVersionUID = -4991998239277488949L; 9 | boolean haveReturnValue; 10 | public InstructionReturn(boolean aHaveReturnValue){ 11 | this.haveReturnValue = aHaveReturnValue; 12 | } 13 | public void execute(RunEnvironment environment,List errorList)throws Exception{ 14 | //目前的模式,不需要执行任何操作 15 | if(environment.isTrace() && log.isDebugEnabled()){ 16 | log.debug(this); 17 | } 18 | if(this.haveReturnValue == true){ 19 | environment.quitExpress(environment.pop().getObject(environment.getContext())); 20 | }else{ 21 | environment.quitExpress(); 22 | } 23 | environment.programPointAddOne(); 24 | } 25 | public String toString(){ 26 | if(this.haveReturnValue){ 27 | return "return [value]"; 28 | }else{ 29 | return "return"; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/CanClone.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | public interface CanClone { 4 | public OperatorBase cloneMe(String name,String errorInfo) throws Exception; 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorAddReduce.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | import com.ql.util.express.OperatorOfNumber; 5 | 6 | public class OperatorAddReduce extends Operator { 7 | public OperatorAddReduce(String name) { 8 | this.name = name; 9 | } 10 | public OperatorAddReduce(String aAliasName, String aName, String aErrorInfo) { 11 | this.name = aName; 12 | this.aliasName = aAliasName; 13 | this.errorInfo = aErrorInfo; 14 | } 15 | public Object executeInner(Object[] list) throws Exception { 16 | return executeInner(list[0], list[1]); 17 | } 18 | 19 | public Object executeInner(Object op1, 20 | Object op2) throws Exception { 21 | Object obj = null; 22 | if (this.getName().equals("+")) { 23 | obj = OperatorOfNumber.add(op1, op2,this.isPrecise); 24 | } else if (this.getName().equals("-")) { 25 | obj = OperatorOfNumber.subtract(op1, op2,this.isPrecise); 26 | } 27 | return obj; 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorAlias.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | import com.ql.util.express.OperateData; 5 | import com.ql.util.express.instruction.opdata.OperateDataAlias; 6 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 7 | 8 | public class OperatorAlias extends OperatorBase { 9 | public OperatorAlias(String aName) { 10 | this.name = aName; 11 | } 12 | public OperatorAlias(String aAliasName, String aName, String aErrorInfo) { 13 | this.name = aName; 14 | this.aliasName = aAliasName; 15 | this.errorInfo = aErrorInfo; 16 | } 17 | 18 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception { 19 | String varName = (String)list[0].getObjectInner(context); 20 | OperateDataAttr realAttr = (OperateDataAttr)list[1]; 21 | OperateDataAttr result = new OperateDataAlias(varName,realAttr); 22 | context.addSymbol(varName, result); 23 | return result; 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorAnd.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | 5 | /** 6 | * 处理 And,Or,&&,||操作 7 | */ 8 | 9 | public class OperatorAnd extends Operator { 10 | public OperatorAnd(String name) { 11 | this.name = name; 12 | } 13 | public OperatorAnd(String aAliasName, String aName, String aErrorInfo) { 14 | this.name = aName; 15 | this.aliasName = aAliasName; 16 | this.errorInfo = aErrorInfo; 17 | } 18 | public Object executeInner(Object[] list) throws Exception { 19 | return executeInner(list[0], list[1]); 20 | } 21 | 22 | public Object executeInner(Object op1, 23 | Object op2) throws Exception { 24 | 25 | Object o1 = op1; 26 | Object o2 = op2; 27 | boolean r1 = false; 28 | boolean r2= false; 29 | if(o1 == null){ 30 | r1 = false; 31 | }else if(o1 instanceof Boolean){ 32 | r1 = ((Boolean) o1).booleanValue(); 33 | }else{ 34 | String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作"; 35 | throw new Exception(msg); 36 | } 37 | if(o2 == null){ 38 | r2 = false; 39 | }else if(o2 instanceof Boolean){ 40 | r2 = ((Boolean) o2).booleanValue(); 41 | }else{ 42 | String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作"; 43 | throw new Exception(msg); 44 | } 45 | boolean result = r1 && r2; 46 | return Boolean.valueOf(result); 47 | 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorAnonymousNewArray.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import java.lang.reflect.Array; 4 | 5 | import com.ql.util.express.ExpressUtil; 6 | import com.ql.util.express.InstructionSetContext; 7 | import com.ql.util.express.OperateData; 8 | import com.ql.util.express.instruction.OperateDataCacheManager; 9 | 10 | public class OperatorAnonymousNewArray extends OperatorBase { 11 | public OperatorAnonymousNewArray(String aName) { 12 | this.name = aName; 13 | } 14 | public OperatorAnonymousNewArray(String aAliasName, String aName, String aErrorInfo) { 15 | this.name = aName; 16 | this.aliasName = aAliasName; 17 | this.errorInfo = aErrorInfo; 18 | } 19 | 20 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception { 21 | Class type = Object.class; 22 | if(list.length >0){ 23 | type = list[0].getType(context); 24 | } 25 | type = ExpressUtil.getSimpleDataType(type); 26 | int[] dims = new int[1]; 27 | dims[0]= list.length; 28 | Object data = Array.newInstance(type,dims); 29 | for(int i=0;i result = new ArrayList(); 22 | for(int i=0;i result = new HashMap(); 23 | for(int i=0;i tmpClass = (Class) list[0].getObject(parent); 15 | Object castObj = ExpressUtil.castObject(list[1].getObject(parent), tmpClass,true); 16 | OperateData result = OperateDataCacheManager.fetchOperateData(castObj,tmpClass); 17 | return result; 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorDef.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | import com.ql.util.express.OperateData; 5 | import com.ql.util.express.instruction.OperateDataCacheManager; 6 | import com.ql.util.express.instruction.opdata.OperateDataLocalVar; 7 | import com.ql.util.express.instruction.opdata.OperateDataVirClass; 8 | 9 | public class OperatorDef extends OperatorBase { 10 | public OperatorDef(String aName) { 11 | this.name = aName; 12 | } 13 | public OperatorDef(String aAliasName, String aName, String aErrorInfo) { 14 | this.name = aName; 15 | this.aliasName = aAliasName; 16 | this.errorInfo = aErrorInfo; 17 | } 18 | 19 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception { 20 | Object type = list[0].getObject(context); 21 | String varName = (String)list[1].getObject(context); 22 | Class tmpClass = null; 23 | if(type instanceof Class ){ 24 | tmpClass = (Class) type; 25 | }else{ 26 | tmpClass = OperateDataVirClass.class; 27 | } 28 | OperateDataLocalVar result = OperateDataCacheManager.fetchOperateDataLocalVar(varName,tmpClass); 29 | context.addSymbol(varName, result); 30 | return result; 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorDoubleAddReduce.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.ExpressUtil; 4 | import com.ql.util.express.InstructionSetContext; 5 | import com.ql.util.express.OperateData; 6 | import com.ql.util.express.OperatorOfNumber; 7 | import com.ql.util.express.instruction.OperateDataCacheManager; 8 | 9 | public class OperatorDoubleAddReduce extends OperatorBase { 10 | public OperatorDoubleAddReduce(String name) { 11 | this.name = name; 12 | } 13 | 14 | public OperateData executeInner(InstructionSetContext parent, 15 | OperateData[] list) throws Exception { 16 | Object obj = list[0].getObject(parent); 17 | Object result = null; 18 | if (this.getName().equals("++")) { 19 | result = OperatorOfNumber.add(obj, 1,this.isPrecise); 20 | } else if (this.getName().equals("--")) { 21 | result = OperatorOfNumber.subtract(obj, 1,this.isPrecise); 22 | } 23 | ((OperateData)list[0]).setObject(parent, result); 24 | 25 | if(result == null){ 26 | return OperateDataCacheManager.fetchOperateData(null,null); 27 | }else{ 28 | return OperateDataCacheManager.fetchOperateData(result,ExpressUtil.getSimpleDataType(result.getClass())); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorEqualsLessMore.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | 5 | /** 6 | * 处理 =,==,>,>=,<,<=,!=,<> 7 | */ 8 | public class OperatorEqualsLessMore extends Operator { 9 | public OperatorEqualsLessMore(String aName) { 10 | this.name = aName; 11 | } 12 | 13 | public OperatorEqualsLessMore(String aAliasName, String aName, 14 | String aErrorInfo) { 15 | this.name = aName; 16 | this.aliasName = aAliasName; 17 | this.errorInfo = aErrorInfo; 18 | } 19 | 20 | public Object executeInner(Object[] list) throws Exception { 21 | return executeInner(list[0], list[1]); 22 | } 23 | 24 | public Object executeInner(Object op1,Object op2) throws Exception { 25 | boolean result = executeInner(this.name, op1, op2); 26 | return result; 27 | } 28 | 29 | public static boolean executeInner(String opStr, Object obj1, Object obj2) 30 | throws Exception { 31 | 32 | if (obj1 == null && obj2 == null) { 33 | if (opStr.equals("==")) { 34 | return true; 35 | } else if (opStr.equals("!=") || opStr.equals("<>")) { 36 | return false; 37 | } else { 38 | throw new Exception("两个空操作数不能执行这个操作:" + opStr); 39 | } 40 | } else if (obj1 == null || obj2 == null) { 41 | if (opStr.equals("==")) { 42 | return false; 43 | } else if (opStr.equals("!=") || opStr.equals("<>")) { 44 | return true; 45 | } else { 46 | throw new Exception("空操作数不能执行这个操作:" + opStr); 47 | } 48 | } 49 | 50 | int i = Operator.compareData(obj1, obj2); 51 | boolean result = false; 52 | if (i > 0) { 53 | if (opStr.equals(">") || opStr.equals(">=") || opStr.equals("!=") 54 | || opStr.equals("<>")) 55 | result = true; 56 | else 57 | result = false; 58 | } else if (i == 0) { 59 | if (opStr.equals("=") || opStr.equals("==") || opStr.equals(">=") 60 | || opStr.equals("<=")) 61 | result = true; 62 | else 63 | result = false; 64 | } else if (i < 0) { 65 | if (opStr.equals("<") || opStr.equals("<=") || opStr.equals("!=") 66 | || opStr.equals("<>")) 67 | result = true; 68 | else 69 | result = false; 70 | } 71 | return result; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorEvaluate.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.ExpressUtil; 4 | import com.ql.util.express.InstructionSetContext; 5 | import com.ql.util.express.OperateData; 6 | 7 | public class OperatorEvaluate extends OperatorBase { 8 | public OperatorEvaluate(String name) { 9 | this.name = name; 10 | } 11 | public OperatorEvaluate(String aAliasName, String aName, String aErrorInfo) { 12 | this.name = aName; 13 | this.aliasName = aAliasName; 14 | this.errorInfo = aErrorInfo; 15 | } 16 | public OperateData executeInner(InstructionSetContext parent, OperateData[] list) throws Exception { 17 | return executeInner(parent, list[0], list[1]); 18 | } 19 | 20 | public OperateData executeInner(InstructionSetContext parent, 21 | OperateData op1, OperateData op2) throws Exception { 22 | Class targetType = op1.getDefineType(); 23 | Class sourceType = op2.getType(parent); 24 | if (targetType != null) { 25 | if (ExpressUtil.isAssignable(targetType, sourceType) == false) { 26 | throw new Exception("赋值时候,类型转换错误:" 27 | + ExpressUtil.getClassName(sourceType) + " 不能转换为 " 28 | + ExpressUtil.getClassName(targetType)); 29 | } 30 | 31 | } 32 | Object result = op2.getObject(parent); 33 | if(targetType != null){ 34 | result = ExpressUtil.castObject(result,targetType,false); 35 | } 36 | op1.setObject(parent,result); 37 | return op1; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorExportAlias.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | import com.ql.util.express.OperateData; 5 | import com.ql.util.express.instruction.opdata.OperateDataAlias; 6 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 7 | 8 | public class OperatorExportAlias extends OperatorBase { 9 | public OperatorExportAlias(String aName) { 10 | this.name = aName; 11 | } 12 | public OperatorExportAlias(String aAliasName, String aName, String aErrorInfo) { 13 | this.name = aName; 14 | this.aliasName = aAliasName; 15 | this.errorInfo = aErrorInfo; 16 | } 17 | 18 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception { 19 | String varName = (String)list[0].getObjectInner(context); 20 | OperateDataAttr realAttr = (OperateDataAttr)list[1]; 21 | OperateDataAttr result = new OperateDataAlias(varName,realAttr); 22 | context.exportSymbol(varName, result); 23 | return result; 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorExportDef.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | import com.ql.util.express.OperateData; 5 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 6 | 7 | public class OperatorExportDef extends OperatorBase { 8 | public OperatorExportDef(String aName) { 9 | this.name = aName; 10 | } 11 | public OperatorExportDef(String aAliasName, String aName, String aErrorInfo) { 12 | this.name = aName; 13 | this.aliasName = aAliasName; 14 | this.errorInfo = aErrorInfo; 15 | } 16 | 17 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception { 18 | Class tmpClass = (Class) list[0].getObject(context); 19 | String varName = (String)list[1].getObject(context); 20 | //OperateDataLocalVar result = new OperateDataLocalVar(varName,tmpClass); 21 | //context.exportSymbol(varName, result); 22 | OperateDataAttr result = (OperateDataAttr)context.getSymbol(varName); 23 | result.setDefineType(tmpClass); 24 | return result; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorFactory.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import com.ql.util.express.parse.ExpressNode; 8 | 9 | public class OperatorFactory { 10 | 11 | /** 12 | * 是否需要高精度计算 13 | */ 14 | protected boolean isPrecise = false; 15 | private Map operator = new HashMap(); 16 | 17 | public OperatorFactory(boolean aIsPrecise){ 18 | this.isPrecise = aIsPrecise; 19 | addOperator("new",new OperatorNew("new")); 20 | addOperator("anonymousNewArray",new OperatorAnonymousNewArray("anonymousNewArray")); 21 | addOperator("NewList",new OperatorAnonymousNewList("NewList")); 22 | addOperator(":",new OperatorKeyValue(":")); 23 | addOperator("NewMap",new OperatorAnonymousNewMap("NewMap")); 24 | addOperator("def", new OperatorDef("def")); 25 | addOperator("exportDef", new OperatorExportDef("exportDef")); 26 | addOperator("!",new OperatorNot("!")); 27 | addOperator("*", new OperatorMultiDiv("*")); 28 | addOperator("/", new OperatorMultiDiv("/")); 29 | addOperator("%", new OperatorMultiDiv("%")); 30 | addOperator("mod", new OperatorMultiDiv("mod")); 31 | addOperator("+",new OperatorAddReduce("+")); 32 | addOperator("-",new OperatorAddReduce("-")); 33 | addOperator("<",new OperatorEqualsLessMore("<")); 34 | addOperator(">",new OperatorEqualsLessMore(">")); 35 | addOperator("<=",new OperatorEqualsLessMore("<=")); 36 | addOperator(">=",new OperatorEqualsLessMore(">=")); 37 | addOperator("==",new OperatorEqualsLessMore("==")); 38 | addOperator("!=",new OperatorEqualsLessMore("!=")); 39 | addOperator("<>",new OperatorEqualsLessMore("<>")); 40 | addOperator("&&",new OperatorAnd("&&")); 41 | addOperator("||",new OperatorOr("||")); 42 | addOperator("nor",new OperatorNor("nor")); 43 | addOperator("=",new OperatorEvaluate("=")); 44 | addOperator("exportAlias",new OperatorExportAlias("exportAlias")); 45 | addOperator("alias",new OperatorAlias("alias")); 46 | addOperator("break",new OperatorBreak("break")); 47 | addOperator("continue",new OperatorContinue("continue")); 48 | addOperator("return",new OperatorReturn("return")); 49 | addOperator("METHOD_CALL",new OperatorMethod()); 50 | addOperator("FIELD_CALL",new OperatorField()); 51 | addOperator("ARRAY_CALL",new OperatorArray("ARRAY_CALL")); 52 | addOperator("++",new OperatorDoubleAddReduce("++")); 53 | addOperator("--",new OperatorDoubleAddReduce("--")); 54 | addOperator("cast", new OperatorCast("cast")); 55 | addOperator("macro",new OperatorMacro("macro")); 56 | addOperator("function",new OperatorFunction("function")); 57 | addOperator("in", new OperatorIn("in")); 58 | addOperator("like", new OperatorLike("like")); 59 | } 60 | public void addOperator(String name, OperatorBase op) { 61 | OperatorBase oldOp = this.operator.get(name); 62 | if (oldOp != null) { 63 | throw new RuntimeException("重复定义操作符:" + name + "定义1:" 64 | + oldOp.getClass() + " 定义2:" + op.getClass()); 65 | } 66 | op.setPrecise(this.isPrecise); 67 | op.setAliasName(name); 68 | operator.put(name, op); 69 | } 70 | public OperatorBase replaceOperator(String name, OperatorBase op){ 71 | OperatorBase old = this.operator.remove(name); 72 | this.addOperator(name, op); 73 | return old; 74 | } 75 | 76 | @SuppressWarnings("unchecked") 77 | public void addOperatorWithAlias(String aAliasName,String name,String errorInfo) throws Exception{ 78 | if (this.operator.containsKey(name) == false){ 79 | throw new Exception(name + " 不是系统级别的操作符号,不能设置别名"); 80 | }else{ 81 | OperatorBase orgiOperator = this.operator.get(name); 82 | if(orgiOperator == null){ 83 | throw new Exception(name + " 不能被设置别名"); 84 | } 85 | OperatorBase destOperator = null; 86 | if (orgiOperator instanceof CanClone) { 87 | destOperator = ((CanClone)orgiOperator).cloneMe(aAliasName, errorInfo); 88 | } else { 89 | Class opClass = (Class) orgiOperator.getClass(); 90 | Constructor constructor = null; 91 | try { 92 | constructor = (Constructor) opClass 93 | .getConstructor(String.class, String.class,String.class); 94 | } catch (Exception e) { 95 | throw new Exception(name + " 不能被设置别名:" + e.getMessage()); 96 | } 97 | if (constructor == null) { 98 | throw new Exception(name + " 不能被设置别名"); 99 | } 100 | destOperator = constructor.newInstance(aAliasName, name,errorInfo); 101 | } 102 | if(this.operator.containsKey(aAliasName)){ 103 | throw new RuntimeException("操作符号:\"" + aAliasName + "\" 已经存在"); 104 | } 105 | this.addOperator(aAliasName,destOperator); 106 | } 107 | } 108 | public boolean isExistOperator(String operName) throws Exception { 109 | return operator.containsKey(operName); 110 | } 111 | public OperatorBase getOperator(String aOperName){ 112 | return this.operator.get(aOperName); 113 | } 114 | 115 | /** 116 | * 创建一个新的操作符实例 117 | */ 118 | public OperatorBase newInstance(ExpressNode opItem) throws Exception { 119 | OperatorBase op = operator.get(opItem.getNodeType().getName()); 120 | if (op == null) { 121 | op = operator.get(opItem.getTreeType().getName()); 122 | } 123 | if(op == null){ 124 | op = operator.get(opItem.getValue()); 125 | } 126 | if (op == null) 127 | throw new Exception("没有为\"" + opItem.getValue() + "\"定义操作符处理对象"); 128 | return op; 129 | } 130 | public OperatorBase newInstance(String opName) throws Exception { 131 | OperatorBase op = operator.get(opName); 132 | if (op == null){ 133 | throw new Exception("没有为\"" + opName + "\"定义操作符处理对象"); 134 | } 135 | return op; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorField.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | import com.ql.util.express.OperateData; 5 | import com.ql.util.express.instruction.OperateDataCacheManager; 6 | import com.ql.util.express.instruction.opdata.OperateDataField; 7 | 8 | public class OperatorField extends OperatorBase { 9 | 10 | public OperatorField() { 11 | this.name = "FieldCall"; 12 | } 13 | 14 | public OperateData executeInner(InstructionSetContext parent, OperateData[] list) throws Exception { 15 | Object obj = list[0].getObject(parent); 16 | String fieldName = list[1].getObject(parent).toString(); 17 | return OperateDataCacheManager.fetchOperateDataField(obj,fieldName); 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorIf.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | import com.ql.util.express.OperateData; 5 | 6 | public class OperatorIf extends OperatorBase { 7 | public OperatorIf(String aName) { 8 | this.name = aName; 9 | } 10 | 11 | public OperatorIf(String aAliasName, String aName, String aErrorInfo) { 12 | this.name = aName; 13 | this.aliasName = aAliasName; 14 | this.errorInfo = aErrorInfo; 15 | } 16 | 17 | public OperateData executeInner(InstructionSetContext parent, OperateData[] list) throws Exception { 18 | if(list.length <2){ 19 | throw new Exception("\"" + this.aliasName + "\"操作至少要两个操作数"); 20 | } 21 | Object obj = list[0].getObject(parent); 22 | if (obj == null) { 23 | String msg ="\"" + this.aliasName + "\"的判断条件不能为空"; 24 | throw new Exception(msg); 25 | } else if ((obj instanceof Boolean) == false) { 26 | String msg = "\"" + this.aliasName + "\"的判断条件 必须是 Boolean,不能是:"; 27 | throw new Exception(msg + obj.getClass().getName()); 28 | } else { 29 | if (((Boolean)obj).booleanValue() == true){ 30 | return list[1]; 31 | }else{ 32 | if(list.length == 3){ 33 | return list[2]; 34 | } 35 | } 36 | return null; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorIn.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import java.lang.reflect.Array; 4 | import java.util.List; 5 | 6 | import com.ql.util.express.Operator; 7 | 8 | public class OperatorIn extends Operator { 9 | public OperatorIn(String aName) { 10 | this.name = aName; 11 | } 12 | 13 | public OperatorIn(String aAliasName, String aName, String aErrorInfo) { 14 | this.name = aName; 15 | this.aliasName = aAliasName; 16 | this.errorInfo = aErrorInfo; 17 | } 18 | 19 | public Object executeInner(Object[] list) throws Exception { 20 | Object obj = list[0]; 21 | if (obj == null) { 22 | // 对象为空,不能执行方法 23 | String msg = "对象为空,不能执行方法:"; 24 | throw new Exception(msg + this.name); 25 | } else if (((obj instanceof Number) || (obj instanceof String)) == false) { 26 | String msg = "对象类型不匹配,只有数字和字符串类型才才能执行 in 操作,当前数据类型是:"; 27 | throw new Exception(msg + obj.getClass().getName()); 28 | } else if(list.length == 2 && (list[1].getClass().isArray() || list[1] instanceof List)){ 29 | if(obj.equals(list[1]) == true){ 30 | return true; 31 | }else if(list[1].getClass().isArray()){ 32 | int len = Array.getLength(list[1]); 33 | for(int i=0;i array = (List)list[1]; 42 | for(int i=0;i= 0) { 25 | String[] list = split(s2, "%"); 26 | int index = 0; 27 | for (int i = 0; i < list.length; i++) { 28 | if (index >= s1.length()) { 29 | result = false; 30 | break; 31 | } 32 | index = s1.indexOf(list[i], index); 33 | if (index < 0) { 34 | result = false; 35 | break; 36 | } 37 | index = index + 1; 38 | } 39 | } else if (s1.equals(s2)) 40 | result = true; 41 | else 42 | result = false; 43 | 44 | return Boolean.valueOf(result); 45 | } 46 | 47 | public String[] split(String str, String s) { 48 | int start = 0; 49 | int end = -1; 50 | String tmpStr = ""; 51 | ArrayList list = new ArrayList(); 52 | do { 53 | end = str.indexOf(s, start); 54 | if (end < 0) 55 | tmpStr = str.substring(start); 56 | else 57 | tmpStr = str.substring(start, end); 58 | if (tmpStr.length() > 0) 59 | list.add(tmpStr); 60 | start = end + 1; 61 | if (start >= str.length()) 62 | break; 63 | } while (end >= 0); 64 | return (String[]) list.toArray(new String[0]); 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorMacro.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | import com.ql.util.express.OperateData; 5 | import com.ql.util.express.instruction.opdata.OperateDataAlias; 6 | import com.ql.util.express.instruction.opdata.OperateDataAttr; 7 | 8 | public class OperatorMacro extends OperatorBase { 9 | public OperatorMacro(String aName) { 10 | this.name = aName; 11 | } 12 | public OperatorMacro(String aAliasName, String aName, String aErrorInfo) { 13 | this.name = aName; 14 | this.aliasName = aAliasName; 15 | this.errorInfo = aErrorInfo; 16 | } 17 | 18 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws Exception { 19 | String varName = (String)list[0].getObjectInner(context); 20 | OperateDataAttr realAttr = (OperateDataAttr)list[1]; 21 | OperateDataAttr result = new OperateDataAlias(varName,realAttr); 22 | context.addSymbol(varName, result); 23 | return result; 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorMethod.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import com.ql.util.express.ExpressUtil; 6 | import com.ql.util.express.InstructionSetContext; 7 | import com.ql.util.express.OperateData; 8 | import com.ql.util.express.instruction.OperateDataCacheManager; 9 | import com.ql.util.express.instruction.opdata.OperateClass; 10 | import com.ql.util.express.instruction.opdata.OperateDataVirClass; 11 | 12 | public class OperatorMethod extends OperatorBase { 13 | public OperatorMethod() { 14 | this.name ="MethodCall"; 15 | } 16 | 17 | static Class ArrayClass = (new Object[]{}).getClass(); 18 | 19 | public OperateData executeInner(InstructionSetContext parent, OperateData[] list) throws Exception { 20 | 21 | Object obj = list[0].getObject(parent); 22 | if(obj instanceof OperateDataVirClass ){ 23 | OperateDataVirClass vClass = (OperateDataVirClass)obj; 24 | String methodName = list[1].getObject(parent).toString(); 25 | OperateData[] parameters = new OperateData[list.length - 2]; 26 | for(int i=0;i< list.length -2;i++){ 27 | parameters[i] =list[i+2]; 28 | } 29 | return vClass.callSelfFunction(methodName, parameters); 30 | } 31 | 32 | String methodName = list[1].getObject(parent).toString(); 33 | if (obj == null) { 34 | // 对象为空,不能执行方法 35 | String msg = "对象为空,不能执行方法:"; 36 | throw new Exception(msg + methodName); 37 | } else { 38 | Class[] types = new Class[list.length - 2]; 39 | Class[] orgiTypes = new Class[list.length - 2]; 40 | 41 | Object[] objs = new Object[list.length - 2]; 42 | Object tmpObj; 43 | for (int i = 0; i < types.length; i++) { 44 | tmpObj = list[i + 2].getObject(parent); 45 | types[i] = list[i + 2].getType(parent); 46 | orgiTypes[i] = list[i + 2].getType(parent); 47 | objs[i] = tmpObj; 48 | } 49 | Method m = null; 50 | if (list[0] instanceof OperateClass) {// 调用静态方法 51 | m = ExpressUtil.findMethodWithCache((Class) obj, methodName, 52 | types, true, true); 53 | } else { 54 | m = ExpressUtil.findMethodWithCache(obj.getClass(), methodName, 55 | types, true, false); 56 | } 57 | if(m == null){ 58 | types = new Class[]{ArrayClass}; 59 | if (list[0] instanceof OperateClass) {// 调用静态方法 60 | m = ExpressUtil.findMethodWithCache((Class) obj, methodName, 61 | types, true, true); 62 | } else { 63 | m = ExpressUtil.findMethodWithCache(obj.getClass(), methodName, 64 | types, true, false); 65 | } 66 | objs = new Object[]{objs}; 67 | } 68 | if (m == null) { 69 | StringBuilder s = new StringBuilder(); 70 | s.append("没有找到" + obj.getClass().getName() + "的方法:" 71 | + methodName + "("); 72 | for (int i = 0; i < orgiTypes.length; i++) { 73 | if (i > 0) 74 | s.append(","); 75 | if(orgiTypes[i] == null){ 76 | s.append("null"); 77 | }else{ 78 | s.append(orgiTypes[i].getName()); 79 | } 80 | } 81 | s.append(")"); 82 | throw new Exception(s.toString()); 83 | } 84 | 85 | if (list[0] instanceof OperateClass) {// 调用静态方法 86 | boolean oldA = m.isAccessible(); 87 | m.setAccessible(true); 88 | tmpObj = m.invoke(null,ExpressUtil.transferArray(objs,m.getParameterTypes())); 89 | m.setAccessible(oldA); 90 | } else { 91 | boolean oldA = m.isAccessible(); 92 | m.setAccessible(true); 93 | tmpObj = m.invoke(obj, ExpressUtil.transferArray(objs,m.getParameterTypes())); 94 | m.setAccessible(oldA); 95 | } 96 | return OperateDataCacheManager.fetchOperateData(tmpObj, m.getReturnType()); 97 | } 98 | } 99 | public String toString(){ 100 | return this.name; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorMinMax.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | 5 | public class OperatorMinMax extends Operator { 6 | public OperatorMinMax(String name) { 7 | this.name = name; 8 | } 9 | 10 | public Object executeInner(Object[] list) throws Exception { 11 | if (list.length == 0){ 12 | throw new Exception("操作数异常"); 13 | } 14 | Object result = list[0]; 15 | 16 | for (int i = 1; i < list.length; i++) 17 | result = executeInner(result, list[i]); 18 | return result; 19 | } 20 | 21 | public Object executeInner(Object op1, 22 | Object op2) throws Exception { 23 | Object result = null; 24 | int compareResult = Operator.compareData(op1,op2); 25 | if (this.name.equals("min")) { 26 | if (compareResult < 0) 27 | result = op1; 28 | else 29 | result = op2; 30 | } else if (this.name.equals("max")) { 31 | if (compareResult < 0) 32 | result = op2; 33 | else 34 | result = op1; 35 | } 36 | return result; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorMultiDiv.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | import com.ql.util.express.OperatorOfNumber; 5 | 6 | public class OperatorMultiDiv extends Operator { 7 | public OperatorMultiDiv(String name) { 8 | this.name = name; 9 | } 10 | 11 | public Object executeInner(Object[] list) throws Exception { 12 | return executeInner( list[0], list[1]); 13 | } 14 | 15 | public Object executeInner(Object op1, 16 | Object op2) throws Exception { 17 | Object obj = null; 18 | if (this.getName().equals("*")) 19 | obj = OperatorOfNumber.multiply(op1, op2,this.isPrecise); 20 | else if (this.getName().equals("/")) 21 | obj = OperatorOfNumber.divide(op1, op2,this.isPrecise); 22 | else if (this.getName().equals("%")) 23 | obj = OperatorOfNumber.modulo(op1, op2); 24 | else if (this.getName().equals("mod")) 25 | obj = OperatorOfNumber.modulo(op1, op2); 26 | 27 | return obj; 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorNew.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import java.lang.reflect.Array; 4 | import java.lang.reflect.Constructor; 5 | 6 | import com.ql.util.express.ExpressUtil; 7 | import com.ql.util.express.InstructionSetContext; 8 | import com.ql.util.express.OperateData; 9 | import com.ql.util.express.instruction.OperateDataCacheManager; 10 | 11 | public class OperatorNew extends OperatorBase { 12 | public OperatorNew(String aName) { 13 | this.name = aName; 14 | } 15 | 16 | public OperateData executeInner(InstructionSetContext parent, OperateData[] list) throws Exception { 17 | Class obj = (Class) list[0].getObject(parent); 18 | if (obj.isArray()) { 19 | Class tmpClass = obj; 20 | int dim = 0; 21 | while (tmpClass.isArray()) { 22 | tmpClass = tmpClass.getComponentType(); 23 | dim = dim + 1; 24 | } 25 | int[] dimLength = new int[dim]; 26 | for (int index = 0; index < dim; index++) { 27 | dimLength[index] = ((Number) (list[index + 1].getObject(parent))) 28 | .intValue(); 29 | } 30 | return OperateDataCacheManager.fetchOperateData(Array.newInstance(tmpClass, dimLength), obj); 31 | } 32 | Class[] types = new Class[list.length - 1]; 33 | Object[] objs = new Object[list.length - 1]; 34 | Object tmpObj; 35 | for (int i = 0; i < types.length; i++) { 36 | tmpObj = list[i + 1].getObject(parent); 37 | types[i] = list[i + 1].getType(parent); 38 | objs[i] = tmpObj; 39 | } 40 | Constructor c = ExpressUtil.findConstructor(obj, types); 41 | 42 | if (c == null) { 43 | // "没有找到" + obj.getName() + "的构造方法:" 44 | StringBuilder s = new StringBuilder(); 45 | s.append("没有找到" + obj.getName() + "的构造方法:" + obj.getName() + "("); 46 | for (int i = 0; i < types.length; i++) { 47 | if (i > 0){ 48 | s.append(","); 49 | } 50 | s.append(types[i].getName()); 51 | } 52 | s.append(")"); 53 | throw new Exception(s.toString()); 54 | } 55 | 56 | tmpObj = c.newInstance(objs); 57 | return OperateDataCacheManager.fetchOperateData(tmpObj, obj); 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorNor.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | 5 | public class OperatorNor extends Operator { 6 | public OperatorNor(String name) { 7 | this.name = name; 8 | } 9 | 10 | public OperatorNor(String aAliasName, String aName, String aErrorInfo) { 11 | this.name = aName; 12 | this.aliasName = aAliasName; 13 | this.errorInfo = aErrorInfo; 14 | } 15 | 16 | public Object executeInner(Object[] list) throws Exception { 17 | return executeInner(list[0], list[1]); 18 | } 19 | 20 | public Object executeInner(Object op1, Object op2) throws Exception { 21 | 22 | if (op1 != null) { 23 | return op1; 24 | } else { 25 | return op2; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorNot.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | 5 | public class OperatorNot extends Operator { 6 | public OperatorNot(String name) { 7 | this.name = name; 8 | } 9 | public OperatorNot(String aAliasName, String aName, String aErrorInfo) { 10 | this.name = aName; 11 | this.aliasName = aAliasName; 12 | this.errorInfo = aErrorInfo; 13 | } 14 | public Object executeInner(Object[] list) throws Exception { 15 | return executeInner(list[0]); 16 | } 17 | 18 | public Object executeInner(Object op) 19 | throws Exception { 20 | Object result = null; 21 | if (op == null){ 22 | throw new Exception("null 不能执行操作:" + this.getAliasName()); 23 | } 24 | if (Boolean.class.equals(op.getClass()) == true) { 25 | boolean r = !((Boolean) op).booleanValue(); 26 | result = Boolean.valueOf(r); 27 | } else { 28 | // 29 | String msg = "没有定义类型" + op.getClass().getName() + " 的 " + this.name 30 | + "操作"; 31 | throw new Exception(msg); 32 | } 33 | return result; 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorNullOp.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.IExpressContext; 4 | import com.ql.util.express.InstructionSetContext; 5 | import com.ql.util.express.OperateData; 6 | 7 | 8 | /** 9 | * 处理 ",","(",")",";" 10 | */ 11 | 12 | public class OperatorNullOp extends OperatorBase { 13 | public OperatorNullOp(String name) { 14 | this.name = name; 15 | } 16 | public OperatorNullOp(String aAliasName, String aName, String aErrorInfo) { 17 | this.name = aName; 18 | this.aliasName = aAliasName; 19 | this.errorInfo = aErrorInfo; 20 | } 21 | public OperateData executeInner(InstructionSetContext parent, OperateData[] list) throws Exception { 22 | return executeInner(parent); 23 | } 24 | 25 | public OperateData executeInner(IExpressContext parent) throws Exception { 26 | return null; 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorOr.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | 5 | public class OperatorOr extends Operator { 6 | public OperatorOr(String name) { 7 | this.name = name; 8 | } 9 | public OperatorOr(String aAliasName, String aName, String aErrorInfo) { 10 | this.name = aName; 11 | this.aliasName = aAliasName; 12 | this.errorInfo = aErrorInfo; 13 | } 14 | public Object executeInner(Object[] list) throws Exception { 15 | return executeInner(list[0], list[1]); 16 | } 17 | 18 | public Object executeInner(Object op1, 19 | Object op2) throws Exception { 20 | Object o1 = op1; 21 | Object o2 = op2; 22 | boolean r1 = false; 23 | boolean r2= false; 24 | if(o1 == null){ 25 | r1 = false; 26 | }else if(o1 instanceof Boolean){ 27 | r1 = ((Boolean) o1).booleanValue(); 28 | }else{ 29 | String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作"; 30 | throw new Exception(msg); 31 | } 32 | if(o2 == null){ 33 | r2 = false; 34 | }else if(o2 instanceof Boolean){ 35 | r2 = ((Boolean) o2).booleanValue(); 36 | }else{ 37 | String msg = "没有定义类型" + o1 + "和" + o2 + " 的 " + this.name + "操作"; 38 | throw new Exception(msg); 39 | } 40 | boolean result = r1 || r2; 41 | return Boolean.valueOf(result); 42 | 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorPrint.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | 5 | public class OperatorPrint extends Operator { 6 | public OperatorPrint(String name) { 7 | this.name = name; 8 | } 9 | public OperatorPrint(String aAliasName, String aName, String aErrorInfo) { 10 | this.name = aName; 11 | this.aliasName = aAliasName; 12 | this.errorInfo = aErrorInfo; 13 | } 14 | public Object executeInner(Object[] list) throws Exception { 15 | if (list.length != 1 ){ 16 | throw new Exception("操作数异常,有且只能有一个操作数"); 17 | } 18 | System.out.print(list[0]); 19 | return null; 20 | } 21 | 22 | 23 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorPrintln.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | 5 | public class OperatorPrintln extends Operator { 6 | public OperatorPrintln(String name) { 7 | this.name = name; 8 | } 9 | public OperatorPrintln(String aAliasName, String aName, String aErrorInfo) { 10 | this.name = aName; 11 | this.aliasName = aAliasName; 12 | this.errorInfo = aErrorInfo; 13 | } 14 | public Object executeInner(Object[] list) throws Exception { 15 | if (list.length != 1 ){ 16 | throw new Exception("操作数异常,有且只能有一个操作数"); 17 | } 18 | System.out.println(list[0]); 19 | return null; 20 | } 21 | 22 | 23 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorRound.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import com.ql.util.express.Operator; 4 | import com.ql.util.express.OperatorOfNumber; 5 | 6 | public class OperatorRound extends Operator { 7 | public OperatorRound(String name) { 8 | this.name = name; 9 | } 10 | 11 | public Object executeInner(Object[] list) throws Exception { 12 | return executeInner(list[0], list[1]); 13 | } 14 | 15 | public Object executeInner(Object op1,Object op2) throws Exception { 16 | double r = OperatorOfNumber.round( 17 | ((Number) op1).doubleValue(), ((Number) op2).intValue()); 18 | return new Double(r); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/op/OperatorSelfDefineClassFunction.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.op; 2 | 3 | import java.lang.reflect.Method; 4 | import java.lang.reflect.Modifier; 5 | 6 | import com.ql.util.express.ExpressUtil; 7 | import com.ql.util.express.InstructionSetContext; 8 | import com.ql.util.express.OperateData; 9 | import com.ql.util.express.instruction.OperateDataCacheManager; 10 | 11 | /** 12 | * 用户自定义的函数操作 13 | * @author qhlhl2010@gmail.com 14 | * 15 | */ 16 | public class OperatorSelfDefineClassFunction extends OperatorBase implements CanClone{ 17 | String functionName; 18 | String[] parameterTypes; 19 | Class[] parameterClasses ; 20 | Class operClass; 21 | Method method; 22 | boolean isReturnVoid; 23 | 24 | public OperatorSelfDefineClassFunction(String aOperName,String aClassName, String aFunctionName, 25 | Class[] aParameterClassTypes,String[] aParameterDesc,String[] aParameterAnnotation,String aErrorInfo) throws Exception { 26 | if (errorInfo != null && errorInfo.trim().length() == 0) { 27 | errorInfo = null; 28 | } 29 | this.name = aOperName; 30 | this.errorInfo = aErrorInfo; 31 | this.functionName = aFunctionName; 32 | this.parameterClasses = aParameterClassTypes; 33 | this.parameterTypes = new String[aParameterClassTypes.length]; 34 | this.operDataDesc = aParameterDesc; 35 | this.operDataAnnotation = aParameterAnnotation; 36 | for(int i=0;i[] parameterClasses ; 20 | Method method; 21 | boolean isReturnVoid; 22 | 23 | public OperatorSelfDefineServiceFunction(String aOperName, 24 | Object aServiceObject, String aFunctionName, 25 | Class[] aParameterClassTypes,String[] aParameterDesc,String[] aParameterAnnotation, String aErrorInfo) throws Exception { 26 | if (errorInfo != null && errorInfo.trim().length() == 0) { 27 | errorInfo = null; 28 | } 29 | this.name = aOperName; 30 | this.errorInfo = aErrorInfo; 31 | this.serviceObject = aServiceObject; 32 | this.functionName = aFunctionName; 33 | this.parameterClasses = aParameterClassTypes; 34 | this.operDataDesc = aParameterDesc; 35 | this.operDataAnnotation = aParameterAnnotation; 36 | this.parameterTypes = new String[this.parameterClasses.length]; 37 | for (int i = 0; i < this.parameterClasses.length; i++) { 38 | this.parameterTypes[i] = this.parameterClasses[i].getName(); 39 | } 40 | Class operClass = serviceObject.getClass(); 41 | method = operClass.getMethod(functionName, parameterClasses); 42 | this.isReturnVoid = method.getReturnType().equals(void.class); 43 | } 44 | 45 | public OperatorSelfDefineServiceFunction(String aOperName,Object aServiceObject, String aFunctionName, 46 | String[] aParameterTypes,String[] aParameterDesc,String[] aParameterAnnotation,String aErrorInfo) throws Exception { 47 | 48 | if (errorInfo != null && errorInfo.trim().length() == 0) { 49 | errorInfo = null; 50 | } 51 | this.name = aOperName; 52 | this.errorInfo = aErrorInfo; 53 | this.serviceObject = aServiceObject; 54 | this.functionName = aFunctionName; 55 | this.parameterTypes = aParameterTypes; 56 | this.operDataDesc = aParameterDesc; 57 | this.operDataAnnotation = aParameterAnnotation; 58 | this.parameterClasses = new Class[this.parameterTypes.length]; 59 | for(int i=0;i operClass = serviceObject.getClass(); 63 | method = operClass.getMethod(functionName,parameterClasses); 64 | 65 | } 66 | 67 | public OperatorBase cloneMe(String opName, String errorInfo) 68 | throws Exception { 69 | OperatorBase result = new OperatorSelfDefineServiceFunction(opName, 70 | this.serviceObject, this.functionName, this.parameterClasses, 71 | this.operDataDesc, this.operDataAnnotation, errorInfo); 72 | return result; 73 | } 74 | public OperateData executeInner(InstructionSetContext context, OperateData[] list) throws 75 | Exception { 76 | if(this.parameterClasses.length != list.length){ 77 | throw new Exception("定义的参数长度与运行期传入的参数长度不一致"); 78 | } 79 | Object[] parameres = new Object[list.length]; 80 | for(int i=0;i m_class; 9 | public OperateClass(String name, Class aClass) { 10 | super(null,null); 11 | this.name = name; 12 | this.m_class = aClass; 13 | } 14 | public void toResource(StringBuilder builder,int level){ 15 | builder.append(this.name); 16 | } 17 | public String toString() { 18 | return "Class:" + name; 19 | // return name; 20 | } 21 | public Class getVarClass(){ 22 | return this.m_class; 23 | } 24 | public void reset(String aName,Class newClass){ 25 | this.name = aName; 26 | this.m_class = newClass; 27 | } 28 | public Object getObjectInner(InstructionSetContext parent) { 29 | return m_class; 30 | } 31 | public String getName(){ 32 | return this.name; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/opdata/OperateDataAlias.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.opdata; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | 5 | public class OperateDataAlias extends OperateDataAttr { 6 | OperateDataAttr realAttr; 7 | public OperateDataAlias(String aName,OperateDataAttr aRealAttr) { 8 | super(aName,null); 9 | this.realAttr = aRealAttr; 10 | } 11 | public String toString() { 12 | try { 13 | return this.name + "[alias=" + this.realAttr.name+"]"; 14 | } catch (Exception ex) { 15 | return ex.getMessage(); 16 | } 17 | } 18 | public Object getObjectInner(InstructionSetContext context) { 19 | try { 20 | return realAttr.getObject(context); 21 | } catch (Exception e) { 22 | throw new RuntimeException(e); 23 | } 24 | } 25 | 26 | public Class getType(InstructionSetContext context) throws Exception { 27 | return realAttr.getType(context); 28 | } 29 | 30 | public void setObject(InstructionSetContext context, Object object) { 31 | try { 32 | realAttr.setObject(context, object); 33 | } catch (Exception e) { 34 | throw new RuntimeException(e); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/opdata/OperateDataArrayItem.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.opdata; 2 | 3 | import java.lang.reflect.Array; 4 | 5 | import com.ql.util.express.InstructionSetContext; 6 | import com.ql.util.express.OperateData; 7 | 8 | public class OperateDataArrayItem extends OperateDataAttr { 9 | OperateData arrayObject; 10 | int index; 11 | public OperateDataArrayItem(OperateData aArrayObject,int aIndex) { 12 | super("array[" + aArrayObject +"," + aIndex +"]",null); 13 | this.arrayObject = aArrayObject; 14 | this.index = aIndex; 15 | } 16 | public void initialDataArrayItem(OperateData aArrayObject,int aIndex){ 17 | super.initialDataAttr("array[" + aArrayObject +"," + aIndex +"]",null); 18 | this.arrayObject = aArrayObject; 19 | this.index = aIndex; 20 | } 21 | public void clearDataArrayItem(){ 22 | super.clearDataAttr(); 23 | this.arrayObject = null; 24 | this.index = -1; 25 | } 26 | public void toResource(StringBuilder builder,int level){ 27 | builder.append(this.index); 28 | } 29 | public Class getType(InstructionSetContext context) throws Exception { 30 | return this.arrayObject.getObject(context).getClass(); 31 | } 32 | public Object getObjectInner(InstructionSetContext context){ 33 | try { 34 | return Array.get(this.arrayObject.getObject(context),this.index); 35 | } catch (Exception e) { 36 | throw new RuntimeException(e); 37 | } 38 | } 39 | 40 | public void setObject(InstructionSetContext context, Object value) { 41 | try { 42 | Array.set(this.arrayObject.getObject(context), this.index, value); 43 | } catch (Exception e) { 44 | throw new RuntimeException(e); 45 | } 46 | } 47 | } 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/opdata/OperateDataAttr.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.opdata; 2 | 3 | import com.ql.util.express.ExpressUtil; 4 | import com.ql.util.express.InstructionSetContext; 5 | import com.ql.util.express.OperateData; 6 | 7 | 8 | public class OperateDataAttr extends OperateData { 9 | protected String name; 10 | public OperateDataAttr(String aName,Class aType) { 11 | super(null,aType); 12 | this.name = aName; 13 | } 14 | public void initialDataAttr(String aName, Class aType) { 15 | super.initial(null, aType); 16 | this.name = aName; 17 | } 18 | public void clearDataAttr(){ 19 | super.clear(); 20 | this.name = null; 21 | } 22 | public void setDefineType(Class orgiType){ 23 | this.type = orgiType; 24 | } 25 | public Class getDefineType(){ 26 | return this.type; 27 | } 28 | public String getName(){ 29 | return name; 30 | } 31 | public void toResource(StringBuilder builder,int level){ 32 | builder.append(this.name); 33 | } 34 | public String toString() { 35 | try { 36 | String str =""; 37 | if(this.type == null){ 38 | str = name; 39 | }else{ 40 | str = name + "[" + ExpressUtil.getClassName(this.type) + "]" ; 41 | } 42 | return str; 43 | } catch (Exception ex) { 44 | return ex.getMessage(); 45 | } 46 | } 47 | public Object getObjectInner(InstructionSetContext context) throws Exception { 48 | if (this.name.equalsIgnoreCase("null")) { 49 | return null; 50 | } 51 | if (context == null) { 52 | throw new RuntimeException("没有设置表达式计算的上下文,不能获取属性:\"" + this.name 53 | + "\"请检查表达式"); 54 | } 55 | try { 56 | return context.get(this.name); 57 | } catch (Exception e) { 58 | throw new RuntimeException(e); 59 | } 60 | } 61 | 62 | public Class getType(InstructionSetContext context) throws Exception { 63 | if(this.type != null){ 64 | return this.type; 65 | } 66 | Object obj = context.get(name); 67 | if (obj == null) 68 | return null; 69 | else 70 | return obj.getClass(); 71 | } 72 | 73 | public void setObject(InstructionSetContext parent, Object object) throws Exception { 74 | try { 75 | parent.put(this.name, object); 76 | } catch (Exception e) { 77 | throw new RuntimeException(e); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/opdata/OperateDataField.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.opdata; 2 | 3 | import com.ql.util.express.ExpressUtil; 4 | import com.ql.util.express.InstructionSetContext; 5 | 6 | public class OperateDataField extends OperateDataAttr { 7 | Object fieldObject; 8 | String orgiFieldName; 9 | 10 | public OperateDataField(Object aFieldObject,String aFieldName) { 11 | super(null,null); 12 | if(aFieldObject == null){ 13 | this.name = "没有初始化的Field"; 14 | }else{ 15 | this.name = aFieldObject.getClass().getName() + "." + aFieldName; 16 | } 17 | this.fieldObject = aFieldObject; 18 | this.orgiFieldName =aFieldName; 19 | } 20 | 21 | public void initialDataField(Object aFieldObject,String aFieldName){ 22 | super.initialDataAttr(null, null); 23 | this.name = aFieldObject.getClass().getName() + "." + aFieldName; 24 | this.fieldObject = aFieldObject; 25 | this.orgiFieldName = aFieldName; 26 | } 27 | public void clearDataField(){ 28 | super.clearDataAttr(); 29 | this.name = null; 30 | this.fieldObject = null; 31 | this.orgiFieldName = null; 32 | } 33 | public String getName(){ 34 | return name; 35 | } 36 | public String toString() { 37 | try { 38 | return name; 39 | } catch (Exception ex) { 40 | return ex.getMessage(); 41 | } 42 | } 43 | 44 | public Object transferFieldName(InstructionSetContext context,String oldName){ 45 | if (context.isSupportDynamicFieldName() == false) { 46 | return oldName; 47 | } else { 48 | try { 49 | OperateDataAttr o = (OperateDataAttr) context 50 | .findAliasOrDefSymbol(oldName); 51 | if (o != null) { 52 | return o.getObject(context); 53 | } else { 54 | return oldName; 55 | } 56 | } catch (Exception e) { 57 | throw new RuntimeException(e); 58 | } 59 | } 60 | } 61 | public Object getObjectInner(InstructionSetContext context) throws Exception { 62 | //如果能找到aFieldName的定义,则再次运算 63 | if(this.fieldObject instanceof OperateDataVirClass){ 64 | return ((OperateDataVirClass)this.fieldObject).getValue(transferFieldName(context,this.orgiFieldName)); 65 | }else{ 66 | return ExpressUtil.getProperty(this.fieldObject,transferFieldName(context,this.orgiFieldName)); 67 | } 68 | } 69 | 70 | public Class getType(InstructionSetContext context) throws Exception { 71 | if(this.fieldObject instanceof OperateDataVirClass){ 72 | return ((OperateDataVirClass)this.fieldObject).getValueType(transferFieldName(context,this.orgiFieldName)); 73 | }else{ 74 | return ExpressUtil.getPropertyClass(this.fieldObject,transferFieldName(context,this.orgiFieldName)); 75 | } 76 | } 77 | 78 | public void setObject(InstructionSetContext context, Object value) throws Exception{ 79 | if(this.fieldObject instanceof OperateDataVirClass){ 80 | ((OperateDataVirClass)this.fieldObject).setValue(transferFieldName(context,this.orgiFieldName).toString(),value); 81 | }else{ 82 | ExpressUtil.setProperty(fieldObject, transferFieldName(context,this.orgiFieldName), value); 83 | } 84 | 85 | } 86 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/opdata/OperateDataKeyValue.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.opdata; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | import com.ql.util.express.OperateData; 5 | 6 | public class OperateDataKeyValue extends OperateData { 7 | OperateData key; 8 | OperateData value; 9 | 10 | public OperateDataKeyValue(OperateData aKey, OperateData aValue) { 11 | super(null, null); 12 | this.key = aKey; 13 | this.value = aValue; 14 | } 15 | public void initialDataKeyValue(OperateData aKey, OperateData aValue){ 16 | super.initial(null, null); 17 | this.key = aKey; 18 | this.value = aValue; 19 | } 20 | public void clearDataKeyValue(){ 21 | super.clear(); 22 | this.key = null; 23 | this.value = null; 24 | } 25 | public OperateData getKey() { 26 | return key; 27 | } 28 | 29 | public OperateData getValue() { 30 | return value; 31 | } 32 | 33 | public String toString() { 34 | return this.key + ":" + this.value; 35 | } 36 | 37 | public Object getObjectInner(InstructionSetContext context) { 38 | throw new RuntimeException("没有实现方法:getObjectInner"); 39 | } 40 | 41 | public Class getType(InstructionSetContext context) 42 | throws Exception { 43 | throw new RuntimeException("没有实现方法:getType"); 44 | } 45 | 46 | public void setObject(InstructionSetContext parent, 47 | Object object) { 48 | throw new RuntimeException("没有实现方法:setObject"); 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/opdata/OperateDataLocalVar.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.opdata; 2 | 3 | import com.ql.util.express.InstructionSetContext; 4 | 5 | 6 | 7 | public class OperateDataLocalVar extends OperateDataAttr { 8 | public OperateDataLocalVar(String name,Class type) { 9 | super(name,type); 10 | } 11 | 12 | public void initialDataLocalVar(String name,Class type){ 13 | super.initialDataAttr(name, type); 14 | } 15 | public void clearDataLocalVar(){ 16 | super.clear(); 17 | } 18 | public String toString() { 19 | try { 20 | return name +":localVar"; 21 | } catch (Exception ex) { 22 | return ex.getMessage(); 23 | } 24 | } 25 | 26 | public Object getObjectInner(InstructionSetContext context) { 27 | try { 28 | return this.dataObject; 29 | } catch (Exception e) { 30 | throw new RuntimeException(e); 31 | } 32 | } 33 | 34 | public Class getType(InstructionSetContext context) throws Exception { 35 | return this.type; 36 | } 37 | 38 | public void setObject(InstructionSetContext parent, Object value) { 39 | this.dataObject = value; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/instruction/opdata/OperateDataVirClass.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.instruction.opdata; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.commons.logging.Log; 6 | 7 | import com.ql.util.express.InstructionSet; 8 | import com.ql.util.express.InstructionSetContext; 9 | import com.ql.util.express.InstructionSetRunner; 10 | import com.ql.util.express.OperateData; 11 | import com.ql.util.express.instruction.OperateDataCacheManager; 12 | 13 | 14 | /** 15 | * 虚拟Class的内存对象 16 | * @author xuannan 17 | * 18 | */ 19 | public class OperateDataVirClass extends OperateDataAttr{ 20 | /** 21 | * 虚拟Class的数据上下文 22 | */ 23 | InstructionSetContext context; 24 | /** 25 | * 虚拟类的指令集合 26 | */ 27 | InstructionSet virClassInstructionSet; 28 | 29 | boolean isTrace; 30 | Log log; 31 | public OperateDataVirClass(String name){ 32 | super(name,null); 33 | } 34 | public void initialInstance(InstructionSetContext parent,OperateData[] parameters, 35 | List errorList,boolean aIsTrace,Log aLog) throws Exception { 36 | this.isTrace = aIsTrace; 37 | this.log = aLog; 38 | this.context = OperateDataCacheManager.fetchInstructionSetContext(false, 39 | parent.getExpressRunner(),parent,parent.getExpressLoader(),parent.isSupportDynamicFieldName()); 40 | Object functionSet = parent.getSymbol(this.name); 41 | if (functionSet == null || functionSet instanceof InstructionSet == false) { 42 | throw new Exception("没有找到自定义对象\"" + this.name + "\""); 43 | } 44 | this.virClassInstructionSet = (InstructionSet)functionSet; 45 | 46 | OperateDataLocalVar[] vars = virClassInstructionSet.getParameters(); 47 | for(int i=0;i getValueType(Object name) throws Exception{ 114 | Object o = this.context.findAliasOrDefSymbol(name.toString()); 115 | if(o instanceof OperateData){ 116 | return ((OperateData)o).getType(context); 117 | }else{ 118 | throw new Exception("不支持的数据类型:" + o.getClass().getName()); 119 | } 120 | } 121 | public Object getObjectInner(InstructionSetContext context) { 122 | return this; 123 | } 124 | 125 | public Class getType(InstructionSetContext context) throws Exception { 126 | return this.getClass(); 127 | } 128 | 129 | public void setObject(InstructionSetContext parent, Object object) { 130 | throw new RuntimeException("不支持的方法"); 131 | } 132 | 133 | public String toString(){ 134 | return "VClass[" + this.name+"]"; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/match/IDataNode.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.match; 2 | 3 | 4 | 5 | public interface IDataNode { 6 | public void setNodeType(INodeType type); 7 | public void setTreeType(INodeType findNodeType); 8 | public INodeType getNodeType(); 9 | public INodeType getTreeType(); 10 | 11 | public void addLeftChild(IDataNode ref); 12 | public IDataNode createExpressNode(INodeType aType,String aValue) throws Exception; 13 | 14 | public String getValue(); 15 | public void setObjectValue(Object value); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/match/INodeType.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.match; 2 | 3 | 4 | /** 5 | * 匹配类型 6 | * @author xuannan 7 | * 8 | */ 9 | public interface INodeType { 10 | public String getName(); 11 | public INodeTypeManager getManager(); 12 | public QLPatternNode getPatternNode(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/match/INodeTypeManager.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.match; 2 | 3 | public interface INodeTypeManager { 4 | public INodeType findNodeType(String name); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/match/NodeTypeManagerTestImpl.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.match; 2 | 3 | public class NodeTypeManagerTestImpl implements INodeTypeManager { 4 | 5 | public INodeType findNodeType(String name) { 6 | return new TestNodeTypeImpl(name); 7 | } 8 | 9 | } 10 | 11 | class TestNodeTypeImpl implements INodeType{ 12 | String name; 13 | public TestNodeTypeImpl(String aName){ 14 | this.name = aName; 15 | } 16 | public String getName() { 17 | return this.name; 18 | } 19 | 20 | public INodeTypeManager getManager() { 21 | throw new RuntimeException("没有实现的方法"); 22 | } 23 | 24 | @Override 25 | public QLPatternNode getPatternNode() { 26 | throw new RuntimeException("没有实现的方法"); 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/match/QLMatchResult.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.match; 2 | 3 | import java.util.List; 4 | 5 | public class QLMatchResult { 6 | protected List matchs; 7 | protected int matchLastIndex; 8 | public INodeType statementNodeType; 9 | public QLMatchResult(List aList,int aIndex){ 10 | this.matchLastIndex = aIndex; 11 | this.matchs = aList; 12 | } 13 | 14 | public String toString(){ 15 | StringBuilder builder = new StringBuilder(); 16 | for(QLMatchResultTree item:matchs){ 17 | item.printNode(builder,1); 18 | } 19 | return builder.toString(); 20 | } 21 | public List getMatchs() { 22 | return matchs; 23 | } 24 | 25 | public void setMatchs(List matchs) { 26 | this.matchs = matchs; 27 | } 28 | public int getMatchLastIndex() { 29 | return matchLastIndex; 30 | } 31 | 32 | public void setMatchLastIndex(int matchLastIndex) { 33 | this.matchLastIndex = matchLastIndex; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/match/QLMatchResultTree.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.match; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class QLMatchResultTree{ 7 | INodeType matchNodeType; 8 | IDataNode ref; 9 | 10 | INodeType targetNodeType; 11 | private List left; 12 | private List right; 13 | 14 | public QLMatchResultTree(INodeType aNodeType,IDataNode aRef,INodeType aTargetNodeType){ 15 | this(aNodeType,aRef); 16 | this.targetNodeType = aTargetNodeType; 17 | } 18 | public QLMatchResultTree(INodeType aNodeType,IDataNode aRef){ 19 | this.matchNodeType = aNodeType; 20 | this.ref = aRef; 21 | } 22 | public IDataNode getRef() { 23 | return ref; 24 | } 25 | public List getLeft(){ 26 | return this.left; 27 | } 28 | public void addLeft(QLMatchResultTree node){ 29 | if(this.left == null){ 30 | this.left = new ArrayList(); 31 | } 32 | this.left.add(node); 33 | } 34 | public void addLeftAll(List list){ 35 | if(this.left == null){ 36 | this.left = new ArrayList(); 37 | } 38 | this.left.addAll(list); 39 | } 40 | 41 | public void addRightAll(List list){ 42 | if(this.right == null){ 43 | this.right = new ArrayList(); 44 | } 45 | this.right.addAll(list); 46 | } 47 | public IDataNode transferExpressNodeType(IDataNode sourceNode,INodeType targetType){ 48 | sourceNode.setNodeType(targetType); 49 | if(targetType == targetType.getManager().findNodeType("CONST_STRING")){ 50 | sourceNode.setObjectValue(sourceNode.getValue()); 51 | sourceNode.setTreeType(targetType.getManager().findNodeType("CONST")); 52 | } 53 | return sourceNode; 54 | } 55 | public void buildExpressNodeTree(){ 56 | if(this.targetNodeType != null){ 57 | transferExpressNodeType(this.ref,this.targetNodeType); 58 | } 59 | if(this.left != null){ 60 | for (QLMatchResultTree item : left) { 61 | this.ref.addLeftChild(item.ref); 62 | item.buildExpressNodeTree(); 63 | } 64 | } 65 | if (this.right != null) { 66 | for (QLMatchResultTree item : right) { 67 | this.ref.addLeftChild(item.ref); 68 | item.buildExpressNodeTree(); 69 | } 70 | } 71 | } 72 | public String toString(){ 73 | StringBuilder builder = new StringBuilder(); 74 | printNode(builder,1); 75 | return builder.toString(); 76 | } 77 | 78 | public void printNode(StringBuilder builder, int level) { 79 | builder.append(level + ":"); 80 | for (int i = 0; i < level; i++) { 81 | builder.append(" "); 82 | } 83 | builder.append(ref.getValue() + ":" + this.matchNodeType.getName()) 84 | .append("\n"); 85 | if (this.left != null) { 86 | for (QLMatchResultTree item : this.left) { 87 | item.printNode(builder, level + 1); 88 | } 89 | } 90 | if (this.right != null) { 91 | for (QLMatchResultTree item : this.right) { 92 | item.printNode(builder, level + 1); 93 | } 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/parse/ExpressPackage.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.parse; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | public class ExpressPackage { 9 | private List m_packages; 10 | private Map> name2CallCache = null; 11 | private Class S_NULL = NullClass.class; 12 | private ExpressPackage parent; 13 | public ExpressPackage(ExpressPackage aParent) { 14 | this.parent = aParent; 15 | } 16 | public void addPackage(String aPackageName) { 17 | if(this.m_packages == null){ 18 | this.m_packages = new ArrayList(); 19 | } 20 | int point = aPackageName.indexOf(".*"); 21 | if(point >=0){ 22 | aPackageName = aPackageName.substring(0, point); 23 | } 24 | this.m_packages.add(aPackageName); 25 | } 26 | 27 | public void removePackage(String aPackageName) { 28 | if(this.m_packages != null){ 29 | this.m_packages.remove(aPackageName); 30 | } 31 | } 32 | 33 | public Class getClass(String name) { 34 | Class tempClass = null; 35 | if (this.parent != null){ 36 | tempClass = this.parent.getClass(name); 37 | } 38 | if(tempClass == null){ 39 | if(this.m_packages == null && this.parent != null){ 40 | return null; 41 | } 42 | if (this.name2CallCache == null) { 43 | this.name2CallCache = new ConcurrentHashMap>(); 44 | }else{ 45 | tempClass = this.name2CallCache.get(name); 46 | } 47 | if(tempClass == null){ 48 | tempClass = this.getClassInner(name,this.parent == null); 49 | if(tempClass == null){ 50 | tempClass = S_NULL ; 51 | } 52 | } 53 | this.name2CallCache.put(name, tempClass); 54 | } 55 | 56 | if(tempClass == S_NULL){ 57 | return null; 58 | }else{ 59 | return tempClass; 60 | } 61 | } 62 | 63 | private Class getClassInner(String name,boolean isRootCall) { 64 | Class result = null; 65 | if (isRootCall == true) { 66 | // 如果本身具有包名,这直接定位 67 | if (name.indexOf(".") >= 0) { 68 | try { 69 | result = Class.forName(name); 70 | } catch (Throwable ex) { 71 | } 72 | return result; 73 | } 74 | if (Integer.TYPE.getName().equals(name) == true) 75 | return Integer.TYPE; 76 | if (Short.TYPE.getName().equals(name) == true) 77 | return Short.TYPE; 78 | if (Long.TYPE.getName().equals(name) == true) 79 | return Long.TYPE; 80 | if (Double.TYPE.getName().equals(name) == true) 81 | return Double.TYPE; 82 | if (Float.TYPE.getName().equals(name) == true) 83 | return Float.TYPE; 84 | if (Byte.TYPE.getName().equals(name) == true) 85 | return Byte.TYPE; 86 | if (Character.TYPE.getName().equals(name) == true) 87 | return Character.TYPE; 88 | if (Boolean.TYPE.getName().equals(name) == true) 89 | return Boolean.TYPE; 90 | } 91 | if (this.m_packages != null) { 92 | for (int i = 0; i < m_packages.size(); i++) { 93 | String tmp = ""; 94 | if (m_packages.get(i).endsWith("." + name) == true) { 95 | tmp = m_packages.get(i); 96 | } else { 97 | tmp = m_packages.get(i) + "." + name; 98 | } 99 | try { 100 | result = Class.forName(tmp); 101 | } catch (ClassNotFoundException ex) { 102 | // 不做任何操作 103 | } 104 | if (result != null) { 105 | return result; 106 | } 107 | } 108 | } 109 | return null; 110 | } 111 | } 112 | 113 | class NullClass{ 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/parse/KeyWordDefine4SQL.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.parse; 2 | 3 | 4 | public class KeyWordDefine4SQL { 5 | public String[] splitWord={ 6 | "+", "-","*", "/",//四则运算: 7 | ".",",",":",";","(", ")","[", "]","{","}","?",//分隔符号 8 | "!","<", ">", "<=", ">=", "<>","=" 9 | }; 10 | public String[] keyWords = new String[] { 11 | "select","from","where","and","or","like","if","then","else","as" 12 | }; 13 | public String[] nodeTypeDefines = new String[] { 14 | "in:TYPE=KEYWORD", 15 | "EOF:TYPE=WORDDEF", 16 | "FUNCTION_NAME:TYPE=WORDDEF", 17 | "FUNCTION_DEFINE:TYPE=WORDDEF", 18 | "ID:TYPE=WORDDEF", 19 | "LEFT_BRACKET:TYPE=WORDDEF,DEFINE=(", 20 | "RIGHT_BRACKET:TYPE=WORDDEF,DEFINE=)", 21 | 22 | "CONST_BYTE:TYPE=WORDDEF", 23 | "CONST_SHORT:TYPE=WORDDEF", 24 | "CONST_INTEGER:TYPE=WORDDEF", 25 | "CONST_LONG:TYPE=WORDDEF", 26 | "CONST_FLOAT:TYPE=WORDDEF", 27 | "CONST_DOUBLE:TYPE=WORDDEF", 28 | "CONST_NUMBER:TYPE=WORDDEF,DEFINE=CONST_BYTE|CONST_SHORT|CONST_INTEGER|CONST_LONG|CONST_FLOAT|CONST_DOUBLE", 29 | "CONST_CHAR:TYPE=WORDDEF", 30 | "CONST_STRING:TYPE=WORDDEF", 31 | "CONST_BOOLEAN:TYPE=WORDDEF", 32 | "CONST_CLASS:TYPE=WORDDEF", 33 | "CONST:TYPE=GROUP,DEFINE=CONST_NUMBER|CONST_CHAR|CONST_STRING|CONST_BOOLEAN|CONST_CLASS", 34 | 35 | // "():TYPE=BLOCK,STARTTAG=(,ENDTAG=)", 36 | // "[]:TYPE=BLOCK,STARTTAG=[,ENDTAG=]", 37 | // "{}:TYPE=BLOCK,STARTTAG={,ENDTAG=}", 38 | // "EXPRESS_CHILD:TYPE=GROUP,DEFINE=()|[]", 39 | 40 | "OP_LEVEL1:TYPE=OPERATOR,DEFINE=!", 41 | "OP_LEVEL2:TYPE=OPERATOR,DEFINE=*|/", 42 | "OP_LEVEL3:TYPE=OPERATOR,DEFINE=+|-", 43 | "OP_LEVEL4:TYPE=OPERATOR,DEFINE=in|like", 44 | "OP_LEVEL5:TYPE=OPERATOR,DEFINE=>|>=|<|<=|=|<>", 45 | "OP_LEVEL6:TYPE=OPERATOR,DEFINE=and", 46 | "OP_LEVEL7:TYPE=OPERATOR,DEFINE=or", 47 | 48 | "TAB_COL_NAME:TYPE=STATEMENT,DEFINE=ID$(.$ID)*#TAB_COL_NAME", 49 | "CHILD_EXPRESS:TYPE=EXPRESS,DEFINE=LEFT_BRACKET~$EXPRESS$RIGHT_BRACKET~", 50 | "OPDATA:TYPE=EXPRESS,DEFINE=CHILD_EXPRESS|CONST|TAB_COL_NAME", 51 | "TAB_COL_NAME_ALIAS:TYPE=STATEMENT,DEFINE=TAB_COL_NAME$(as^$TAB_COL_NAME){0:1}", 52 | "TAB_COL_LIST:TYPE=STATEMENT,DEFINE=TAB_COL_NAME_ALIAS$(,~$TAB_COL_NAME_ALIAS)*", 53 | 54 | "EXPRESS_OP_L1:TYPE=EXPRESS,DEFINE=OP_LEVEL1^*$OPDATA", 55 | "EXPRESS_OP_L2:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L1$(OP_LEVEL2^$EXPRESS_OP_L1)^*", 56 | "EXPRESS_OP_L3:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L2$(OP_LEVEL3^$EXPRESS_OP_L2)^*", 57 | "EXPRESS_OP_L4:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L3$(OP_LEVEL4^$EXPRESS_OP_L3)^*", 58 | "EXPRESS_OP_L5:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L4$(OP_LEVEL5^$EXPRESS_OP_L4)^*", 59 | "EXPRESS_OP_L6:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L5$(OP_LEVEL6^$EXPRESS_OP_L5)^*", 60 | "EXPRESS_OP_L7:TYPE=EXPRESS,DEFINE=EXPRESS_OP_L6$(OP_LEVEL7^$EXPRESS_OP_L6)^*", 61 | 62 | "EXPRESS:TYPE=STATEMENT,DEFINE=EXPRESS_OP_L7", 63 | 64 | "OP_LIST:TYPE=GROUP,DEFINE=OP_LEVEL1|OP_LEVEL2|OP_LEVEL3|OP_LEVEL4|OP_LEVEL5|OP_LEVEL6|OP_LEVEL7|LEFT_BRACKET|RIGHT_BRACKET|[|]", 65 | "PARAMETER_LIST:TYPE=STATEMENT,DEFINE=EXPRESS$(,~$EXPRESS)*", 66 | "SELECT:TYPE=STATEMENT,DEFINE=(select^$TAB_COL_LIST)$(from^$PARAMETER_LIST)$(where^$EXPRESS){0:1}#SELECT", 67 | 68 | "STATEMENT:TYPE=STATEMENT", 69 | "PROGRAM:TYPE=STATEMENT,DEFINE=SELECT", 70 | 71 | 72 | }; 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/parse/NodeType.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.parse; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.regex.Matcher; 6 | import java.util.regex.Pattern; 7 | 8 | import com.ql.util.express.match.INodeType; 9 | import com.ql.util.express.match.QLPattern; 10 | import com.ql.util.express.match.QLPatternNode; 11 | 12 | enum NodeTypeKind { 13 | KEYWORD, BLOCK, EXPRESS, OPERATOR, WORDDEF, GROUP, STATEMENT 14 | } 15 | 16 | public class NodeType implements INodeType { 17 | NodeTypeManager manager; 18 | private String name; 19 | private String defineStr; 20 | private NodeTypeKind kind; 21 | private NodeType realNodeType; 22 | private String instructionFactory; 23 | /** 24 | * 模式匹配 25 | */ 26 | private QLPatternNode qlPatternNode; 27 | 28 | protected NodeType(NodeTypeManager aManager, String aName, String aDefineStr) { 29 | this.manager = aManager; 30 | this.defineStr = aDefineStr; 31 | this.name = aName; 32 | } 33 | 34 | public static String[][] splitProperties(String str) { 35 | Pattern p = Pattern.compile("(,|:)\\s*(([A-Z]|-|_)*)\\s*="); 36 | Matcher matcher = p.matcher(str); 37 | List list = new ArrayList(); 38 | int endIndex = 0; 39 | while (matcher.find()) { 40 | if (list.size() > 0) { 41 | list.get(list.size() - 1)[1] = str.substring(endIndex, 42 | matcher.start()).trim(); 43 | } 44 | list.add(new String[2]); 45 | list.get(list.size() - 1)[0] = str.substring(matcher.start() + 1, 46 | matcher.end() - 1).trim(); 47 | endIndex = matcher.end(); 48 | } 49 | if (list.size() > 0) { 50 | list.get(list.size() - 1)[1] = str.substring(endIndex).trim(); 51 | } 52 | return (String[][]) list.toArray(new String[0][2]); 53 | } 54 | 55 | public void initial() { 56 | try { 57 | int index = this.defineStr.indexOf(":", 1); 58 | String[][] properties = splitProperties(this.defineStr.substring(index)); 59 | for (String[] tempList : properties) { 60 | if (tempList[0].equalsIgnoreCase("type")) { 61 | this.setKind(NodeTypeKind.valueOf(tempList[1])); 62 | } else if (tempList[0].equalsIgnoreCase("real")) { 63 | this.realNodeType = manager.findNodeType(tempList[1]); 64 | } else if (tempList[0].equalsIgnoreCase("factory")) { 65 | this.instructionFactory = tempList[1]; 66 | } else if (tempList[0].equalsIgnoreCase("define")) { 67 | this.qlPatternNode = QLPattern.createPattern(this.manager, 68 | this.name, tempList[1]); 69 | } else { 70 | throw new RuntimeException("不能识别\"" + this.name 71 | + "\"的属性类型:" + tempList[0] + " 定义:" 72 | + this.defineStr); 73 | } 74 | } 75 | } catch (Exception e) { 76 | throw new RuntimeException("节点类型\"" + this.name + "\"初始化失败,定义:" 77 | + this.defineStr, e); 78 | } 79 | } 80 | public boolean isEqualsOrChild(String parent) { 81 | return this.manager.findNodeType(parent).isContainerChild(this); 82 | } 83 | 84 | public boolean isContainerChild(NodeType child) { 85 | if (this.equals(child)) { 86 | return true; 87 | } 88 | if (this.qlPatternNode == null) { 89 | return false; 90 | } 91 | if (this.qlPatternNode.isDetailMode()) { 92 | return ((NodeType) this.qlPatternNode.getNodeType()) 93 | .isContainerChild(child); 94 | } 95 | // 是and类型,不能增加子节点或进行判断 96 | if (this.qlPatternNode.isAndMode() 97 | && this.qlPatternNode.getChildren().size() > 0) { 98 | return false; 99 | } 100 | for (QLPatternNode node : this.qlPatternNode.getChildren()) { 101 | if (node.getNodeType() != null 102 | && ((NodeType) node.getNodeType()).isContainerChild(child)) { 103 | return true; 104 | } 105 | } 106 | return false; 107 | } 108 | 109 | public void addChild(NodeType child) throws Exception { 110 | String str = child.name; 111 | if (this.qlPatternNode != null) { 112 | str = this.qlPatternNode.toString() + "|" + str; 113 | } 114 | this.qlPatternNode = QLPattern.createPattern(this.manager, this.name,str); 115 | } 116 | 117 | public String toString() { 118 | StringBuilder result = new StringBuilder(); 119 | result.append(name + ":TYPE=" + this.kind); 120 | if (this.instructionFactory != null) { 121 | result.append(",FACTORY=" + this.instructionFactory); 122 | } 123 | if (this.qlPatternNode != null) { 124 | result.append(",DEFINE=").append(this.qlPatternNode); 125 | } 126 | return result.toString(); 127 | } 128 | 129 | public NodeType getRealNodeType() { 130 | return realNodeType; 131 | } 132 | 133 | public NodeTypeKind getKind() { 134 | return kind; 135 | } 136 | 137 | public String getInstructionFactory() { 138 | return instructionFactory; 139 | } 140 | 141 | public void setInstructionFactory(String instructionFactory) { 142 | this.instructionFactory = instructionFactory; 143 | } 144 | 145 | public NodeTypeManager getManager() { 146 | return manager; 147 | } 148 | 149 | public String getDefineStr() { 150 | return defineStr; 151 | } 152 | public void setKind(NodeTypeKind kind) { 153 | this.kind = kind; 154 | } 155 | 156 | public String getName() { 157 | return name; 158 | } 159 | 160 | 161 | public QLPatternNode getPatternNode() { 162 | return this.qlPatternNode; 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/parse/NodeTypeManager.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.parse; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.apache.commons.logging.Log; 9 | import org.apache.commons.logging.LogFactory; 10 | 11 | import com.ql.util.express.match.INodeTypeManager; 12 | 13 | public class NodeTypeManager implements INodeTypeManager { 14 | private static final Log log = LogFactory.getLog(NodeTypeManager.class); 15 | 16 | public String[] splitWord; 17 | private String[] keyWords; 18 | private String[] nodeTypeDefines; 19 | protected String[][] instructionFacotryMapping; 20 | protected Map nodeTypes = new HashMap(); 21 | 22 | //所有的函数定义 23 | protected Map functions = new HashMap(); 24 | 25 | public NodeTypeManager() { 26 | this(new KeyWordDefine4Java()); 27 | } 28 | public NodeTypeManager(KeyWordDefine4SQL keyWorkdDefine){ 29 | this.splitWord = keyWorkdDefine.splitWord; 30 | this.keyWords = keyWorkdDefine.keyWords; 31 | this.nodeTypeDefines = keyWorkdDefine.nodeTypeDefines; 32 | this.initial(); 33 | 34 | } 35 | public NodeTypeManager(KeyWordDefine4Java keyWorkdDefine){ 36 | this.splitWord = keyWorkdDefine.splitWord; 37 | this.keyWords = keyWorkdDefine.keyWords; 38 | this.nodeTypeDefines = keyWorkdDefine.nodeTypeDefines; 39 | this.instructionFacotryMapping = keyWorkdDefine.instructionFacotryMapping; 40 | this.initial(); 41 | this.addOperatorWithRealNodeType("and","&&"); 42 | this.addOperatorWithRealNodeType("or","||"); 43 | 44 | } 45 | 46 | public void initial() { 47 | //创建所有的关键字 48 | NodeType[] tempKeyWordNodeTypes = new NodeType[splitWord.length + keyWords.length]; 49 | for (int i = 0; i < splitWord.length; i++) { 50 | tempKeyWordNodeTypes[i] = this.createNodeType(splitWord[i] + ":TYPE=KEYWORD"); 51 | } 52 | for (int i = 0 ; i < keyWords.length; i++) { 53 | tempKeyWordNodeTypes[i + splitWord.length] = this.createNodeType(keyWords[i] + ":TYPE=KEYWORD"); 54 | } 55 | // 初始化所有的类型信息, 56 | for (int i = 0; i < tempKeyWordNodeTypes.length; i++) { 57 | tempKeyWordNodeTypes[i].initial(); 58 | } 59 | 60 | // 创建所有的类型信息,但不能初始化 61 | NodeType[] nodeTypes = new NodeType[nodeTypeDefines.length]; 62 | for (int i = 0; i < nodeTypeDefines.length; i++) { 63 | nodeTypes[i] = this.createNodeType(nodeTypeDefines[i]); 64 | } 65 | // 初始化所有的类型信息, 66 | for (int i = 0; i < nodeTypes.length; i++) { 67 | nodeTypes[i].initial(); 68 | } 69 | 70 | //初始化指令Facotry 71 | if (this.instructionFacotryMapping != null) { 72 | for (String[] list : this.instructionFacotryMapping) { 73 | for (String s : list[0].split(",")) { 74 | this.findNodeType(s).setInstructionFactory(list[1]); 75 | } 76 | } 77 | } 78 | } 79 | 80 | /** 81 | * 创建节点类型,需要注意的是不能初始化,必须所有的类型都创建完成后才能调用初始化方法 82 | * @param aDefineStr 83 | * @return 84 | */ 85 | public NodeType createNodeType(String aDefineStr){ 86 | int index = aDefineStr.indexOf(":",1);//避免对操作符号":"的错误处理 87 | String name = aDefineStr.substring(0,index).trim(); 88 | NodeType define = nodeTypes.get(name); 89 | if(define != null ){ 90 | log.warn("节点类型定义重复:"+name+" 定义1="+define.getDefineStr() + " 定义2=" + aDefineStr); 91 | throw new RuntimeException("节点类型定义重复:"+name+" 定义1="+define.getDefineStr() + " 定义2=" + aDefineStr); 92 | } 93 | define = new NodeType(this,name,aDefineStr); 94 | nodeTypes.put(name, define); 95 | return define; 96 | } 97 | /** 98 | * 根据类型名称查找节点类型 99 | * @param name 100 | * @return 101 | */ 102 | @Override 103 | public NodeType findNodeType(String name){ 104 | NodeType result = nodeTypes.get(name); 105 | if(result == null){ 106 | throw new RuntimeException("没有定义的节点类型:" + name); 107 | } 108 | while(result.getRealNodeType() != null){ 109 | result = result.getRealNodeType(); 110 | } 111 | return result; 112 | } 113 | 114 | /** 115 | * 增加关键字,但是用实际的类型代替,例如 :"如果"->"if" 116 | * @param keyWordName 117 | * @param realName 118 | */ 119 | public void addOperatorWithRealNodeType(String keyWordName, String realName){ 120 | NodeType target = this.createNodeType(keyWordName + ":TYPE=KEYWORD,REAL=" + realName); 121 | target.initial(); 122 | } 123 | 124 | /** 125 | * 增加新的操作符号,其优先级别,以及语法关系与参照的操作符号一致 126 | * @param operName 127 | * @param refOperName 128 | * @throws Exception 129 | */ 130 | public void addOperatorWithLevelOfReference(String operName, String refOperName) throws Exception{ 131 | NodeType target = this.createNodeType(operName + ":TYPE=KEYWORD"); 132 | target.initial(); 133 | NodeType[] list = this.getNodeTypesByKind(NodeTypeKind.OPERATOR); 134 | NodeType refNodeType = this.findNodeType(refOperName); 135 | target.setInstructionFactory(refNodeType.getInstructionFactory()); 136 | for(NodeType item:list){ 137 | if(item.isContainerChild(refNodeType)){ 138 | item.addChild(target); 139 | return; 140 | } 141 | } 142 | } 143 | 144 | /** 145 | * 判断是否存在节点类型定义 146 | * @param name 147 | * @return 148 | */ 149 | public NodeType isExistNodeTypeDefine(String name){ 150 | NodeType result = nodeTypes.get(name); 151 | if(result != null && result.getRealNodeType() != null){ 152 | result = result.getRealNodeType(); 153 | } 154 | return result; 155 | } 156 | 157 | public NodeType[] getNodeTypesByKind(NodeTypeKind aKind){ 158 | List result = new ArrayList(); 159 | for(NodeType item :this.nodeTypes.values()){ 160 | if(item.getKind() == aKind){ 161 | result.add(item); 162 | } 163 | } 164 | return result.toArray(new NodeType[0]); 165 | } 166 | public boolean isFunction(String name){ 167 | return this.functions.containsKey(name); 168 | } 169 | public void addFunctionName(String name){ 170 | this.functions.put(name, name); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/parse/Word.java: -------------------------------------------------------------------------------- 1 | package com.ql.util.express.parse; 2 | 3 | 4 | public class Word { 5 | public String word; 6 | public int line; 7 | public int col; 8 | public Word(String aWord,int aLine,int aCol){ 9 | this.word = aWord; 10 | this.line = aLine; 11 | this.col = aCol - aWord.length() + 1; 12 | } 13 | public String toString(){ 14 | return this.word;// + "[" + this.line + "," + this.col + "]"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/ql/util/express/parse/WordSplit.java: -------------------------------------------------------------------------------- 1 | 2 | package com.ql.util.express.parse; 3 | 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | 9 | 10 | /** 11 | * 语法解析类 12 | * 1、单词分解 13 | * @author xuannan 14 | * 15 | */ 16 | 17 | public class WordSplit 18 | { 19 | /** 20 | * 文本分析函数,“.”作为操作符号处理 21 | * @param str String 22 | * @throws Exception 23 | * @return String[] 24 | */ 25 | public static Word[] parse(String[] splitWord,String str) throws Exception{ 26 | if (str == null){ 27 | return new Word[0]; 28 | } 29 | sortSplitWord(splitWord); 30 | char c; 31 | int line =1; 32 | List list = new ArrayList(); 33 | int i= 0; 34 | int point = 0; 35 | while(i0 && str.charAt(index - 1) =='\\'){ 41 | index = str.indexOf(c,index + 1); 42 | } 43 | if (index < 0) 44 | throw new Exception("字符串没有关闭"); 45 | String tempDealStr = str.substring(i,index + 1); 46 | //处理 \\,\"的情况 47 | String tmpResult = ""; 48 | int tmpPoint = tempDealStr.indexOf("\\"); 49 | while(tmpPoint >=0 ){ 50 | tmpResult = tmpResult + tempDealStr.substring(0,tmpPoint); 51 | if(tmpPoint == tempDealStr.length() -1){ 52 | throw new Exception("字符串中的" + "\\错误:" + tempDealStr); 53 | } 54 | tmpResult = tmpResult + tempDealStr.substring(tmpPoint + 1 ,tmpPoint + 2); 55 | tempDealStr = tempDealStr.substring(tmpPoint + 2); 56 | tmpPoint = tempDealStr.indexOf("\\"); 57 | } 58 | tmpResult = tmpResult + tempDealStr; 59 | list.add(new Word(tmpResult,line,i)); 60 | 61 | if (point < i ){ 62 | list.add(new Word(str.substring(point,i),line,i)); 63 | } 64 | i = index + 1; 65 | point = i; 66 | }else if(c=='.' && point < i && isNumber(str.substring(point,i))){ 67 | i = i + 1; //小数点的特殊处理 68 | }else if(c == ' ' ||c =='\r'|| c =='\n'||c=='\t'||c=='\u000C'){ 69 | if (point < i ){ 70 | list.add(new Word(str.substring(point,i),line,i)); 71 | } 72 | if(c =='\n'){ 73 | line = line + 1; 74 | } 75 | i = i + 1; 76 | point = i; 77 | }else{ 78 | boolean isFind = false; 79 | for(String s:splitWord){ 80 | int length = s.length(); 81 | if(i + length <= str.length() && str.substring(i, i+length).equals(s)){ 82 | if (point < i ){ 83 | list.add(new Word(str.substring(point,i),line,i)); 84 | } 85 | list.add(new Word(str.substring(i, i+length),line,i)); 86 | i = i + length; 87 | point = i; 88 | isFind = true; 89 | break; 90 | } 91 | } 92 | if(isFind == false){ 93 | i = i+1; 94 | } 95 | } 96 | } 97 | if (point < i) { 98 | list.add(new Word(str.substring(point, i), line, i)); 99 | } 100 | 101 | Word result[] = new Word[list.size()]; 102 | list.toArray(result); 103 | return result; 104 | } 105 | 106 | public static String[] sortSplitWord(String[] splitWord) { 107 | Arrays.sort(splitWord, new Comparator() { 108 | public int compare(String o1, String o2) { 109 | if (o1.length() == o2.length()) { 110 | return 0; 111 | } else if (o1.length() > o2.length()) { 112 | return -1; 113 | } else { 114 | return 1; 115 | } 116 | 117 | } 118 | }); 119 | return splitWord; 120 | } 121 | 122 | protected static boolean isNumber(String str) { 123 | if (str == null || str.equals("")) 124 | return false; 125 | char c = str.charAt(0); 126 | if (c >= '0' && c <= '9') { // 数字 127 | return true; 128 | } else { 129 | return false; 130 | } 131 | } 132 | 133 | 134 | public static String getPrintInfo(Object[] list,String splitOp){ 135 | StringBuffer buffer = new StringBuffer(); 136 | for(int i=0;i 0){buffer.append(splitOp);} 138 | buffer.append("{" + list[i] +"}"); 139 | } 140 | return buffer.toString(); 141 | } 142 | 143 | } 144 | --------------------------------------------------------------------------------