# jglue **Repository Path**: xukui911/jglue ## Basic Information - **Project Name**: jglue - **Description**: java实现的脚本引擎,纯解释执行。语法上最大程度兼容js,使用简单;体积小巧(编译后的jar包只有350K+);功能和效率全面超越现有的java解释型脚本以及表达式引擎 (比qlexpress执行效率有倍数提升)。在规则以及决策方面与宿主java语言无缝集成。也可以作为低代码平台后端业务功能扩展引擎(我的低代码平台:http://simplecodeplat.com:8081) - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: develop - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 10 - **Forks**: 2 - **Created**: 2023-02-15 - **Last Updated**: 2025-05-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # jglue ### 介绍 java实现的脚本引擎,纯解释执行。语法上最大程度兼容js,使用简单;体积小巧(编译后的jar包只有350K+);功能和效率全面超越现有的java解释型脚本以及表达式引擎 (在百万次循环执行中,比qlexpress执行效率有倍数提升)。在规则以及决策方面与宿主java语言无缝集成。也可以作为低代码平台后端业务功能扩展引擎 ### 软件架构 软件架构说明 ### 安装教程 1. 下载项目后,可直接根据源码编译出jar包,或者在项目下的target目录下找到已经编译好的jar包 2. 在目标项目中直接引入jglue包 ### 使用说明 #### 1.第一个案例:hellojglue ##### 解析执行一体: ``` JglueEngine engine = new JglueEngine(); JGlueContext context = new JSimpleContext();\n context.set("name", "jglue"); engine.execRuntime("print('hello,' +name+ '!!')", context); ``` ##### 解析执行分离 ``` JglueEngine engine = new JglueEngine(); engine.addContent("func hellojglue() {print('hello,'+name+'!!');}"); JGlueContext context = new JSimpleContext(); context.set("name", "jglue"); engine.execFunc("hellojglue", context); ``` 通过文件定义(格式化代码清晰美观):classpath下新建文件:com/xw/glue/test.glue 键入脚本内容: ``` func helloJglue() { print('hello,'+name+'!!'); } ``` 通过下面方式执行脚本代码: ``` JglueEngine engine = new JglueEngine(); engine.loadFile('com/xw/glue/test.glue'); JGlueContext context = new JSimpleContext(); context.set("name", "jglue"); engine.execFunc("helloJglue", context); ``` #### 2. 基本语法 ##### 定义数字: var a = 1; ##### 定义字符串 var b = 'b'; ##### 定义对象: var c = {a: a, b: b, c: 'c', d: 4}; ##### 定义数组: var d = [a, b, c, 4, '5']; ##### 方法定义(关键字func或者function): ``` func hello() { var a = 1; var b = 'b'; var c = {a: a, b: b, c: 'c', d: 4}; var d = [a, b, c, 4, '5']; } ``` ###### 条件判断if func helloIf() { var a = 1; if(a>0) { print('a > 0'); } else if(a==0){ print('a==0'); }else { print('a < 0'); } } ###### 循环结构while func helloWhile() { var i=10; while(i>0) { print(i); i--; } } ###### 循环结构for func helloFor() { //普通for循环 for(var i=0;i<10;i++) { print(i); } //遍历map var map = {a: 'a', b: 'b'}; for(key,val of map) { print(key+'='+val); } //遍历list var list = ['a',1,2,3, 'b']; for(val,index of list) { print('list['+index+']='+val); } } ###### 选择语句switch func helloSwitch() { var a = 1; switch(a) { case 0: print(0); break; case 1: print(1); break; default: print('defalut'); break; } } ###### 异常处理try/catch/finally func helloTryCatch() { var a = 1; try{ var b = a.a; print('execute success:'+b); }catch(e) { print('execute error:'+e); }finally { print('excute finally'); } } ###### 注释使用 ``` func helloDesc() { var a = 1; //这是注释 //这是注释 var b = 2; /* 这里也可以是注释 */ var c = 3; } ``` #### 3.高级语法部分 ###### 函数调用 ``` func funcA() { funcB(); funcC('funcC'); } func funcB() { print('hello, funcB'); } func funcC(c) { print('hello,' + c); } 调用代码: JGlueContext context = new JSimpleContext(); engine.execFunc("funcA", context); ``` ###### 子函数定义 ``` func parent() { func childA() { print('my name is ChildA'); }; var childB() { print('my name is ChildB'); }; childA(); childB(); } 调用代码: JGlueContext context = new JSimpleContext(); engine.execFunc("parent", context); ``` ###### 匿名函数 ``` func parent() { var childA = () => { print('my name is ChildA'); }; var childB = () => { print('my name is ChildB'); }; childA(); childB(); } 调用代码: JGlueContext context = new JSimpleContext(); engine.execFunc("parent", context); ``` ###### 函数作为参数传递 ``` func funcA() { funcB((a) => {print(a);}, (b) => {return 2*b;}); } func funcB(fa, fb) { fa(1); print(fb(2)); } 调用代码: JGlueContext context = new JSimpleContext(); engine.execFunc("funcA", context); ``` ###### 支持闭包 ``` func funcA() { var fa = funcB(); print(fa(100)); //支持链式调用 print(funcB()(200)); } func funcB() { var a = 1; return (x) => { return a+x;}; } 调用代码: GlueContext context = new JSimpleContext(); engine.execFunc("funcA", context); ``` ###### 面向对象支持: ``` func Person(name, age) { this.name = name; this.age = age; this.say = () => { print('my name is ' + this.name +',i\'m '+age); }; } func funcA() { var lilei = new Person('lilei', 20); print(lilei.name + ' say:'); lilei.say(); var hanmeimei = new Person('hanmeimei', 19); print(hanmeimei.name + ' say:'); hanmeimei.say() } 调用代码: GlueContext context = new JSimpleContext(); engine.execFunc("funcA", context); ``` #### 4.常用系统函数 ###### 静态函数(可自定义扩展) ``` func funtA() { print('hello, jglue'); //打印 len('hello, jglue') //获取字符串长度 Math.random(); Math.floor(5.5); Math.min(5, 6); Math.max(5, 6); } 调用代码: GlueContext context = new JSimpleContext(); engine.execFunc("funcA", context); ``` ###### 对象函数(可自定义扩展) ``` func funtA() { //启动新线程执行任务 new Thread((t) => { print(t.name); print(t.id); }).start(); //String方法 print('abc'.length()); print('abc'.substring(0,1)); print('abc'.split('b')); print('abc'.indexOf('b')); print('abc'.trim()); print('abc'.startsWith('a')); print('abc'.charAt(0)); //Date var date = new Date(); print(date.getTime()); print(date.getYear()); print(date.getMonth()); print(date.getDate()); print(date.toString()); //array var arr = []; print(arr.push(1)); print(arr[0]); print(arr.push(2)); print(arr.size()); print(arr.length); print(arr.indexOf(2)); //获取指定元素所在位置 //Promise异步 var promise = new Promise((r, j)=>{r(123);}).then( (data) => { print(data); return data + 100; } ).then( (data) => { print(data); return data + 100; } ); print(promise.get()); //同步获取最终结果 } 调用代码: GlueContext context = new JSimpleContext(); engine.execFunc("funcA", context); ``` #### 5.自定义函数 ``` //首先定义打印函数 public class DemoPrintFunc extends AbstractFunc { public DemoPrintFunc() { super("demoPrint"); addParam("paramOne"); } @Override public Object exec(JGlueContext var1, Object[] var2) { System.out.print(var2[0]); return null; } } //单元测试 public void testAddFunc() { JglueEngine engine = new JglueEngine(); JGlueContext context = new JSimpleContext(); engine.addFunc(new DemoPrintFunc()); context.set("paramOne", "this is addFunc UnitTest!!"); engine.execFunc("demoPrint", context); //其他函数中引用 engine.execRuntime("()=>{demoPrint('hello, I\\'m demoPrint!!');}()", context); } //输出结果 this is addFunc UnitTest!! hello, I'm demoPrint!! ``` #### 6.增加文件操作API ``` function fileTest() { var file = new File('E:\\a.txt'); //填入自己的文件路径 //读取文件 file.read((line, i) => { print('第'+i+'行:'+line); }); //文件路径 print(file.getAbsPath()); //追加内容 file.write('this is append content'); //插入内容到指定行 file.write('this is insert content', 1); //替换内容 file.replace('oldContent', 'newContent'); //更新每一行内容 file.update((content, lineNumber) => { return 'aa:'+content;}); //更新指定行内容 file.update((content, lineNumber) => { if(lineNumber==10) { return 'aa:'+content; } return content; }); //判断文件是否存在 if(file.isExists()) { file.read((line, i) => { print('第'+i+'行:'+line); }); } //获取目录下文件名称列表 file.lists(); //删除文件 file.delete(); } //java运行代码 JglueEngine engine = new JglueEngine(); engine.loadFile("test.glue"); JGlueContext context = new JSimpleContext(); engine.execFunc("fileTest", context); ``` #### 7.增加一些算法案例 ``` /* 快速排序 * @param array 输入待排序数组 * @returns 排序后的数组 */ func quickSort(array) { const sort = (arr, left, right) => { if (left >= right) {//如果左边的索引大于等于右边的索引说明整理完毕 return; } let low = left; let index = right; const baseVal = arr[right]; // 取无序数组最后一个数为基准值 while (low < index) {//把所有比基准值小的数放在左边大的数放在右边 //找到一个比基准值大的数交换 while (low < index && arr[low] <= baseVal) { low++; } arr[index] = arr[low]; // 将较大的值放在右边如果没有比基准值大的数就是将自己赋值给自己(i 等于 j) while (low < index && arr[index] >= baseVal) { //找到一个比基准值小的数交换 index--; break; } arr[low] = arr[index]; // 将较小的值放在左边如果没有找到比基准值小的数就是将自己赋值给自己(i 等于 j) } arr[index] = baseVal; // 将基准值放至中央位置完成一次循环(这时候 j 等于 i ) var r = index -1; sort(arr, left, r); // 将左边的无序数组重复上面的操作 sort(arr, index+1, right); // 将右边的无序数组重复上面的操作 } sort(array, 0, array.length - 1); return array; } ``` ``` /* 冒泡排序 从小到大 * @param arr */ function bubbleSort(arr) { let len = arr.length; for (let i = 0; i < len - 1; i++) { for (let j = 0; j < len - i - 1; j++) { // -i 是 排除已经沉到最下面的数,没必要再次比较。 if (arr[j] > arr[j + 1]) { let temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } ``` ``` /* 二分查找法 * arr 目标数组 * num 要查找的数字 */ function binarySearch(arr, num) { let low = 0; let hight = arr.length - 1; let count = 0; while (low <= hight) { count++; let mid = Math.floor((low + hight) / 2); let guess = arr[mid]; if (guess === num) { return mid; } if (guess > num) { hight = mid - 1; } else { low = mid + 1; } } return -1; } ``` ``` /** * 斐波拉奇数列 **/ function getFibonacci(n) { var fibarr = []; var i = 0; while(i