提交 2336835d 编写于 作者: T tianqiao

update

上级 4090b603
# Created by .ignore support plugin (hsz.mobi)
### Java template
*.class
target/*
*.iml
.idea/
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
## qlExpress相关文档
### 最简单的调用案例
```xml
<dependency>
<groupId>com.taobao.util</groupId>
<artifactId>taobao-express</artifactId>
<version>3.0.17</version>
</dependency>
```
```java
ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
context.put("a",1);
context.put("b",2);
context.put("c",3);
String express = "a+b*c";
Object r = runner.execute(express, context, null, true, false);
System.out.println(r);
```
### 更多的语法介绍
1、java的绝大多数语法
```
//支持 +,-,*,/,<,>,<=,>=,==,!=,<>【等同于!=】,%,mod【取模等同于%】,++,--,
//in【类似sql】,like【sql语法】,&&,||,!,等操作符
//支持for,break、continue、if then else 等标准的程序控制逻辑
n=10;
for(sum=0,i=0;i<n;i++){
sum=sum+i;
}
return sum;
//逻辑三元操作
a=1;
b=2;
max = a>b?a:b;
```
//关于对象,类,属性,方法的调用
```
import com.ql.util.express.test.OrderQuery;
//系统自动会import java.lang.*,import java.util.*;
query = new OrderQuery();//创建class实例,会根据classLoader信息,自动补全类路径
query.setCreateDate(new Date());//设置属性
query.buyer = "张三";//调用属性,默认会转化为setBuyer("张三")
result = bizOrderDAO.query(query);//调用bean对象的方法
System.out.println(result.getId());//静态方法
//自定义方法与调用
function add(int a,int b){
return a+b;
};
function sub(int a,int b){
return a - b;
};
a=10;
return add(a,4) + sub(a,9);
```
2、自定义操作符号:addOperatorWithAlias+addOperator+addFunction
```
runner.addOperatorWithAlias("如果", "if",null);
runner.addOperatorWithAlias("则", "then",null);
runner.addOperatorWithAlias("否则", "else",null);
exp = "如果 (如果 1==2 则 false 否则 true) 则 {2+2;} 否则 {20 + 20;}";
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
runner.execute(exp,nil,null,false,false,null);
//定义一个继承自com.ql.util.express.Operator的操作符
public class JoinOperator extends Operator{
public Object executeInner(Object[] list) throws Exception {
Object opdata1 = list[0];
Object opdata2 = list[1];
if(opdata1 instanceof java.util.List){
((java.util.List)opdata1).add(opdata2);
return opdata1;
}else{
java.util.List result = new java.util.ArrayList();
result.add(opdata1);
result.add(opdata2);
return result;
}
}
}
ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
runner.addOperator("join",new JoinOperator());
Object r = runner.execute("1 join 2 join 3", context, null, false, false);
System.out.println(r);
//返回结果 [1, 2, 3]
class GroupOperator extends Operator {
public GroupOperator(String aName) {
this.name= aName;
}
public Object executeInner(Object[] list)throws Exception {
Object result = Integer.valueOf(0);
for (int i = 0; i < list.length; i++) {
result = OperatorOfNumber.add(result, list[i],false);//根据list[i]类型(string,number等)做加法
}
return result;
}
}
runner.addFunction("group", new GroupOperator("group"));
ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
runner.addOperator("join",new JoinOperator());
Object r = runner.execute("group(1,2,3)", context, null, false, false);
System.out.println(r);
//返回结果 6
```
3、类的静态方法,对象的方法绑定:addFunctionOfClassMethod+addFunctionOfServiceMethod
```
public class BeanExample {
public static String upper(String abc) {
return abc.toUpperCase();
}
public boolean anyContains(String str, String searchStr) {
char[] s = str.toCharArray();
for (char c : s) {
if (searchStr.contains(c+"")) {
return true;
}
}
return false;
}
}
runner.addFunctionOfClassMethod("取绝对值", Math.class.getName(), "abs",
new String[] { "double" }, null);
runner.addFunctionOfClassMethod("转换为大写", BeanExample.class.getName(),
"upper", new String[] { "String" }, null);
runner.addFunctionOfServiceMethod("打印", System.out, "println",new String[] { "String" }, null);
runner.addFunctionOfServiceMethod("contains", new BeanExample(), "anyContains",
new Class[] { String.class, String.class }, null);
String exp = “取绝对值(-100);转换为大写(\"hello world\");打印(\"你好吗?\");contains("helloworld",\"aeiou\")”;
runner.execute(exp, context, null, false, false);
```
4、macro 宏定义
```
runner.addMacro("计算平均成绩", "(语文+数学+英语)/3.0");
runner.addMacro("是否优秀", "计算平均成绩>90");
IExpressContext<String, Object> context =new DefaultContext<String, Object>();
context.put("语文", 88);
context.put("数学", 99);
context.put("英语", 95);
Object result = runner.execute("是否优秀", context, null, false, false);
System.out.println(r);
//返回结果true
```
5、编译脚本,查询外部需要定义的变量,注意以下脚本int和没有int的区别
```
String express = "int 平均分 = (语文+数学+英语+综合考试.科目2)/4.0;return 平均分";
ExpressRunner runner = new ExpressRunner(true,true);
String[] names = runner.getOutVarNames(express);
for(String s:names){
System.out.println("var : " + s);
}
//输出结果:
var : 数学
var : 综合考试
var : 英语
var : 语文
```
6、关于不定参数的使用
```
@Test
public void testMethodReplace() throws Exception {
ExpressRunner runner = new ExpressRunner();
IExpressContext<String,Object> expressContext = new DefaultContext<String,Object>();
runner.addFunctionOfServiceMethod("getTemplate", this, "getTemplate", new Class[]{Object[].class}, null);
//(1)默认的不定参数可以使用数组来代替
Object r = runner.execute("getTemplate([11,'22',33L,true])", expressContext, null,false, false);
System.out.println(r);
//(2)像java一样,支持函数动态参数调用,需要打开以下全局开关,否则以下调用会失败
DynamicParamsUtil.supportDynamicParams = true;
r = runner.execute("getTemplate(11,'22',33L,true)", expressContext, null,false, false);
System.out.println(r);
}
//等价于getTemplate(Object[] params)
public Object getTemplate(Object... params) throws Exception{
String result = "";
for(Object obj:params){
result = result+obj+",";
}
return result;
}
```
7、关于集合的快捷写法
```
@Test
public void testSet() throws Exception {
ExpressRunner runner = new ExpressRunner(false,false);
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
String express = "abc = NewMap(1:1,2:2); return abc.get(1) + abc.get(2);";
Object r = runner.execute(express, context, null, false, false);
System.out.println(r);
express = "abc = NewList(1,2,3); return abc.get(1)+abc.get(2)";
r = runner.execute(express, context, null, false, false);
System.out.println(r);
express = "abc = [1,2,3]; return abc[1]+abc[2];";
r = runner.execute(express, context, null, false, false);
System.out.println(r);
}
```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.taobao.util</groupId>
<artifactId>taobao-express</artifactId>
<packaging>jar</packaging>
<version>3.0.18</version>
<name>taobao-express</name>
<dependencies>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.unitils</groupId>
<artifactId>unitils</artifactId>
<version>2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>releases</id>
<url>http://mvnrepo.alibaba-inc.com/mvn/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://mvnrepo.alibaba-inc.com/mvn/snapshots</url>
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.1</version>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package com.ql.util.express;
public final class ArraySwap {
OperateData[] arrays;
int start;
public int length;
public void swap(OperateData[] aArrays,int aStart ,int aLength){
this.arrays = aArrays;
this.start = aStart;
this.length = aLength;
}
public OperateData get(int i){
return this.arrays[i+start];
}
}
package com.ql.util.express;
import java.io.Serializable;
/**
* 简单的缓存对象
* @author tianqiao
*
*/
public class CacheObject implements Serializable{
/**
*
*/
private static final long serialVersionUID = -145121001676214513L;
private String expressName;
private String text;
private InstructionSet instructionSet;
public String getExpressName() {
return expressName;
}
public void setExpressName(String name) {
this.expressName = name;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public InstructionSet getInstructionSet() {
return instructionSet;
}
public void setInstructionSet(InstructionSet instructionSet) {
this.instructionSet = instructionSet;
}
}
package com.ql.util.express;
public class CallResult{
private Object returnValue;
private boolean isExit;
public CallResult(Object aReturnValue,boolean aIsExit){
this.initial(aReturnValue, aIsExit);
}
public void initial(Object aReturnValue,boolean aIsExit){
this.returnValue = aReturnValue;
this.isExit = aIsExit;
}
public void clear(){
this.returnValue = null;
this.isExit = false;
}
public Object getReturnValue() {
return returnValue;
}
public boolean isExit() {
return isExit;
}
}
package com.ql.util.express;
import java.util.HashMap;
@SuppressWarnings("serial")
public class DefaultContext<K,V> extends HashMap<K,V> implements IExpressContext<K,V> {
}
package com.ql.util.express;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class DefaultExpressResourceLoader implements IExpressResourceLoader {
public String loadExpress(String expressName) throws Exception {
expressName = expressName.replace('.', '/') + ".ql";
InputStream in = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(expressName);
if (in == null) {
throw new Exception("不能找到表达式文件:" + expressName);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder builder = new StringBuilder();
String tmpStr = null;
while ((tmpStr = reader.readLine()) != null) {
builder.append(tmpStr).append("\n");
}
reader.close();
in.close();
return builder.toString();
}
}
package com.ql.util.express;
import java.lang.reflect.Array;
/**
* Created by tianqiao on 16/9/12.
*/
public class DynamicParamsUtil {
public static boolean supportDynamicParams = false;
public static Object[] transferDynamicParams(InstructionSetContext context, ArraySwap list, Class<?>[] delaredParamsClasses,boolean maybeDynamicParams) throws Exception {
Object[] params = null;
//参数定义不符合动态参数形式 || 用户自定义不支持 || 用户传入的参数不符合
if(!maybeDynamicParams || !supportDynamicParams || !maybeDynamicParams(context,list,delaredParamsClasses)){
if(delaredParamsClasses.length != list.length){
throw new Exception("定义的参数长度与运行期传入的参数长度不一致");
}
params = new Object[list.length];
for (int i = 0; i < list.length; i++) {
params[i] = list.get(i).getObject(context);
}
return params;
}
//支持不定参数的使用 function(arg1,arg2,arg3...)
//list -> parameres[]
// arg1,arg2 -> arg1,arg2,[]
// arg1,arg2,arg3,arg4,arg5 -> arg1,arg2,[arg3,arg4,arg5]
int paramLength = delaredParamsClasses.length;
int beforeCount = paramLength-1;
int paramsCount = list.length - beforeCount;
if(beforeCount>=0 && ((Class<?>)(delaredParamsClasses[beforeCount])).isArray() && paramsCount>=0){
Class<?>componentType = delaredParamsClasses[beforeCount].getComponentType();
params = new Object[beforeCount+1];
Object[] lastParameres = (Object[]) Array.newInstance(componentType,paramsCount);
params[beforeCount] = lastParameres;
for (int i = 0; i < list.length; i++) {
if(i<beforeCount) {
params[i] = list.get(i).getObject(context);
}else{
lastParameres[i-beforeCount] = list.get(i).getObject(context);
}
}
}else {
throw new Exception("定义的参数长度与运行期传入的参数长度不一致");
}
return params;
}
public static boolean maybeDynamicParams(Class<?>[] delaredParamsClasses)
{
int length = delaredParamsClasses.length;
if(length>0 && delaredParamsClasses[length-1].isArray())
{
return true;
}
return false;
}
private static boolean maybeDynamicParams(InstructionSetContext context, ArraySwap list, Class<?>[] delaredParamsClasses) throws Exception {
//长度不一致,有可能
if(delaredParamsClasses.length != list.length) {
return true;
}
//长度一致的不定参数:不定参数的数组,只输入了一个参数并且为array,有可能
int length = list.length;
Object lastParam = list.get(length-1).getObject(context);
if(lastParam!=null && !lastParam.getClass().isArray())
{
return true;
}
return false;
}
}
package com.ql.util.express;
import java.io.Serializable;
/**
* 输出给其它指令共享使用的对象
* @author xuannan
*
*/
public class ExportItem implements Serializable{
private static final long serialVersionUID = 5440012774123494760L;
public static String TYPE_ALIAS ="alias";
public static String TYPE_DEF ="def";
public static String TYPE_FUNCTION ="function";
public static String TYPE_MACRO ="macro";
String globeName;
String name;
String type;//def,alias
String desc;//类名或者别名
public ExportItem(String aName,String aType,String aDesc){
this.globeName = aName;
this.name = aName;
this.type =aType;
this.desc = aDesc;
}
public ExportItem(String aGlobeName,String aName,String aType,String aDesc){
this.globeName = aGlobeName;
this.name = aName;
this.type =aType;
this.desc = aDesc;
}
public String toString(){
return this.globeName + "["+ this.type +":" + this.name +" " + this.desc + "]";
}
public String getGlobeName() {
return globeName;
}
public void setGlobeName(String globeName) {
this.globeName = globeName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
package com.ql.util.express;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
public class ExpressClassLoader extends ClassLoader {
public ExpressClassLoader(ClassLoader parent){
super(parent);
}
public Class<?> loadClass(String name, byte[] code) {
return this.defineClass(name, code, 0, code.length);
}
public synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
//System.out.print("开始查找 类" + name + "。。。。。。。。。。。");
Class<?> clasz = findLoadedClass(this, name);
if (clasz != null) {
//System.out.println(clasz.getClassLoader());
return clasz;
}
if (clasz == null) {
clasz = parentLoadClass(this, name);
}
if (clasz == null && name.startsWith("[")) { // 进行数组处理
int index = name.indexOf("L");
String str = name.substring(0, index);
String componentClassName = name.substring(index + 1,
name.length() - 1);
int[] dimes = new int[str.length()];
for (int i = 0; i < dimes.length; i++) {
dimes[i] = 0;
}
try {
Class<?> componentType = this.loadClass(componentClassName);
clasz = Array.newInstance(componentType, dimes).getClass();
} catch (Exception e) {
// 不错处理
}
}
if (clasz == null)
throw new ClassNotFoundException(name);
return clasz;
}
public static Class<?> findLoadedClass(ClassLoader loader, String name)
throws ClassNotFoundException {
Method m = null;
try {
m = ClassLoader.class.getDeclaredMethod("findLoadedClass",
new Class[] { String.class });
m.setAccessible(true);
Class<?> result = (Class<?>) m.invoke(loader, new Object[] { name });
if (result == null) {
result = (Class<?>) m.invoke(loader.getClass().getClassLoader(),
new Object[] { name });
}
if (result == null) {
result = (Class<?>) m.invoke(Thread.currentThread()
.getContextClassLoader(), new Object[] { name });
}
return result;
} catch (Exception ex) {
throw new ClassNotFoundException(ex.getMessage());
} finally {
if (m != null) {
m.setAccessible(false);
}
}
}
public static Class<?> parentLoadClass(ClassLoader loader, String name)
throws ClassNotFoundException {
// 如果存在这个类,则直接返回
Class<?> clasz = null;
if (clasz == null) {
try {
clasz = loader.getClass().getClassLoader().loadClass(name);
} catch (Throwable e) {
}
}
if (clasz == null)
try {
clasz = Thread.currentThread().getContextClassLoader()
.loadClass(name);
} catch (Throwable e) {
}
return clasz;
}
}
package com.ql.util.express;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import com.ql.util.express.instruction.FunctionInstructionSet;
/**
* 表达式装载器
*
* @author xuannan
*
*/
public class ExpressLoader {
private ConcurrentHashMap<String, InstructionSet> expressInstructionSetCache = new ConcurrentHashMap<String, InstructionSet>();
ExpressRunner creator;
public ExpressLoader(ExpressRunner aCreator){
this.creator = aCreator;
}
public InstructionSet loadExpress(String expressName)
throws Exception {
return parseInstructionSet(expressName,this.creator.getExpressResourceLoader().loadExpress(expressName));
}
public void addInstructionSet(String expressName, InstructionSet set)
throws Exception {
synchronized (expressInstructionSetCache) {
if (expressInstructionSetCache.containsKey(expressName)) {
throw new Exception("表达式定义重复:" + expressName);
}
expressInstructionSetCache.put(expressName, set);
}
}
public InstructionSet parseInstructionSet(String expressName,
String expressString) throws Exception {
InstructionSet parseResult = null;
if (expressInstructionSetCache.containsKey(expressName)) {
throw new Exception("表达式定义重复:" + expressName);
}
synchronized (expressInstructionSetCache) {
parseResult = this.creator.parseInstructionSet(expressString);
parseResult.setName(expressName);
parseResult.setGlobeName(expressName);
// 需要将函数和宏定义都提取出来
for (FunctionInstructionSet item : parseResult
.getFunctionInstructionSets()) {
this.addInstructionSet(item.name, item.instructionSet);
item.instructionSet.setName(item.name);
item.instructionSet.setGlobeName(expressName+ "." + item.name);
}
if(parseResult.hasMain()){
this.addInstructionSet(expressName, parseResult);
}
}
return parseResult;
}
public void clear(){
this.expressInstructionSetCache.clear();
}
public InstructionSet getInstructionSet(String expressName) {
return expressInstructionSetCache.get(expressName);
}
public ExportItem[] getExportInfo(){
Map<String,ExportItem> result = new TreeMap<String,ExportItem>();
for(InstructionSet item:expressInstructionSetCache.values()){
for(ExportItem var:item.getExportDef()){
var.setGlobeName(item.getGlobeName() + "." + var.name);
result.put(var.getGlobeName(),var);
}
result.put(item.getGlobeName(),new ExportItem(item.getGlobeName(), item.getName(),item.getType(),item.toString()));
}
return (ExportItem[])result.values().toArray(new ExportItem[0]);
}
}
package com.ql.util.express;
import java.util.List;
import org.apache.commons.logging.Log;
/**
* 远程缓存对象
* @author tianqiao
*
*/
public abstract class ExpressRemoteCacheRunner {
public void loadCache(String expressName,String text){
InstructionSet instructionSet;
try {
instructionSet = getExpressRunner().parseInstructionSet(text);
CacheObject cache = new CacheObject();
cache.setExpressName(expressName);
cache.setText(text);
cache.setInstructionSet(instructionSet);
this.putCache(expressName, cache);
} catch (Exception e) {
throw new RuntimeException("解析指令并缓存过程出现错误.",e);
}
}
public Object execute(String name,IExpressContext<String,Object> context, List<String> errorList,
boolean isTrace,boolean isCatchException, Log aLog){
try {
CacheObject cache = (CacheObject) this.getCache(name);
if(cache==null){
throw new RuntimeException("未获取到缓存对象.");
}
return getExpressRunner().execute(cache.getInstructionSet(), context, errorList, isTrace, isCatchException, aLog);
} catch (Exception e) {
throw new RuntimeException("获取缓存信息,并且执行指令集出现错误.",e);
}
}
/**
* 获取执行器ExpressRunner
* @return
*/
public abstract ExpressRunner getExpressRunner();
/**
* 获取缓存对象
* @param key
* @return
*/
public abstract Object getCache(String key);
/**
* 放置缓存的对象
* @param key
* @param object
*/
public abstract void putCache(String key,Object object );
}
此差异已折叠。
此差异已折叠。
package com.ql.util.express;
/**
* 表达式计算的数据注入接口
* @author qhlhl2010@gmail.com
*
*/
public interface IExpressContext<K,V> {
/**
* 根据名称从属性列表中提取属性值。如果表达式中用到了Spring的对象,也是通过此方法获取
* @param name 属性名称
* @return
* @throws Exception
*/
public V get(Object key);
/**
* 表达式计算的结果可以设置回调用系统,例如 userId = 3 + 4
* @param name 属性名称
* @param object 属性值
* @throws Exception
*/
public V put(K name, V object);
}
package com.ql.util.express;
/**
* 加载表达式资源接口
* @author xuannan
*
*/
public interface IExpressResourceLoader {
/**
* 根据表达式名称获取表达式的内容
* @param expressName
* @return
* @throws Exception
*/
public String loadExpress(String expressName) throws Exception;
}
package com.ql.util.express;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import com.ql.util.express.instruction.detail.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ql.util.express.instruction.FunctionInstructionSet;
import com.ql.util.express.instruction.OperateDataCacheManager;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
/**
* 表达式执行编译后形成的指令集合
* @author qhlhl2010@gmail.com
*
*/
public class InstructionSet implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1841743860792681669L;
private static final transient Log log = LogFactory.getLog(InstructionSet.class);
public static AtomicInteger uniqIndex = new AtomicInteger(1);
public static String TYPE_MAIN ="main";
public static String TYPE_CLASS ="VClass";
public static String TYPE_FUNCTION ="function";
public static String TYPE_MARCO ="marco";
public static boolean printInstructionError = true;
private String type ="main";
private String name;
private String globeName;
/**
* 指令
*/
private Instruction[] instructionList = new Instruction[0];
/**
* 函数和宏定义
*/
private Map<String,FunctionInstructionSet> functionDefine = new HashMap<String,FunctionInstructionSet>();
//为了增加性能,开始的时候缓存为数组
private Map<String,Object> cacheFunctionSet = null;
private List<ExportItem> exportVar = new ArrayList<ExportItem>();
/**
* 函数参数定义
*/
private List<OperateDataLocalVar> parameterList = new ArrayList<OperateDataLocalVar>();
public static int getUniqClassIndex(){
return uniqIndex.getAndIncrement();
}
public InstructionSet(String aType){
this.type = aType;
}
public String[] getOutFunctionNames() throws Exception {
Map<String,String> result = new TreeMap<String,String>();
for (int i = 0; i < instructionList.length; i++) {
Instruction instruction = instructionList[i];
if (instruction instanceof InstructionCallSelfDefineFunction) {
String functionName = ((InstructionCallSelfDefineFunction)instruction).getFunctionName();
if(!functionDefine.containsKey(functionName)) {
result.put(functionName, null);
}
}
}
return result.keySet().toArray(new String[0]);
}
public String[] getOutAttrNames() throws Exception{
Map<String,String> result = new TreeMap<String,String>();
for(Instruction instruction:instructionList){
if(instruction instanceof InstructionLoadAttr){
if("null".equals(((InstructionLoadAttr)instruction).getAttrName())){
continue;
}
result.put(((InstructionLoadAttr)instruction).getAttrName(),null);
}
}
//剔除本地变量定义和别名定义
for (int i = 0; i < instructionList.length; i++) {
Instruction instruction = instructionList[i];
if (instruction instanceof InstructionOperator) {
String opName = ((InstructionOperator) instruction)
.getOperator().getName();
if (opName.equalsIgnoreCase("def")
|| opName.equalsIgnoreCase("exportDef")) {
String varLocalName = (String) ((InstructionConstData) instructionList[i - 1])
.getOperateData().getObject(null);
result.remove(varLocalName);
} else if (opName.equalsIgnoreCase("alias")
|| opName.equalsIgnoreCase("exportAlias")) {
String varLocalName = (String) ((InstructionConstData) instructionList[i - 2])
.getOperateData().getObject(null);
result.remove(varLocalName);
}
}
}
return result.keySet().toArray(new String[0]);
}
/**
* 添加指令,为了提高运行期的效率,指令集用数组存储
* @param item
* @return
*/
private void addArrayItem(Instruction item){
Instruction[] newArray = new Instruction[this.instructionList.length + 1];
System.arraycopy(this.instructionList, 0, newArray, 0, this.instructionList.length);
newArray[this.instructionList.length] = item;
this.instructionList = newArray;
}
/**
* 插入数据
* @param aPoint
* @param item
*/
private void insertArrayItem(int aPoint,Instruction item){
Instruction[] newArray = new Instruction[this.instructionList.length + 1];
System.arraycopy(this.instructionList, 0, newArray, 0, aPoint);
System.arraycopy(this.instructionList, aPoint, newArray, aPoint + 1,this.instructionList.length - aPoint);
newArray[aPoint] = item;
this.instructionList = newArray;
}
/**
*
* @param environmen
* @param context
* @param errorList
* @param isReturnLastData 是否最后的结果,主要是在执行宏定义的时候需要
* @param aLog
* @return
* @throws Exception
*/
public CallResult excute(RunEnvironment environmen,InstructionSetContext context,
List<String> errorList,boolean isReturnLastData,Log aLog)
throws Exception {
//将函数export到上下文中,这儿就是重入也没有关系,不需要考虑并发
if(cacheFunctionSet == null){
Map<String,Object> tempMap = new HashMap<String,Object>();
for(FunctionInstructionSet s : this.functionDefine.values()){
tempMap.put(s.name,s.instructionSet);
}
cacheFunctionSet = tempMap;
}
context.addSymbol(cacheFunctionSet);
this.executeInnerOrigiInstruction(environmen, errorList, aLog);
if (environmen.isExit() == false) {// 是在执行完所有的指令后结束的代码
if (environmen.getDataStackSize() > 0) {
OperateData tmpObject = environmen.pop();
if (tmpObject == null) {
environmen.quitExpress(null);
} else {
if(isReturnLastData == true){
if(tmpObject.getType(context) != null && tmpObject.getType(context).equals(void.class)){
environmen.quitExpress(null);
}else{
environmen.quitExpress(tmpObject.getObject(context));
}
}else{
environmen.quitExpress(tmpObject);
}
}
}
}
if (environmen.getDataStackSize() > 1) {
throw new Exception("在表达式执行完毕后,堆栈中还存在多个数据");
}
CallResult result = OperateDataCacheManager.fetchCallResult(environmen.getReturnValue(), environmen.isExit());
return result;
}
public void executeInnerOrigiInstruction(RunEnvironment environmen,List<String> errorList,Log aLog) throws Exception{
Instruction instruction =null;
try {
while (environmen.programPoint < this.instructionList.length) {
// if (environmen.isExit() == true) {
// return;
// }
instruction = this.instructionList[environmen.programPoint];
instruction.setLog(aLog);// 设置log
instruction.execute(environmen, errorList);
}
} catch (Exception e) {
if (printInstructionError) {
log.error("当前ProgramPoint = " + environmen.programPoint);
log.error("当前指令" + instruction);
log.error(e);
}
throw e;
}
}
public int getInstructionLength(){
return this.instructionList.length;
}
public void addMacroDefine(String macroName,FunctionInstructionSet iset){
this.functionDefine.put(macroName, iset);
}
public FunctionInstructionSet getMacroDefine(String macroName){
return this.functionDefine.get(macroName);
}
public FunctionInstructionSet[] getFunctionInstructionSets(){
return this.functionDefine.values().toArray(new FunctionInstructionSet[0]);
}
public void addExportDef(ExportItem e){
this.exportVar.add(e);
}
public List<ExportItem> getExportDef(){
List<ExportItem> result = new ArrayList<ExportItem> ();
result.addAll(this.exportVar);
return result;
}
public OperateDataLocalVar[] getParameters() {
return this.parameterList.toArray(new OperateDataLocalVar[0]);
}
public void addParameter(OperateDataLocalVar localVar) {
this.parameterList.add(localVar);
}
public void addInstruction(Instruction instruction){
this.addArrayItem(instruction);
}
public void insertInstruction(int point,Instruction instruction){
this.insertArrayItem(point, instruction);
}
public Instruction getInstruction(int point){
return this.instructionList[point];
}
public int getCurrentPoint(){
return this.instructionList.length - 1;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGlobeName() {
return globeName;
}
public void setGlobeName(String globeName) {
this.globeName = globeName;
}
public boolean hasMain(){
return this.instructionList.length >0;
}
public String getType() {
return type;
}
public void appendSpace(StringBuffer buffer,int level){
for(int i=0;i<level;i++){
buffer.append(" ");
}
}
public String toString() {
return "\n" + toString(0);
}
public String toString(int level) {
try {
StringBuffer buffer = new StringBuffer();
// 输出宏定义
for (FunctionInstructionSet set : this.functionDefine.values()) {
appendSpace(buffer,level);
buffer.append(set.type + ":" + set.name).append("(");
for (int i=0;i<set.instructionSet.parameterList.size();i++) {
OperateDataLocalVar var = set.instructionSet.parameterList.get(i);
if(i > 0){
buffer.append(",");
}
buffer.append(var.getType(null).getName()).append(" ").append(var.getName());
}
buffer.append("){\n");
buffer.append(set.instructionSet.toString(level + 1));
appendSpace(buffer,level);
buffer.append("}\n");
}
for (int i = 0; i < this.instructionList.length; i++) {
appendSpace(buffer,level);
buffer.append(i + 1).append(":").append(this.instructionList[i])
.append("\n");
}
return buffer.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package com.ql.util.express;
import java.util.HashMap;
import java.util.Map;
import com.ql.util.express.instruction.OperateDataCacheManager;
public class InstructionSetContext implements IExpressContext<String,Object> {
/*
* 没有知道数据类型的变量定义是否传递到最外层的Context
*/
private boolean isExpandToParent = true;
private IExpressContext<String,Object> parent = null;
private Map<String,Object> content;
/**
* 符号表
*/
private Map<String,Object> symbolTable =new HashMap<String,Object>();
private ExpressLoader expressLoader;
private boolean isSupportDynamicFieldName = false;
public ExpressRunner getRunner() {
return runner;
}
private ExpressRunner runner;
public InstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext<String,Object> aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
this.initial(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
}
public void initial(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext<String,Object> aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
this.isExpandToParent = aIsExpandToParent;
this.runner = aRunner;
this.parent = aParent;
this.expressLoader = aExpressLoader;
this.isSupportDynamicFieldName = aIsSupportDynamicFieldName;
}
public void clear(){
isExpandToParent = true;
parent = null;
content = null;
expressLoader = null;
isSupportDynamicFieldName = false;
runner = null;
symbolTable.clear();
}
public void exportSymbol(String varName,Object aliasNameObject) throws Exception{
if( this.parent != null && this.parent instanceof InstructionSetContext){
((InstructionSetContext)this.parent).exportSymbol(varName, aliasNameObject);
}else{
this.addSymbol(varName, aliasNameObject);
}
}
public void addSymbol(String varName,Object aliasNameObject) throws Exception{
if(this.symbolTable.containsKey(varName)){
throw new Exception("变量" + varName + "已经存在,不能重复定义,也不能再从函数内部 exprot ");
}
this.symbolTable.put(varName,aliasNameObject);
}
public void addSymbol(Map<String,Object> aliasNameObjects) throws Exception{
this.symbolTable.putAll(aliasNameObjects);
}
public void setSupportDynamicFieldName(boolean isSupportDynamicFieldName) {
this.isSupportDynamicFieldName = isSupportDynamicFieldName;
}
public boolean isSupportDynamicFieldName(){
return this.isSupportDynamicFieldName;
}
public ExpressRunner getExpressRunner(){
return this.runner;
}
public Object findAliasOrDefSymbol(String varName)throws Exception{
Object result = this.symbolTable.get(varName);
if(result == null){
if( this.parent != null && this.parent instanceof InstructionSetContext){
result = ((InstructionSetContext)this.parent).findAliasOrDefSymbol(varName);
}else{
result = null;
}
}
return result;
}
public Object getSymbol(String varName) throws Exception{
Object result = this.symbolTable.get(varName);
if( result == null && this.expressLoader != null){
result = this.expressLoader.getInstructionSet(varName);
}
if(result == null){
if (this.isExpandToParent == true && this.parent != null
&& this.parent instanceof InstructionSetContext) {
result = ((InstructionSetContext) this.parent)
.getSymbol(varName);
} else {
result = OperateDataCacheManager.fetchOperateDataAttr(varName, null);
this.addSymbol(varName, result);
}
}
return result;
}
public ExpressLoader getExpressLoader() {
return expressLoader;
}
public IExpressContext<String,Object> getParent(){
return this.parent;
}
public Object get(Object key){
if(this.content != null && this.content.containsKey(key)){
return this.content.get(key);
}else if(this.isExpandToParent == true && this.parent != null){
return this.parent.get(key);
}
return null;
}
public Object put(String key, Object value){
if(this.content != null && this.content.containsKey(key) ){
return this.content.put(key,value);
}else if (this.isExpandToParent == false){
if(this.content == null){
this.content = new HashMap<String,Object>();
}
return this.content.put(key,value);
}else if(this.parent != null){
return this.parent.put(key,value);
}else{
throw new RuntimeException("没有定义局部变量:" + key +",而且没有全局上下文");
}
}
}
package com.ql.util.express;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ql.util.express.instruction.OperateDataCacheManager;
public class InstructionSetRunner {
private static final Log log = LogFactory.getLog(InstructionSetRunner.class);
public static Object executeOuter(ExpressRunner runner,InstructionSet sets,ExpressLoader loader,
IExpressContext<String,Object> aContext, List<String> errorList,
boolean isTrace,boolean isCatchException,
Log aLog,boolean isSupportDynamicFieldName) throws Exception{
try{
OperateDataCacheManager.push(runner);
return execute(runner,sets, loader, aContext, errorList, isTrace, isCatchException,true, aLog,isSupportDynamicFieldName);
}finally{
OperateDataCacheManager.resetCache(runner);
}
}
/**
* 批量执行指令集合,指令集间可以共享 变量和函数
* @param runner
* @param sets
* @param loader
* @param aContext
* @param errorList
* @param isTrace
* @param isCatchException
* @param isReturnLastData
* @param aLog
* @param isSupportDynamicFieldName
* @return
* @throws Exception
*/
public static Object execute(ExpressRunner runner,InstructionSet sets,ExpressLoader loader,
IExpressContext<String,Object> aContext, List<String> errorList,
boolean isTrace,boolean isCatchException,
boolean isReturnLastData,Log aLog,boolean isSupportDynamicFieldName)
throws Exception {
InstructionSetContext context = OperateDataCacheManager.fetchInstructionSetContext (
true,runner,aContext,loader,isSupportDynamicFieldName);
Object result = execute(sets,context,errorList,isTrace,isCatchException,isReturnLastData,aLog);
return result;
}
public static Object execute(InstructionSet set,
InstructionSetContext context, List<String> errorList, boolean isTrace,boolean isCatchException,
boolean isReturnLastData,Log aLog) throws Exception {
RunEnvironment environmen = null;
Object result = null;
environmen = OperateDataCacheManager.fetRunEnvironment(set,
(InstructionSetContext) context, isTrace);
try {
CallResult tempResult = set.excute(environmen, context, errorList,
isReturnLastData, aLog);
if (tempResult.isExit() == true) {
result = tempResult.getReturnValue();
}
} catch (Exception e) {
if (isCatchException == true) {
if (aLog != null) {
aLog.error(e.getMessage(), e);
} else {
log.error(e.getMessage(), e);
}
} else {
throw e;
}
}
return result;
}
}
package com.ql.util.express;
import java.util.HashMap;
import java.util.Map;
/**
* 作为表达式
* @author tianqiao
*
*/
public class LocalExpressCacheRunner extends ExpressRemoteCacheRunner{
private static Map<String,Object> expressMap = new HashMap<String,Object> ();
private ExpressRunner expressRunner;
public LocalExpressCacheRunner(ExpressRunner expressRunner){
this.expressRunner = expressRunner;
}
@Override
public final Object getCache(String key) {
return expressMap.get(key);
}
@Override
public final void putCache(String key, Object object) {
expressMap.put(key, object);
}
@Override
public final ExpressRunner getExpressRunner() {
return this.expressRunner;
}
}
package com.ql.util.express;
/**
* 数据类型定义
* @author qhlhl2010@gmail.com
*
*/
public class OperateData implements java.io.Serializable {
private static final long serialVersionUID = 4749348640699065036L;
protected Object dataObject;
protected Class<?> type;
public OperateData(Object obj, Class<?> aType) {
this.type = aType;
this.dataObject = obj;
}
/**
* 给对象缓存接口使用
* @param obj
* @param aType
*/
public void initial(Object obj, Class<?> aType) {
this.type = aType;
this.dataObject = obj;
}
public void clear(){
this.dataObject = null;
this.type = null;
}
public Class<?> getDefineType(){
throw new RuntimeException(this.getClass().getName() + "必须实现方法:getDefineType");
}
public Class<?> getOrgiType(){
return this.type;
}
public Class<?> getType(InstructionSetContext parent) throws Exception {
if (type != null)
return type;
Object obj = this.getObject(parent);
if (obj == null)
return null;
else
return obj.getClass();
}
public final Object getObject(InstructionSetContext context) throws Exception {
if(this.type != null && this.type.equals(void.class)){
throw new Exception("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句");
}
return getObjectInner(context);
}
public Object getObjectInner(InstructionSetContext context) throws Exception{
return this.dataObject;
}
public void setObject(InstructionSetContext parent, Object object) throws Exception {
throw new RuntimeException("必须在子类中实现此方法");
}
public String toJavaCode(){
if(this.getClass().equals(OperateData.class) == false){
throw new RuntimeException(this.getClass().getName() + "没有实现:toJavaCode()");
}
String result ="new " + OperateData.class.getName() +"(";
if(String.class.equals(this.type)){
result = result + "\"" + this.dataObject + "\"";
}else if(this.type.isPrimitive()){
result = result + this.dataObject.getClass().getName() +".valueOf(\"" + this.dataObject + "\")";
}else{
result = result + "new " + this.dataObject.getClass().getName() + "(\"" + this.dataObject.toString() + "\")";
}
result = result + "," + type.getName() + ".class";
result = result + ")";
return result;
}
public String toString() {
if( this.dataObject == null)
return this.type + ":null";
else{
if(this.dataObject instanceof Class){
return ExpressUtil.getClassName((Class<?>)this.dataObject);
}else{
return this.dataObject.toString();
}
}
}
public void toResource(StringBuilder builder,int level){
if(this.dataObject != null){
builder.append(this.dataObject.toString());
}else{
builder.append("null");
}
}
}
package com.ql.util.express;
import com.ql.util.express.instruction.OperateDataCacheManager;
import com.ql.util.express.instruction.op.OperatorBase;
/**
* 操作符的基类
* @author xuannan
*
*/
public abstract class Operator extends OperatorBase{
public OperateData executeInner(InstructionSetContext context, ArraySwap list) throws Exception{
Object[] parameters = new Object[list.length];
for(int i = 0;i <list.length;i++){
parameters[i] = list.get(i).getObject(context);
}
Object result = this.executeInner(parameters);
if(result != null && result.getClass().equals(OperateData.class)){
throw new Exception("操作符号定义的返回类型错误:" + this.getAliasName());
}
if(result == null){
//return new OperateData(null,null);
return OperateDataCacheManager.fetchOperateData(null, null);
}else{
//return new OperateData(result,ExpressUtil.getSimpleDataType(result.getClass()));
return OperateDataCacheManager.fetchOperateData(result,ExpressUtil.getSimpleDataType(result.getClass()));
}
}
public abstract Object executeInner(Object[] list) throws Exception;
/**
* 进行对象比较
* @param op1
* @param op2
* @return 0--等于 ,负数 < , 正数 >
* @throws Exception
*/
public static int compareData(Object op1,Object op2) throws Exception{
int compareResult = -1;
if(op1 instanceof String){
compareResult = ((String)op1).compareTo(op2.toString());
}else if(op2 instanceof String){
compareResult = op1.toString().compareTo((String)op2);
}else if(op1 instanceof Number && op2 instanceof Number){
//数字比较
compareResult = OperatorOfNumber.compareNumber((Number)op1, (Number)op2);
}
else if ((op1 instanceof Boolean) && (op2 instanceof Boolean))
{
if (((Boolean)op1).booleanValue() ==((Boolean)op2).booleanValue())
compareResult =0;
else
compareResult =-1;
}
else
throw new Exception(op1 + "和" + op2 +"不能执行compare 操作");
return compareResult;
}
}
package com.ql.util.express;
import java.math.BigDecimal;
/**
* 数字运行函数集合
* @author qhlhl2010@gmail.com
*
*/
interface NumberType{
public int NUMBER_TYPE_BYTE = 1;
public int NUMBER_TYPE_SHORT = 2;
public int NUMBER_TYPE_INT = 3;
public int NUMBER_TYPE_LONG = 4;
public int NUMBER_TYPE_FLOAT = 5;
public int NUMBER_TYPE_DOUBLE = 6;
public int NUMBER_TYPE_BIGDECIMAL = 7;
}
public class OperatorOfNumber {
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 获取数据类型精度顺序
* @param aClass
* @return
*/
public static int getSeq(Class<?> aClass){
if(aClass == Byte.class || aClass == byte.class) return NumberType.NUMBER_TYPE_BYTE;
if(aClass == Short.class || aClass == short.class) return NumberType.NUMBER_TYPE_SHORT;
if(aClass == Integer.class || aClass == int.class) return NumberType.NUMBER_TYPE_INT;
if(aClass == Long.class || aClass == long.class) return NumberType.NUMBER_TYPE_LONG;
if(aClass == Float.class || aClass == float.class) return NumberType.NUMBER_TYPE_FLOAT;
if(aClass == Double.class || aClass == double.class) return NumberType.NUMBER_TYPE_DOUBLE;
if(aClass == BigDecimal.class) return NumberType.NUMBER_TYPE_BIGDECIMAL;
throw new RuntimeException("不能处理的数据类型:" + aClass.getName());
}
/**
* 进行数据类型转换
* @param value
* @param type
* @return
*/
public static Number transfer(Number value,Class<?> type,boolean isForce){
if (isForce == true || value instanceof BigDecimal == false) {
if (type.equals(byte.class) || type.equals(Byte.class)) {
return ((Number) value).byteValue();
} else if (type.equals(short.class) || type.equals(Short.class)) {
return ((Number) value).shortValue();
} else if (type.equals(int.class) || type.equals(Integer.class)) {
return ((Number) value).intValue();
} else if (type.equals(long.class) || type.equals(Long.class)) {
return ((Number) value).longValue();
} else if (type.equals(float.class) || type.equals(Float.class)) {
return ((Number) value).floatValue();
} else if (type.equals(double.class)
|| type.equals(Double.class)) {
return ((Number) value).doubleValue();
} else if (type.equals(BigDecimal.class)) {
return new BigDecimal(value.toString());
}else{
throw new RuntimeException("没有处理的数据类型:" + type.getName());
}
} else {
if (type.equals(byte.class) || type.equals(Byte.class)) {
if(((BigDecimal)value).scale() >0 ){
throw new RuntimeException("有小数位,不能转化为:"+ type.getName());
}
return ((Number) value).byteValue();
} else if (type.equals(short.class) || type.equals(Short.class)) {
if(((BigDecimal)value).scale() >0 ){
throw new RuntimeException("有小数位,不能转化为:"+ type.getName());
}
return ((Number) value).shortValue();
} else if (type.equals(int.class) || type.equals(Integer.class)) {
if(((BigDecimal)value).scale() >0 ){
throw new RuntimeException("有小数位,不能转化为:"+ type.getName());
}
return ((Number) value).intValue();
} else if (type.equals(long.class) || type.equals(Long.class)) {
if(((BigDecimal)value).scale() >0 ){
throw new RuntimeException("有小数位,不能转化为:"+ type.getName());
}
return ((Number) value).longValue();
} else if (type.equals(float.class) || type.equals(Float.class)) {
return ((Number) value).floatValue();
} else if (type.equals(double.class)
|| type.equals(Double.class)) {
return ((Number) value).doubleValue();
}else{
throw new RuntimeException("没有处理的数据类型:" + type.getName());
}
}
}
public static int compareNumber(Number op1, Number op2){
int type1 = OperatorOfNumber.getSeq(op1.getClass());
int type2 = OperatorOfNumber.getSeq(op2.getClass());
int type = type1 > type2 ? type1:type2;
if(type == 1) {
byte o1 = ((Number)op1).byteValue();
byte o2 = ((Number)op2).byteValue();
if(o1 == o2) return 0;
if(o1 < o2) return -1;
return 1;
}
if(type == 2) {
short o1 = ((Number)op1).shortValue();
short o2 = ((Number)op2).shortValue();
if(o1 == o2) return 0;
if(o1 < o2) return -1;
return 1;
}
if(type == 3) {
int o1 = ((Number)op1).intValue();
int o2 = ((Number)op2).intValue();
if(o1 == o2) return 0;
if(o1 < o2) return -1;
return 1;
}
if(type == 4) {
long o1 = ((Number)op1).longValue();
long o2 = ((Number)op2).longValue();
if(o1 == o2) return 0;
if(o1 < o2) return -1;
return 1;
}
if(type == 5) {
float o1 = ((Number)op1).floatValue();
float o2 = ((Number)op2).floatValue();
if(o1 == o2) return 0;
if(o1 < o2) return -1;
return 1;
}
if(type == 6){
double o1 = ((Number)op1).doubleValue();
double o2 = ((Number)op2).doubleValue();
if(o1 == o2) return 0;
if(o1 < o2) return -1;
return 1;
}
if(type == 7){
BigDecimal o1 = new BigDecimal(op1.toString());
BigDecimal o2 = new BigDecimal(op2.toString());
return o1.compareTo(o2);
}
throw new RuntimeException("比较操作错误:op1=" + op1.toString() +",op2=" + op2.toString());
}
public static Object add(Object op1, Object op2,boolean isPrecise) throws Exception {
if(op1 == null){
op1 = "null";
}
if(op2 == null){
op2 = "null";
}
if (op1 instanceof String || op2 instanceof String) {
return op1.toString() + op2.toString();
}
if(isPrecise==true){
return PreciseNumberOperator.addPrecise((Number)op1,(Number)op2);
}else{
return NormalNumberOperator.addNormal((Number)op1,(Number)op2);
}
}
public static Number subtract(Object op1, Object op2,boolean isPrecise) throws Exception {
if(isPrecise==true){
return PreciseNumberOperator.subtractPrecise((Number)op1,(Number)op2);
}else{
return NormalNumberOperator.subtractNormal((Number)op1,(Number)op2);
}
}
public static Number multiply(Object op1, Object op2,boolean isPrecise) throws Exception {
if(isPrecise==true){
return PreciseNumberOperator.multiplyPrecise((Number)op1,(Number)op2);
}else{
return NormalNumberOperator.multiplyNormal((Number)op1,(Number)op2);
}
}
public static Number divide(Object op1, Object op2,boolean isPrecise) throws Exception {
if(isPrecise==true){
return PreciseNumberOperator.dividePrecise((Number)op1,(Number)op2);
}else{
return NormalNumberOperator.divideNormal((Number)op1,(Number)op2);
}
}
public static Object modulo(Object op1,Object op2) throws Exception{
return NormalNumberOperator.moduloNormal((Number)op1,(Number)op2);
}
}
class NormalNumberOperator {
/**
* 普通的加法运算
* @param op1
* @param op2
* @return
* @throws Exception
*/
public static Number addNormal(Number op1, Number op2) throws Exception {
int type1 = OperatorOfNumber.getSeq(op1.getClass());
int type2 = OperatorOfNumber.getSeq(op2.getClass());
int type = type1 > type2 ? type1:type2;
if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() + op2.byteValue();
if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() + op2.shortValue();
if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() + op2.intValue();
if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() + op2.longValue();
if(type == NumberType.NUMBER_TYPE_FLOAT) return op1.floatValue() + op2.floatValue();
if(type == NumberType.NUMBER_TYPE_DOUBLE) return op1.doubleValue() + op2.doubleValue();
if(type == NumberType.NUMBER_TYPE_BIGDECIMAL) return new BigDecimal(op1.toString()).add(new BigDecimal(op2.toString()));
throw new Exception("不支持的对象执行了\"+\"操作");
}
public static Number subtractNormal(Number op1,Number op2) throws Exception{
int type1 = OperatorOfNumber.getSeq(op1.getClass());
int type2 = OperatorOfNumber.getSeq(op2.getClass());
int type = type1 > type2 ? type1:type2;
if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() - op2.byteValue();
if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() - op2.shortValue();
if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() - op2.intValue();
if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() - op2.longValue();
if(type == NumberType.NUMBER_TYPE_FLOAT) return op1.floatValue() - op2.floatValue();
if(type == NumberType.NUMBER_TYPE_DOUBLE) return op1.doubleValue() - op2.doubleValue();
if(type == NumberType.NUMBER_TYPE_BIGDECIMAL) return new BigDecimal(op1.toString()).subtract(new BigDecimal(op2.toString()));
throw new Exception("不支持的对象执行了\"-\"操作");
}
public static Number multiplyNormal(Number op1,Number op2) throws Exception {
int type1 = OperatorOfNumber.getSeq(op1.getClass());
int type2 = OperatorOfNumber.getSeq(op2.getClass());
int type = type1 > type2 ? type1:type2;
if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() * op2.byteValue();
if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() * op2.shortValue();
if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() * op2.intValue();
if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() * op2.longValue();
if(type == NumberType.NUMBER_TYPE_FLOAT) return op1.floatValue() * op2.floatValue();
if(type == NumberType.NUMBER_TYPE_DOUBLE) return op1.doubleValue() * op2.doubleValue();
if(type == NumberType.NUMBER_TYPE_BIGDECIMAL) return new BigDecimal(op1.toString()).multiply(new BigDecimal(op2.toString()));
throw new Exception("不支持的对象执行了\"*\"操作");
}
public static Number divideNormal(Number op1,Number op2) throws Exception{
int type1 = OperatorOfNumber.getSeq(op1.getClass());
int type2 = OperatorOfNumber.getSeq(op2.getClass());
int type = type1 > type2 ? type1:type2;
if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() / op2.byteValue();
if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() / op2.shortValue();
if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() / op2.intValue();
if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() / op2.longValue();
if(type == NumberType.NUMBER_TYPE_FLOAT) return op1.floatValue() / op2.floatValue();
if(type == NumberType.NUMBER_TYPE_DOUBLE) return op1.doubleValue() / op2.doubleValue();
if(type == NumberType.NUMBER_TYPE_BIGDECIMAL) return new BigDecimal(op1.toString()).divide(new BigDecimal(op2.toString()), BigDecimal.ROUND_HALF_UP);
throw new Exception("不支持的对象执行了\"/\"操作");
}
public static Number moduloNormal(Number op1,Number op2) throws Exception{
int type1 = OperatorOfNumber.getSeq(op1.getClass());
int type2 = OperatorOfNumber.getSeq(op2.getClass());
int type = type1 > type2 ? type1:type2;
if(type == NumberType.NUMBER_TYPE_BYTE) return op1.byteValue() % op2.byteValue();
if(type == NumberType.NUMBER_TYPE_SHORT) return op1.shortValue() % op2.shortValue();
if(type == NumberType.NUMBER_TYPE_INT) return op1.intValue() % op2.intValue();
if(type == NumberType.NUMBER_TYPE_LONG) return op1.longValue() % op2.longValue();
throw new Exception("不支持的对象执行了\"mod\"操作");
}
}
/**
* 高精度计算
* @author xuannan
*/
class PreciseNumberOperator {
public static int DIVIDE_PRECISION = 10;
public static Number addPrecise(Number op1, Number op2) throws Exception {
BigDecimal result = null;
if(op1 instanceof BigDecimal){
if(op2 instanceof BigDecimal){
result = ((BigDecimal)op1).add((BigDecimal)op2);
}else{
result = ((BigDecimal)op1).add(new BigDecimal(op2.toString()));
}
}else{
if(op2 instanceof BigDecimal){
result = new BigDecimal(op1.toString()).add((BigDecimal)op2);
}else{
result = new BigDecimal(op1.toString()).add(new BigDecimal(op2.toString()));
}
}
if(result.scale() ==0){
long tempLong = result.longValue();
if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
return (int)tempLong;
}else{
return tempLong;
}
}else{
return result;
}
}
public static Number subtractPrecise(Number op1, Number op2) throws Exception {
BigDecimal result = null;
if(op1 instanceof BigDecimal){
if(op2 instanceof BigDecimal){
result = ((BigDecimal)op1).subtract((BigDecimal)op2);
}else{
result = ((BigDecimal)op1).subtract(new BigDecimal(op2.toString()));
}
}else{
if(op2 instanceof BigDecimal){
result = new BigDecimal(op1.toString()).subtract((BigDecimal)op2);
}else{
result = new BigDecimal(op1.toString()).subtract(new BigDecimal(op2.toString()));
}
}
if(result.scale() ==0){
long tempLong = result.longValue();
if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
return (int)tempLong;
}else{
return tempLong;
}
}else{
return result;
}
}
public static Number multiplyPrecise(Number op1, Number op2) throws Exception {
BigDecimal result = null;
if(op1 instanceof BigDecimal){
if(op2 instanceof BigDecimal){
result = ((BigDecimal)op1).multiply((BigDecimal)op2);
}else{
result = ((BigDecimal)op1).multiply(new BigDecimal(op2.toString()));
}
}else{
if(op2 instanceof BigDecimal){
result = new BigDecimal(op1.toString()).multiply((BigDecimal)op2);
}else{
result = new BigDecimal(op1.toString()).multiply(new BigDecimal(op2.toString()));
}
}
if(result.scale() ==0){
long tempLong = result.longValue();
if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
return (int)tempLong;
}else{
return tempLong;
}
}else{
return result;
}
}
public static Number dividePrecise(Number op1, Number op2) throws Exception {
BigDecimal result = null;
if(op1 instanceof BigDecimal){
if(op2 instanceof BigDecimal){
result = ((BigDecimal)op1).divide((BigDecimal)op2, DIVIDE_PRECISION, BigDecimal.ROUND_HALF_UP);
}else{
result = ((BigDecimal)op1).divide(new BigDecimal(op2.toString()), DIVIDE_PRECISION, BigDecimal.ROUND_HALF_UP);
}
}else{
if(op2 instanceof BigDecimal){
result = new BigDecimal(op1.toString()).divide((BigDecimal)op2, DIVIDE_PRECISION, BigDecimal.ROUND_HALF_UP);
}else{
result = new BigDecimal(op1.toString()).divide(new BigDecimal(op2.toString()), DIVIDE_PRECISION, BigDecimal.ROUND_HALF_UP);
}
}
if(result.scale() ==0){
long tempLong = result.longValue();
if(tempLong <= Integer.MAX_VALUE && tempLong >= Integer.MIN_VALUE){
return (int)tempLong;
}else{
return tempLong;
}
}else{
return result;
}
}
}
package com.ql.util.express;
public final class RunEnvironment {
private static int INIT_DATA_LENTH = 15;
private boolean isTrace = false;
private int point = -1;
protected int programPoint = 0;
private OperateData[] dataContainer;
private ArraySwap arraySwap = new ArraySwap();
private boolean isExit = false;
private Object returnValue = null;
private InstructionSet instructionSet;
private InstructionSetContext context;
public RunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){
dataContainer = new OperateData[INIT_DATA_LENTH];
this.instructionSet = aInstructionSet;
this.context = aContext;
this.isTrace = aIsTrace;
}
public void initial(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){
this.instructionSet = aInstructionSet;
this.context = aContext;
this.isTrace = aIsTrace;
}
public void clear(){
isTrace = false;
point = -1;
programPoint = 0;
isExit = false;
returnValue = null;
instructionSet = null;
context = null;
}
public InstructionSet getInstructionSet() {
return instructionSet;
}
public InstructionSetContext getContext(){
return this.context;
}
public void setContext(InstructionSetContext aContext){
this.context = aContext;
}
public boolean isExit() {
return isExit;
}
public Object getReturnValue() {
return returnValue;
}
public void setReturnValue(Object value){
this.returnValue = value;
}
public void quitExpress(Object aReturnValue){
this.isExit = true;
this.returnValue = aReturnValue;
}
public void quitExpress(){
this.isExit = true;
this.returnValue = null;
}
public boolean isTrace(){
return this.isTrace;
}
public int getProgramPoint() {
return programPoint;
}
public void programPointAddOne() {
programPoint ++ ;
}
public void gotoLastWhenReturn(){
programPoint = this.instructionSet.getInstructionLength();
}
public int getDataStackSize(){
return this.point + 1;
}
public void push(OperateData data){
this.point++;
if(this.point >= this.dataContainer.length){
ensureCapacity(this.point + 1);
}
this.dataContainer[point] = data;
}
public OperateData peek(){
if(point <0){
throw new RuntimeException("系统异常,堆栈指针错误");
}
return this.dataContainer[point];
}
public OperateData pop(){
if(point <0)
throw new RuntimeException("系统异常,堆栈指针错误");
OperateData result = this.dataContainer[point];
this.point--;
return result;
}
public void clearDataStack(){
this.point = -1;
}
public void gotoWithOffset(int aOffset ){
this.programPoint = this.programPoint + aOffset;
}
/**
* 此方法是调用最频繁的,因此尽量精简代码,提高效率
* @param context
* @param len
* @return
* @throws Exception
*/
public ArraySwap popArray(InstructionSetContext context,int len) throws Exception {
int start = point - len + 1;
this.arraySwap.swap(this.dataContainer,start,len);
point = point - len;
return this.arraySwap;
}
public OperateData[] popArrayOld(InstructionSetContext context,int len) throws Exception {
int start = point - len + 1;
OperateData[] result = new OperateData[len];
System.arraycopy(this.dataContainer,start, result,0, len);
point = point - len;
return result;
}
public OperateData[] popArrayBackUp(InstructionSetContext context,int len) throws Exception {
int start = point - len + 1;
if(start <0){
throw new Exception("堆栈溢出,请检查表达式是否错误");
}
OperateData[] result = new OperateData[len];
for (int i = 0 ; i < len; i++) {
result[i] = this.dataContainer[start + i];
if(void.class.equals(result[i].getType(context))){
throw new Exception("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句");
}
}
point = point - len;
return result;
}
public void ensureCapacity(int minCapacity) {
int oldCapacity = this.dataContainer.length;
if (minCapacity > oldCapacity) {
int newCapacity = (oldCapacity * 3) / 2 + 1;
if (newCapacity < minCapacity){
newCapacity = minCapacity;
}
OperateData[] tempList = new OperateData[newCapacity];
System.arraycopy(this.dataContainer,0,tempList,0,oldCapacity);
this.dataContainer = tempList;
}
}
}
package com.ql.util.express.console;
import java.awt.Toolkit;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.Dimension;
public class Console {
boolean packFrame = false;
/**
* Construct and show the application.
*/
public Console() {
ConsoleFrame frame = new ConsoleFrame();
// Validate frames that have preset sizes
// Pack frames that have useful preferred size info, e.g. from their layout
if (packFrame) {
frame.pack();
}
else {
frame.validate();
}
// Center the window
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
frameSize.height = screenSize.height;
frameSize.width = screenSize.width;
frame.setLocation(0,0);
frame.setVisible(true);
}
/**
* Application entry point.
*
* @param args String[]
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception exception) {
exception.printStackTrace();
}
new Console();
}
});
}
}
package com.ql.util.express.console;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.tree.TreePath;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.console.FileTree.PathNode;
public class ConsoleFrame
extends JFrame {
private static final long serialVersionUID = 1L;
JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
JMenuBar jMenuBar1 = new JMenuBar();
JMenu jMenuFile = new JMenu();
JMenuItem jMenuFileExit = new JMenuItem();
JToolBar jToolBar = new JToolBar();
JButton jButton1 = new JButton();
ImageIcon image1 = new ImageIcon(com.ql.util.express.console.ConsoleFrame.class.
getResource("run.png"));
JLabel statusBar = new JLabel();
JTabbedPane jTabbedPaneContent = new JTabbedPane();
JPanel jPaneRunner = new JPanel();
JSplitPane jSplitPaneRun = new JSplitPane();
BorderLayout borderLayout2 = new BorderLayout();
JTextArea jTextAreaScript = new JTextArea();
JScrollPane jScrollPaneScript = new JScrollPane();
JSplitPane jSplitPaneS_C = new JSplitPane();
JScrollPane jScrollPaneContext = new JScrollPane();
JScrollPane jScrollPaneResult = new JScrollPane();
JTextArea jTextAreaContext = new JTextArea();
JTextArea jTextAreaResult = new JTextArea();
JPanel jPanelResult = new JPanel();
BorderLayout borderLayout3 = new BorderLayout();
JLabel jLabelScript = new JLabel();
JLabel jLabelResult = new JLabel();
JLabel jLabelContext = new JLabel();
JPanel jPanelScript = new JPanel();
BorderLayout borderLayout4 = new BorderLayout();
JPanel jPanelContext = new JPanel();
BorderLayout borderLayout5 = new BorderLayout();
StringBufferOutputStream output = new StringBufferOutputStream(jTextAreaResult);
public ConsoleFrame() {
try {
setDefaultCloseOperation(EXIT_ON_CLOSE);
jbInit();
PrintStream ps = new PrintStream(output,true);
System.setOut(ps);
} catch (Exception exception) {
exception.printStackTrace();
}
}
/**
* Component initialization.
*
* @throws java.lang.Exception
*/
private void jbInit() throws Exception {
contentPane = (JPanel) getContentPane();
contentPane.setLayout(borderLayout1);
setSize(new Dimension(1000, 600));
setTitle("QLExpressConsole");
statusBar.setText(" ");
jMenuFile.setText("File");
jMenuFileExit.setText("Exit");
jMenuFileExit.addActionListener(new
ConsoleFrame_jMenuFileExit_ActionAdapter(this));
jSplitPaneRun.setOrientation(JSplitPane.VERTICAL_SPLIT);
jSplitPaneRun.setDividerSize(2);
jPaneRunner.setLayout(borderLayout2);
jTextAreaScript.setText("");
jTextAreaContext.setText("");
jTextAreaResult.setText("");
contentPane.setMinimumSize(new Dimension(500, 400));
contentPane.setPreferredSize(new Dimension(500, 400));
jButton1.addActionListener(new ConsoleFrame_jButton1_actionAdapter(this));
jPanelResult.setLayout(borderLayout3);
jLabelScript.setText("运行脚本");
jLabelResult.setText("运行结果");
jLabelContext.setText("脚本上下文");
jPanelScript.setLayout(borderLayout4);
jPanelContext.setLayout(borderLayout5);
jMenuBar1.add(jMenuFile);
jMenuFile.add(jMenuFileExit);
setJMenuBar(jMenuBar1);
jButton1.setIcon(image1);
jButton1.setToolTipText("执行");
jToolBar.add(jButton1);
contentPane.add(statusBar, BorderLayout.SOUTH);
jPanelResult.add(jScrollPaneResult, java.awt.BorderLayout.CENTER);
jPanelResult.add(jLabelResult, java.awt.BorderLayout.NORTH);
jSplitPaneRun.add(jSplitPaneS_C, JSplitPane.TOP);
jScrollPaneResult.getViewport().add(jTextAreaResult);
jPanelScript.add(jLabelScript, java.awt.BorderLayout.NORTH);
jPanelScript.add(jScrollPaneScript, java.awt.BorderLayout.CENTER);
jScrollPaneScript.getViewport().add(jTextAreaScript);
jPanelContext.add(jLabelContext, java.awt.BorderLayout.NORTH);
jPanelContext.add(jScrollPaneContext, java.awt.BorderLayout.CENTER);
jSplitPaneS_C.add(jPanelScript, JSplitPane.LEFT);
jScrollPaneContext.getViewport().add(jTextAreaContext);
jSplitPaneS_C.setDividerSize(2);
jSplitPaneS_C.setLastDividerLocation(200);
jSplitPaneS_C.add(jPanelContext, JSplitPane.RIGHT);
jSplitPaneS_C.setDividerLocation(500);
jSplitPaneRun.add(jPanelResult, JSplitPane.RIGHT);
jTabbedPaneContent.add(jPaneRunner, "\u6267\u884c\u4ee3\u7801");
jPaneRunner.add(jSplitPaneRun, java.awt.BorderLayout.CENTER);
contentPane.add(jTabbedPaneContent, java.awt.BorderLayout.CENTER);
contentPane.add(jToolBar, java.awt.BorderLayout.NORTH);
jSplitPaneRun.setDividerLocation(200);
}
/**
* File | Exit action performed.
*
* @param actionEvent ActionEvent
*/
void jMenuFileExit_actionPerformed(ActionEvent actionEvent) {
System.exit(0);
}
public void jButton1_actionPerformed(ActionEvent e) {
String script =jTextAreaScript.getText();
String[] lines = jTextAreaContext.getText().split("\n");
String contextText ="";
for(int i =0;i< lines.length;i++){
if(lines[i].trim().length() >0){
String[] tempStr = lines[i].trim().split(":");
if(contextText.length() >0){
contextText = contextText +",";
}
contextText = contextText +"\"" + tempStr[0] +"\":" + tempStr[1];
}
}
Object r = null;
try {
output.clear();
ExpressRunner runner = new ExpressRunner(false,false);
contextText = "NewMap(" + contextText + ")";
@SuppressWarnings("unchecked")
Map<String,Object> tempMap = (Map<String,Object>)runner.execute(contextText,null,null,false,false);
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
context.putAll(tempMap);
r = runner.execute(script, context, null,false,false);
System.out.print("QL>\n" +
"-------------------原始执行脚本--------------------------------\n" +
script + "\n" +
"-------------------脚本运行结果--------------------------------\n" +
r +"\n" +
"-------------------运行后上下文--------------------------------\n" +
context
+ "\nQL>");
} catch (Exception e1) {
e1.printStackTrace(System.out);
}
}
public void jTreeFileSelect_mouseClicked(MouseEvent me) {
StringWriter writer = new StringWriter();
try {
TreePath tp = ((FileTree)me.getSource()).getPathForLocation(me.getX(), me.getY());
PathNode node = (PathNode)tp.getPath()[tp.getPathCount() -1];
String fileName = node.getValue();
ExampleDefine define = ReadExample.readExampleDefine(fileName);
jTextAreaScript.setText(define.getScript());
jTextAreaContext.setText(define.getContext());
} catch (Exception e) {
e.printStackTrace(new PrintWriter(writer));
}
}
}
class ConsoleFrame_jButton1_actionAdapter
implements ActionListener {
private ConsoleFrame adaptee;
ConsoleFrame_jButton1_actionAdapter(ConsoleFrame adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
try {
adaptee.jButton1_actionPerformed(e);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
class ConsoleFrame_jMenuFileExit_ActionAdapter
implements ActionListener {
ConsoleFrame adaptee;
ConsoleFrame_jMenuFileExit_ActionAdapter(ConsoleFrame adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent actionEvent) {
adaptee.jMenuFileExit_actionPerformed(actionEvent);
}
}
class StringBufferOutputStream extends OutputStream
{
protected ByteArrayOutputStream buffer;
JTextArea jTextArea;
public StringBufferOutputStream(JTextArea aJTextAreaResult)
{
jTextArea = aJTextAreaResult;
buffer = new ByteArrayOutputStream();
}
public void clear(){
this.buffer.reset();
}
public void write(int ch)
throws IOException
{
this.buffer.write(ch);
}
public void flush() throws IOException {
jTextArea.setText(this.buffer.toString());
}
}
package com.ql.util.express.console;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.tree.TreePath;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.console.FileTree.PathNode;
public class ConsoleFrame2
extends JFrame {
private static final long serialVersionUID = 1L;
JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
JMenuBar jMenuBar1 = new JMenuBar();
JMenu jMenuFile = new JMenu();
JMenuItem jMenuFileExit = new JMenuItem();
JToolBar jToolBar = new JToolBar();
JButton jButton1 = new JButton();
ImageIcon image1 = new ImageIcon(com.ql.util.express.console.ConsoleFrame2.class.
getResource("run.png"));
JLabel statusBar = new JLabel();
JSplitPane jSplitPaneMain = new JSplitPane();
FileTree jTreeFileSelect = new FileTree(System.getProperty("user.dir"));
JTabbedPane jTabbedPaneContent = new JTabbedPane();
JPanel jPaneRunner = new JPanel();
JPanel jPanelHelp = new JPanel();
JPanel jPanel3 = new JPanel();
JSplitPane jSplitPaneRun = new JSplitPane();
BorderLayout borderLayout2 = new BorderLayout();
JTextArea jTextAreaScript = new JTextArea();
JScrollPane jScrollPaneScript = new JScrollPane();
JSplitPane jSplitPaneS_C = new JSplitPane();
JScrollPane jScrollPaneContext = new JScrollPane();
JScrollPane jScrollPaneResult = new JScrollPane();
JTextArea jTextAreaContext = new JTextArea();
JTextArea jTextAreaResult = new JTextArea();
JScrollPane jScrollPaneTree = new JScrollPane();
JPanel jPanelResult = new JPanel();
BorderLayout borderLayout3 = new BorderLayout();
JLabel jLabelScript = new JLabel();
JLabel jLabelResult = new JLabel();
JLabel jLabelContext = new JLabel();
JPanel jPanelScript = new JPanel();
BorderLayout borderLayout4 = new BorderLayout();
JPanel jPanelContext = new JPanel();
BorderLayout borderLayout5 = new BorderLayout();
public ConsoleFrame2() {
try {
setDefaultCloseOperation(EXIT_ON_CLOSE);
jbInit();
// PrintStream ps = new PrintStream(System.out) {
// public void println(String x) {
// jTextAreaResult.insert(x,jTextAreaResult.getLineCount());
// }
// };
// System.setOut(ps);
}
catch (Exception exception) {
exception.printStackTrace();
}
}
/**
* Component initialization.
*
* @throws java.lang.Exception
*/
private void jbInit() throws Exception {
contentPane = (JPanel) getContentPane();
contentPane.setLayout(borderLayout1);
setSize(new Dimension(1000, 600));
setTitle("QLExpressConsole");
statusBar.setText(" ");
jMenuFile.setText("File");
jMenuFileExit.setText("Exit");
jMenuFileExit.addActionListener(new
ConsoleFrame_jMenuFileExit_ActionAdapter2(this));
jTreeFileSelect.addMouseListener(new
ConsoleFrame_jTreeFileSelect_mouseAdapter2(this));
jSplitPaneMain.add(jScrollPaneTree, JSplitPane.LEFT);
jSplitPaneMain.add(jTabbedPaneContent, JSplitPane.RIGHT);
jSplitPaneMain.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
jSplitPaneRun.setOrientation(JSplitPane.VERTICAL_SPLIT);
jSplitPaneRun.setDividerSize(2);
jPaneRunner.setLayout(borderLayout2);
jTextAreaScript.setText("");
jTextAreaContext.setText("");
jTextAreaResult.setText("");
contentPane.setMinimumSize(new Dimension(500, 400));
contentPane.setPreferredSize(new Dimension(500, 400));
jButton1.addActionListener(new ConsoleFrame_jButton1_actionAdapter2(this));
jPanelResult.setLayout(borderLayout3);
jLabelScript.setText("运行脚本");
jLabelResult.setText("运行结果");
jLabelContext.setText("脚本上下文");
jPanelScript.setLayout(borderLayout4);
jPanelContext.setLayout(borderLayout5);
jMenuBar1.add(jMenuFile);
jMenuFile.add(jMenuFileExit);
setJMenuBar(jMenuBar1);
jButton1.setIcon(image1);
jButton1.setToolTipText("执行");
jToolBar.add(jButton1);
contentPane.add(statusBar, BorderLayout.SOUTH);
contentPane.add(jSplitPaneMain, java.awt.BorderLayout.CENTER);
jTabbedPaneContent.add(jPaneRunner, "执行代码");
jTabbedPaneContent.add(jPanelHelp, "关键字");
jTabbedPaneContent.add(jPanel3, "帮助");
jPaneRunner.add(jSplitPaneRun, java.awt.BorderLayout.CENTER);
jScrollPaneTree.getViewport().add(this.jTreeFileSelect);
jScrollPaneContext.getViewport().add(jTextAreaContext);
jScrollPaneResult.getViewport().add(jTextAreaResult);
jPanelResult.add(jScrollPaneResult, java.awt.BorderLayout.CENTER);
jPanelResult.add(jLabelResult, java.awt.BorderLayout.NORTH);
jPanelScript.add(jLabelScript, java.awt.BorderLayout.NORTH);
jPanelScript.add(jScrollPaneScript, java.awt.BorderLayout.CENTER);
jScrollPaneScript.getViewport().add(jTextAreaScript);
jPanelContext.add(jLabelContext, java.awt.BorderLayout.NORTH);
jPanelContext.add(jScrollPaneContext, java.awt.BorderLayout.CENTER);
jSplitPaneS_C.setDividerSize(2);
jSplitPaneS_C.setLastDividerLocation(200);
jSplitPaneS_C.add(jPanelContext, JSplitPane.RIGHT);
jSplitPaneS_C.add(jPanelScript, JSplitPane.LEFT);
jSplitPaneS_C.setDividerLocation(500);
jSplitPaneRun.add(jPanelResult, JSplitPane.RIGHT);
jSplitPaneRun.add(jSplitPaneS_C, JSplitPane.TOP);
contentPane.add(jToolBar, java.awt.BorderLayout.NORTH);
contentPane.add(jScrollPaneTree, java.awt.BorderLayout.WEST);
jScrollPaneTree.getViewport().add(jTreeFileSelect);
jSplitPaneRun.setDividerLocation(200);
jSplitPaneMain.setDividerLocation(400);
}
/**
* File | Exit action performed.
*
* @param actionEvent ActionEvent
*/
void jMenuFileExit_actionPerformed(ActionEvent actionEvent) {
System.exit(0);
}
@SuppressWarnings("unchecked")
public void jButton1_actionPerformed(ActionEvent e) {
String script =jTextAreaScript.getText();
String[] lines = jTextAreaContext.getText().split("\n");
String contextText ="";
for(int i =0;i< lines.length;i++){
if(lines[i].trim().length() >0){
String[] tempStr = lines[i].trim().split(":");
if(contextText.length() >0){
contextText = contextText +",";
}
contextText = contextText +"\"" + tempStr[0] +"\":" + tempStr[1];
}
}
Object r = null;
StringWriter writer = new StringWriter();
try {
ExpressRunner runner = new ExpressRunner(false,true);
contextText = "NewMap(" + contextText + ")";
Map<String,Object> tempMap = (Map<String,Object>)runner.execute(contextText,null,null,false,false);
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
context.putAll(tempMap);
r = runner.execute(script, context, null,false,true);
writer.write("QL>\n" +
"-------------------原始执行脚本--------------------------------\n" +
script + "\n" +
"-------------------脚本运行结果--------------------------------\n" +
r +"\n" +
"-------------------运行后上下文--------------------------------\n" +
context
+ "\nQL>");
} catch (Exception e1) {
e1.printStackTrace(new PrintWriter(writer));
}
//System.out.println(writer.toString());
jTextAreaResult.setText(writer.toString());
}
public void jTreeFileSelect_mouseClicked(MouseEvent me) {
StringWriter writer = new StringWriter();
try {
TreePath tp = ((FileTree)me.getSource()).getPathForLocation(me.getX(), me.getY());
PathNode node = (PathNode)tp.getPath()[tp.getPathCount() -1];
String fileName = node.getValue();
ExampleDefine define = ReadExample.readExampleDefine(fileName);
jTextAreaScript.setText(define.getScript());
jTextAreaContext.setText(define.getContext());
} catch (Exception e) {
e.printStackTrace(new PrintWriter(writer));
}
}
}
class ConsoleFrame_jTreeFileSelect_mouseAdapter2
extends MouseAdapter {
private ConsoleFrame2 adaptee;
ConsoleFrame_jTreeFileSelect_mouseAdapter2(ConsoleFrame2 adaptee) {
this.adaptee = adaptee;
}
public void mouseClicked(MouseEvent e) {
adaptee.jTreeFileSelect_mouseClicked(e);
}
}
class ConsoleFrame_jButton1_actionAdapter2
implements ActionListener {
private ConsoleFrame2 adaptee;
ConsoleFrame_jButton1_actionAdapter2(ConsoleFrame2 adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e) {
try {
adaptee.jButton1_actionPerformed(e);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
class ConsoleFrame_jMenuFileExit_ActionAdapter2
implements ActionListener {
ConsoleFrame2 adaptee;
ConsoleFrame_jMenuFileExit_ActionAdapter2(ConsoleFrame2 adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent actionEvent) {
adaptee.jMenuFileExit_actionPerformed(actionEvent);
}
}
package com.ql.util.express.console;
public class ExampleDefine {
private String script;
private String context;
public ExampleDefine(String aScript, String aContext) {
this.script = aScript;
this.context = aContext;
}
public String getScript() {
return script;
}
public String getContext() {
return context;
}
}
package com.ql.util.express.console;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
/**
* <p>Description: 系统目录树,动态生成,解决载入慢的问题 </p>
*/
public class FileTree extends JTree {
private static final long serialVersionUID = 1L;
private DefaultTreeModel model;
public FileTree (String dir) {
this.initData(dir);
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
node_mouseAction(e);
}
});
}
private void node_mouseAction(MouseEvent e){
int row = this.getRowForLocation(e.getX(), e.getY());
PathNode pathNode =null;
if(row != -1){
TreePath path = this.getPathForRow(row);
pathNode = (PathNode)path.getLastPathComponent();
if(pathNode.isFolder()&&pathNode.getChildCount()==0){
builderNode(pathNode);
this.expandPath(path);
}
}
}
private PathNode builderNode(PathNode pathNode){
String filePath= pathNode.getValue().toString();
File file=new File(filePath);
File[] files=file.listFiles();
for(int i=0;i<files.length;i++){
if(files[i].isDirectory() || files[i].getName().endsWith(".ql")){
PathNode node=new PathNode(files[i].getName(), files[i].getAbsolutePath(),files[i].isDirectory());
pathNode.add(node);
}
}
return pathNode;
}
public void initData(String rootPath){
File f=new File(rootPath);
PathNode root=new PathNode(f.getName(), rootPath,f.isDirectory());
File[] files=f.listFiles();
for(int i=0;i<files.length;i++){
if(files[i].isDirectory() || files[i].getName().endsWith(".ql")){
PathNode node=new PathNode(files[i].getName(), files[i].getAbsolutePath(),files[i].isDirectory());
root.add(node);
}
}
model=new DefaultTreeModel(root);
this.setModel(model);
FileTreeRenderer renderer=new FileTreeRenderer();
this.setCellRenderer(renderer);
this.repaint();
}
class FileTreeRenderer implements TreeCellRenderer{
private Icon folder_open=new ImageIcon("com/ql/util/console/openFile.png");
private Icon folder_close=new ImageIcon("com/ql/util/console/closeFile.png");
private Icon file=new ImageIcon("com/ql/util/console/help.png");
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
JLabel label = null;
if (value != null) {
if(value instanceof PathNode){
PathNode pathNode = (PathNode) value;
if (pathNode.isFolder()) {
if (expanded) {
label = new JLabel(pathNode.getUserObject().
toString(),
folder_open, JLabel.RIGHT);
} else{// if(!expanded||leaf) {
label = new JLabel(pathNode.getUserObject().
toString(),
folder_close, JLabel.RIGHT);
}
} else {
label = new JLabel(pathNode.getUserObject().toString(),
file, JLabel.RIGHT);
}
return label;
}
}
return label;
}
}
class PathNode extends DefaultMutableTreeNode{
/**
*
*/
private static final long serialVersionUID = 1L;
String value;
boolean isFolder;
public PathNode(String name,Object value,boolean isFolder){
super(name);
this.value=value.toString();
this.isFolder=isFolder;
}
public String getValue(){
return value;
}
public boolean isFolder(){
return isFolder;
}
public String toString(){
return this.value+":" + this.isFolder;
}
}
}
package com.ql.util.express.console;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class ReadExample {
public static void main(String[] args) throws Exception {
String fileName ="E:\\taobaocode\\QLExpress\\trunk\\example\\simple.ql";
InputStream in = new FileInputStream(fileName);
readExampleDefine(in);
}
public static ExampleDefine readExampleDefine(String fileName) throws Exception {
InputStream in = new FileInputStream(fileName);
return readExampleDefine(in);
}
public static ExampleDefine readExampleDefine(InputStream in) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder dbd = dbf.newDocumentBuilder();
Document doc = dbd.parse(in);
XPathFactory f = XPathFactory.newInstance();
XPath path = f.newXPath();
Node scriptNode= (Node)path.evaluate("example/script", doc,XPathConstants.NODE);
String script = scriptNode.getTextContent().trim();
Node contextNode= (Node)path.evaluate("example/context", doc,XPathConstants.NODE);
String context = contextNode.getTextContent().trim();
return new ExampleDefine(script,context);
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionClearDataStack;
import com.ql.util.express.instruction.detail.InstructionCloseNewArea;
import com.ql.util.express.instruction.detail.InstructionOpenNewArea;
import com.ql.util.express.parse.ExpressNode;
public class BlockInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
if (node.isTypeEqualsOrChild("STAT_SEMICOLON")
&&result.getCurrentPoint() >=0 && result.getInstruction(result.getCurrentPoint()) instanceof InstructionClearDataStack == false) {
result.addInstruction(new InstructionClearDataStack());
}
int tmpPoint = result.getCurrentPoint()+1;
boolean returnVal = false;
boolean hasDef = false;
for(ExpressNode tmpNode : node.getChildren()){
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
hasDef = hasDef || tmpHas;
}
if (hasDef == true&& isRoot == false
&& node.getTreeType().isEqualsOrChild("STAT_BLOCK")){
result.insertInstruction(tmpPoint,new InstructionOpenNewArea());
result.insertInstruction(result.getCurrentPoint() + 1,new InstructionCloseNewArea());
returnVal = false;
}else{
returnVal = hasDef;
}
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionGoTo;
import com.ql.util.express.parse.ExpressNode;
public class BreakInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
InstructionGoTo breakInstruction = new InstructionGoTo(result.getCurrentPoint()+1);
breakInstruction.name = "break";
forStack.peek().breakList.add(breakInstruction);
result.addInstruction(breakInstruction);
return false;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionCallSelfDefineFunction;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
public class CallFunctionInstructionFactory extends InstructionFactory{
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
ExpressNode[] children = node.getChildren();
String functionName = children[0].getValue();
boolean returnVal = false;
children = node.getChildren();
for (int i = 1; i < children.length; i++) {
boolean tmpHas = aCompile.createInstructionSetPrivate(result,
forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = aCompile.getOperatorFactory().getOperator(
functionName);
int opNum = children.length -1;
if (op != null) {
result.addInstruction(new InstructionOperator(op,opNum ));
} else {
result.addInstruction(new InstructionCallSelfDefineFunction(
functionName,opNum));
}
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
public class CastInstructionFactory extends InstructionFactory{
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
boolean returnVal = false;
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
ExpressNode[] children = node.getChildren();
if(children.length ==0){
throw new Exception("扩展类型不存在");
}else if(children.length > 2) {
throw new Exception("扩展操作只能有一个类型为Class的操作数");
}else if(children[0].getNodeType().isEqualsOrChild("CONST_CLASS") == false){
throw new Exception("扩展操作只能有一个类型为Class的操作数,当前的数据类型是:" + children[0].getNodeType().getName());
}
for(int i =0;i < children.length;i++){
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,children[i],false);
returnVal = returnVal || tmpHas;
}
result.addInstruction(new InstructionOperator(op,children.length));
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.OperateData;
import com.ql.util.express.instruction.detail.InstructionConstData;
import com.ql.util.express.instruction.opdata.OperateClass;
import com.ql.util.express.parse.ExpressNode;
public class ConstDataInstructionFactory extends InstructionFactory {
public OperateData genOperateData(ExpressNode node) {
if (node.isTypeEqualsOrChild("CONST_CLASS")) {
return new OperateClass(node.getValue(), (Class<?>) node.getObjectValue());
} else {
return new OperateData(node.getObjectValue(), node.getObjectValue().getClass());
}
}
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
result.addInstruction(new InstructionConstData(genOperateData(node)));
return false;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionGoTo;
import com.ql.util.express.parse.ExpressNode;
public class ContinueInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
InstructionGoTo continueInstruction = new InstructionGoTo(result.getCurrentPoint()+1);
continueInstruction.name = "continue";
forStack.peek().continueList.add(continueInstruction);
result.addInstruction(continueInstruction);
return false;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.ExpressUtil;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
class DefineInstructionFactory extends InstructionFactory{
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
int [] finishPoint = new int[children.length];
int arrayDimeCount =0;
String tempStr="";
for(int i = children.length - 2;i>0;i--){
ExpressNode tmpNode = children[i];
if(tmpNode.isTypeEqualsOrChild("[]")){
arrayDimeCount = arrayDimeCount +1;
node.getLeftChildren().remove(i);
tempStr = tempStr +"[]";
}else{
throw new Exception("不正确的类型定义");
}
}
if(arrayDimeCount > 0){
node.getLeftChildren().get(0).setValue(node.getLeftChildren().get(0).getValue() + tempStr);
node.getLeftChildren().get(0).setOrgiValue(node.getLeftChildren().get(0).getOrgiValue() + tempStr);
Object objValue = node.getLeftChildren().get(0).getObjectValue();
if(objValue instanceof Class){
Class<?> tmpClass = ExpressUtil.getJavaClass(ExpressUtil.getClassName((Class<?>)objValue) + tempStr);
node.getLeftChildren().get(0).setObjectValue(tmpClass);
}else{
node.getLeftChildren().get(0).setObjectValue(node.getLeftChildren().get(0).getObjectValue()+ tempStr);
}
}
children = node.getChildren();
for(int i =0;i < children.length;i++){
ExpressNode tmpNode = children[i];
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
returnVal = returnVal || tmpHas;
finishPoint[i] = result.getCurrentPoint();
}
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
result.addInstruction(new InstructionOperator(op, children.length));
returnVal = true;
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.instruction.op.OperatorField;
import com.ql.util.express.parse.ExpressNode;
public class FieldCallInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
//处理对象
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[0], false);
returnVal = returnVal || tmpHas;
//处理属性名称
if(children[1].getNodeType().getName().equalsIgnoreCase("CONST_STRING") == false){
throw new Exception("对象属性名称不是字符串常量:" + children[1] );
}
String fieldName = (String)children[1].getObjectValue();
OperatorBase op = new OperatorField(fieldName);
result.addInstruction(new InstructionOperator(op,1));
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionCloseNewArea;
import com.ql.util.express.instruction.detail.InstructionGoTo;
import com.ql.util.express.instruction.detail.InstructionGoToWithCondition;
import com.ql.util.express.instruction.detail.InstructionOpenNewArea;
import com.ql.util.express.parse.ExpressNode;
public class ForInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
if(node.getChildren().length < 2){
throw new Exception("for 操作符至少需要2个操作数 " );
}else if(node.getChildren().length > 2){
throw new Exception("for 操作符最多只有2个操作数 " );
}
if(node.getChildren()[0].getChildren()!= null && node.getChildren()[0].getChildren().length > 3){
throw new Exception("循环语句的设置不合适:" + node.getChildren()[0]);
}
//生成作用域开始指令
result.addInstruction(new InstructionOpenNewArea());
forStack.push(new ForRelBreakContinue());
//生成条件语句部分指令
ExpressNode conditionNode = node.getChildren()[0];
int nodePoint = 0;
if (conditionNode.getChildren() != null && conditionNode.getChildren().length == 3){//变量定义,判断,自增都存在
int tempPoint = result.getCurrentPoint();
aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[0],false);
if(result.getCurrentPoint() > tempPoint){
nodePoint = nodePoint + 1;
}
}
//循环的开始的位置
int loopStartPoint = result.getCurrentPoint()+ 1;
//有条件语句
InstructionGoToWithCondition conditionInstruction=null;
if(conditionNode.getChildren() != null
&& (conditionNode.getChildren().length == 1
|| conditionNode.getChildren().length == 2
|| conditionNode.getChildren().length == 3)
) {
aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[nodePoint],false);
//跳转的位置需要根据后续的指令情况决定
conditionInstruction = new InstructionGoToWithCondition(false,-1,true);
result.insertInstruction(result.getCurrentPoint()+1,conditionInstruction);
nodePoint = nodePoint+ 1;
}
int conditionPoint = result.getCurrentPoint();
//生成循环体的代码
aCompile.createInstructionSetPrivate(result,forStack,node.getChildren()[1],false);
int selfAddPoint = result.getCurrentPoint()+1;
//生成自增代码指令
if(conditionNode.getChildren()!= null &&(
conditionNode.getChildren().length == 2 || conditionNode.getChildren().length == 3
)){
aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[nodePoint],false);
}
//增加一个无条件跳转
InstructionGoTo reStartGoto = new InstructionGoTo(loopStartPoint - (result.getCurrentPoint() + 1));
result.addInstruction(reStartGoto);
//修改条件判断的跳转位置
if(conditionInstruction != null){
conditionInstruction.setOffset( result.getCurrentPoint() - conditionPoint + 1);
}
//修改Break和Continue指令的跳转位置,循环出堆
ForRelBreakContinue rel = forStack.pop();
for(InstructionGoTo item:rel.breakList){
item.setOffset(result.getCurrentPoint() - item.getOffset()) ;
}
for(InstructionGoTo item:rel.continueList){
item.setOffset(selfAddPoint - item.getOffset() - 1);
}
//生成作用域结束指令
result.addInstruction(new InstructionCloseNewArea());
return false;
}
}
package com.ql.util.express.instruction;
import java.util.ArrayList;
import java.util.List;
import com.ql.util.express.instruction.detail.InstructionGoTo;
public class ForRelBreakContinue{
List<InstructionGoTo> breakList = new ArrayList<InstructionGoTo>();
List<InstructionGoTo> continueList = new ArrayList<InstructionGoTo>();
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
import com.ql.util.express.parse.ExpressNode;
public class FunctionInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
ExpressNode[] children = node.getChildren();
if(children.length != 3){
throw new Exception("funciton 操作符需要3个操作数 " );
}
String functionName =children[0].getValue();
ExpressNode[] varDefines = children[1].getChildren();
int point =0;
String instructionSetType ="";
if (node.isTypeEqualsOrChild("class")) {
instructionSetType = InstructionSet.TYPE_CLASS;
} else {
instructionSetType = InstructionSet.TYPE_FUNCTION;
}
InstructionSet functionSet = new InstructionSet(instructionSetType);
while(point<varDefines.length){
if(varDefines[point].isTypeEqualsOrChild("def") == false){
throw new Exception("function的参数定义错误," + varDefines[point] + "不是一个Class");
}
Class<?> varClass = (Class<?>)varDefines[point].getChildren()[0].getObjectValue();
String varName = varDefines[point].getChildren()[1].getValue();
OperateDataLocalVar tmpVar = new OperateDataLocalVar(varName,varClass);
functionSet.addParameter(tmpVar);
point = point + 1;
}
ExpressNode functionRoot = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("FUNCTION_DEFINE"),"function-" + functionName);
for(ExpressNode tempNode : children[2].getChildren()){
functionRoot.addLeftChild(tempNode);
}
aCompile.createInstructionSet(functionRoot,functionSet);
result.addMacroDefine(functionName, new FunctionInstructionSet(functionName,instructionSetType,functionSet));
return false;
}
}
package com.ql.util.express.instruction;
import java.io.Serializable;
import com.ql.util.express.InstructionSet;
public class FunctionInstructionSet implements Serializable{
private static final long serialVersionUID = 8735208809492617401L;
public String name;
public String type;
public InstructionSet instructionSet;
public FunctionInstructionSet(String aName,String aType,InstructionSet aInstructionSet){
this.name = aName;
this.type = aType;
this.instructionSet = aInstructionSet;
}
}
package com.ql.util.express.instruction;
import com.ql.util.express.CallResult;
import com.ql.util.express.ExpressLoader;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.RunEnvironment;
import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
import com.ql.util.express.instruction.opdata.OperateDataAttr;
import com.ql.util.express.instruction.opdata.OperateDataField;
import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
public interface IOperateDataCache {
public OperateData fetchOperateData(Object obj, Class<?> aType);
public OperateDataAttr fetchOperateDataAttr(String name, Class<?> aType);
public OperateDataLocalVar fetchOperateDataLocalVar(String name, Class<?> aType);
public OperateDataField fetchOperateDataField(Object aFieldObject,String aFieldName);
public OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject,int aIndex);
public OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue);
public RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace);
public CallResult fetchCallResult(Object aReturnValue,boolean aIsExit);
public InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext<String,Object> aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName);
public void resetCache();
public long getFetchCount();
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionGoTo;
import com.ql.util.express.instruction.detail.InstructionGoToWithCondition;
import com.ql.util.express.parse.ExpressNode;
public class IfInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
ExpressNode[] oldChildren = node.getChildren();
if(oldChildren.length < 2){
throw new Exception("if 操作符至少需要2个操作数 " );
}else if(oldChildren.length > 5){
throw new Exception("if 操作符最多只有5个操作数 " );
}
ExpressNode[] children = new ExpressNode[3];
int point = 0;
for(int i=0;i<oldChildren.length;i++){
if(oldChildren[i].isTypeEqualsOrChild("then")
||oldChildren[i].isTypeEqualsOrChild("else")
||oldChildren[i].isTypeEqualsOrChild("?")
||oldChildren[i].isTypeEqualsOrChild(":")){
continue;
}
children[point] = oldChildren[i];
point = point + 1;
}
if(point == 2){
children[2] = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("STAT_BLOCK"),null);
}
int [] finishPoint = new int[children.length];
boolean r1 = aCompile.createInstructionSetPrivate(result,forStack,children[0],false);//condition
finishPoint[0] = result.getCurrentPoint();
boolean r2 = aCompile.createInstructionSetPrivate(result,forStack,children[1],false);//true
result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithCondition(false,result.getCurrentPoint() - finishPoint[0] + 2,true));
finishPoint[1] = result.getCurrentPoint();
boolean r3 = aCompile.createInstructionSetPrivate(result,forStack,children[2],false);//false
result.insertInstruction(finishPoint[1]+1,new InstructionGoTo(result.getCurrentPoint() - finishPoint[1] + 1));
return r1 || r2 || r3;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
public class InInstructionFactory extends InstructionFactory{
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
ExpressNode[] children = node.getChildren();
if (children[1].isTypeEqualsOrChild("CHILD_EXPRESS")) {
node.getLeftChildren().remove(1);
ExpressNode[] parameterList = children[1].getChildren();
for (int i = 0; i < parameterList.length; i++) {
node.getLeftChildren().add(parameterList[i]);
}
}
boolean returnVal = false;
children = node.getChildren();
for (int i = 0; i < children.length; i++) {
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
result.addInstruction(new InstructionOperator(op, children.length));
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.parse.ExpressNode;
public abstract class InstructionFactory {
private static Map<String,InstructionFactory> instructionFactory = new HashMap<String,InstructionFactory>();
public static InstructionFactory getInstructionFactory(String factory) {
try {
InstructionFactory result = instructionFactory.get(factory);
if (result == null) {
result = (InstructionFactory) Class.forName(factory)
.newInstance();
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public abstract boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception;
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
class KeyValueInstructionFactory extends InstructionFactory{
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
if( node.getParent() != null && node.getParent().isTypeEqualsOrChild("STATEMENT")){
children[0].setNodeType(aCompile.getNodeTypeManager().findNodeType("CONST_STRING"));
children[0].setTreeType(aCompile.getNodeTypeManager().findNodeType("CONST"));
children[0].setObjectValue(children[0].getValue());
}
if( node.getParent() != null && node.getParent().isTypeEqualsOrChild("STATEMENT") && children[1].isTypeEqualsOrChild("STAT_BLOCK")){
returnVal = new MacroInstructionFactory().createInstruction(aCompile, result, forStack, node, isRoot);
} else if (node.getParent() != null&& node.getParent().isTypeEqualsOrChild("STATEMENT")) {
for(int i =0;i < children.length;i++){
ExpressNode tmpNode = children[i];
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = aCompile.getOperatorFactory().newInstance("alias");
result.addInstruction(new InstructionOperator(op, children.length));
returnVal = true;
}else{
for(int i =0;i < children.length;i++){
ExpressNode tmpNode = children[i];
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
result.addInstruction(new InstructionOperator(op,children.length));
}
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionCallMacro;
import com.ql.util.express.instruction.detail.InstructionLoadAttr;
import com.ql.util.express.parse.ExpressNode;
public class LoadAttrInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception{
FunctionInstructionSet functionSet = result.getMacroDefine(node.getValue());
if(functionSet != null){//是宏定义
result.insertInstruction(result.getCurrentPoint()+1, new InstructionCallMacro(node.getValue()));
}else{
result.addInstruction(new InstructionLoadAttr(node.getValue()));
if(node.getChildren().length >0){
throw new Exception("表达式设置错误");
}
}
return false;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.parse.ExpressNode;
public class MacroInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception {
ExpressNode[] children = node.getChildren();
String macroName =children[0].getValue();
ExpressNode macroRoot = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("FUNCTION_DEFINE"),"macro-" + macroName);
for(ExpressNode tempNode : children[1].getChildren()){
macroRoot.addLeftChild(tempNode);
}
InstructionSet macroInstructionSet = aCompile.createInstructionSet(macroRoot,InstructionSet.TYPE_MARCO);
result.addMacroDefine(macroName, new FunctionInstructionSet(macroName,"macro",macroInstructionSet));
return false;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.instruction.op.OperatorMethod;
import com.ql.util.express.parse.ExpressNode;
public class MethodCallInstructionFactory extends InstructionFactory {
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
//处理对象
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[0], false);
returnVal = returnVal || tmpHas;
//处理方法名称
if(children[1].getNodeType().getName().equalsIgnoreCase("CONST_STRING") == false){
throw new Exception("对象方法名称不是字符串常量:" + children[1] );
}
String methodName = (String)children[1].getObjectValue();
//处理方法参数
for (int i = 2; i < children.length; i++) {
tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = new OperatorMethod(methodName);
result.addInstruction(new InstructionOperator(op, children.length - 1));
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.ExpressUtil;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
public class NewInstructionFactory extends InstructionFactory{
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
OperatorBase op = aCompile.getOperatorFactory().newInstance("new");
ExpressNode[] children = node.getChildren();
if (node.isTypeEqualsOrChild("NEW_ARRAY")) {
String tempStr = children[0].getValue();
for (int i = 0; i < children.length - 1; i++) {
tempStr = tempStr + "[]";
}
children[0].setValue(tempStr);
children[0].setOrgiValue(tempStr);
children[0].setObjectValue(ExpressUtil.getJavaClass(tempStr));
}else if (node.isTypeEqualsOrChild("anonymousNewArray")) {
op = aCompile.getOperatorFactory().newInstance("anonymousNewArray");
}
boolean returnVal = false;
children = node.getChildren();// 需要重新获取数据
for (int i = 0; i < children.length; i++) {
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
result.addInstruction(new InstructionOperator(op, children.length));
return returnVal;
}
}
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionNewVirClass;
import com.ql.util.express.parse.ExpressNode;
public class NewVClassInstructionFactory extends InstructionFactory{
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
ExpressNode[] children = node.getChildren();
boolean returnVal = false;
String virClassName = children[0].getValue();
for (int i = 1; i < children.length; i++) {
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
result.addInstruction(new InstructionNewVirClass(virClassName, children.length -1));
return returnVal;
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册