diff --git a/APIJSONORM/pom.xml b/APIJSONORM/pom.xml
index 99de1a66..5fe07af6 100644
--- a/APIJSONORM/pom.xml
+++ b/APIJSONORM/pom.xml
@@ -5,7 +5,7 @@
com.github.Tencent
APIJSON
- 5.4.0
+ 5.5.0
jar
APIJSONORM
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
index 7b38a36d..57389974 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java
@@ -5,6 +5,7 @@ This source code is licensed under the Apache License Version 2.0.*/
package apijson.orm;
+import java.io.FileReader;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
@@ -12,7 +13,11 @@ import java.util.List;
import java.util.Map;
import javax.activation.UnsupportedDataTypeException;
+import javax.script.Invocable;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -27,11 +32,17 @@ import apijson.StringUtil;
public class AbstractFunctionParser implements FunctionParser {
// private static final String TAG = "AbstractFunctionParser";
+ public static final int TYPE_REMOTE_FUNCTION = 0;
+ //public static final int TYPE_SQL_FUNCTION = 1;
+ public static final int TYPE_SCRIPT_FUNCTION = 1;
+
//
// >
public static Map FUNCTION_MAP;
+ public static Map SCRIPT_MAP;
static {
FUNCTION_MAP = new HashMap<>();
+ SCRIPT_MAP = new HashMap<>();
}
private RequestMethod method;
@@ -157,13 +168,19 @@ public class AbstractFunctionParser implements FunctionParser {
throw new UnsupportedOperationException("不允许调用远程函数 " + fb.getMethod() + " !");
}
- int v = row.getIntValue("version");
- if (parser.getVersion() < v) {
- throw new UnsupportedOperationException("不允许 version = " + parser.getVersion() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 version >= " + v + " !");
+ int type = row.getIntValue("type");
+ if (type < TYPE_REMOTE_FUNCTION || type > TYPE_SCRIPT_FUNCTION) {
+ throw new UnsupportedOperationException("type = " + type + " 不合法!必须是 [0, 1, 2] 中的一个 !");
+ }
+
+
+ int version = row.getIntValue("version");
+ if (parser.getVersion() < version) {
+ throw new UnsupportedOperationException("不允许 version = " + parser.getVersion() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 version >= " + version + " !");
}
- String t = row.getString("tag");
- if (t != null && t.equals(parser.getTag()) == false) {
- throw new UnsupportedOperationException("不允许 tag = " + parser.getTag() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 tag = " + t + " !");
+ String tag = row.getString("tag");
+ if (tag != null && tag.equals(parser.getTag()) == false) {
+ throw new UnsupportedOperationException("不允许 tag = " + parser.getTag() + " 的请求调用远程函数 " + fb.getMethod() + " ! 必须满足 tag = " + tag + " !");
}
String[] methods = StringUtil.split(row.getString("methods"));
List ml = methods == null || methods.length <= 0 ? null : Arrays.asList(methods);
@@ -172,7 +189,7 @@ public class AbstractFunctionParser implements FunctionParser {
}
try {
- return invoke(parser, fb.getMethod(), fb.getTypes(), fb.getValues());
+ return invoke(parser, fb.getMethod(), fb.getTypes(), fb.getValues(), currentObject, type);
} catch (Exception e) {
if (e instanceof NoSuchMethodException) {
throw new IllegalArgumentException("字符 " + function + " 对应的远程函数 " + getFunction(fb.getMethod(), fb.getKeys()) + " 不在后端工程的DemoFunction内!"
@@ -201,17 +218,114 @@ public class AbstractFunctionParser implements FunctionParser {
* @param args
* @return
*/
- public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull String methodName, @NotNull Class>[] parameterTypes, @NotNull Object[] args) throws Exception {
- return parser.getClass().getMethod(methodName, parameterTypes).invoke(parser, args);
+ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull String methodName
+ , @NotNull Class>[] parameterTypes, @NotNull Object[] args) throws Exception {
+ return invoke(parser, methodName, parameterTypes, args, null, TYPE_REMOTE_FUNCTION);
+ }
+ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull String methodName
+ , @NotNull Class>[] parameterTypes, @NotNull Object[] args, JSONObject currentObject, int type) throws Exception {
+ if (type == TYPE_SCRIPT_FUNCTION) {
+ return invokeScript(parser, methodName, parameterTypes, args, currentObject);
+ }
+ return parser.getClass().getMethod(methodName, parameterTypes).invoke(parser, args);
}
- /**解析函数
- * @param function
- * @param request
- * @param isSQLFunction
- * @return
- * @throws Exception
- */
+ public static Invocable INVOCABLE;
+ public static ScriptEngine SCRIPT_ENGINE;
+ static {
+ try {
+ System.setProperty("Dnashorn.args", "language=es6");
+ System.setProperty("Dnashorn.args", "--language=es6");
+ System.setProperty("-Dnashorn.args", "--language=es6");
+
+ /*获取执行JavaScript的执行引擎*/
+ SCRIPT_ENGINE = new ScriptEngineManager().getEngineByName("javascript");
+ INVOCABLE = (Invocable) SCRIPT_ENGINE;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static Object invokeScript(@NotNull AbstractFunctionParser parser, @NotNull String methodName
+ , @NotNull Class>[] parameterTypes, @NotNull Object[] args, JSONObject currentObject) throws Exception {
+ JSONObject row = SCRIPT_MAP.get(methodName);
+ if (row == null) {
+ throw new UnsupportedOperationException("调用远程函数脚本 " + methodName + " 不存在!");
+ }
+
+ String script = row.getString("script");
+ //SCRIPT_ENGINE.eval(script);
+ //Object[] newArgs = args == null || args.length <= 0 ? null : new Object[args.length];
+
+ SCRIPT_ENGINE.eval(script);
+
+ // APIJSON 远程函数不应该支持
+ //if (row.getBooleanValue("simple")) {
+ // return SCRIPT_ENGINE.eval(script);
+ //}
+
+ Object result;
+ if (args == null || args.length <= 0) {
+ result = INVOCABLE.invokeFunction(methodName);
+ }
+ else {
+ //args[0] = JSON.toJSONString(args[0]); // Java 调 js 函数只支持传基本类型,改用 invokeMethod ?
+
+ //for (int i = 0; i < args.length; i++) {
+ // Object a = currentObject == null ? null : currentObject.get(args[i]);
+ // newArgs[i] = a == null || apijson.JSON.isBooleanOrNumberOrString(a) ? a : JSON.toJSONString(a);
+ //}
+
+ // TODO 先试试这个
+ result = INVOCABLE.invokeFunction(methodName, args);
+ //result = INVOCABLE.invokeMethod(args[0], methodName, args);
+
+ //switch (newArgs.length) {
+ // case 1:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0]);
+ // break;
+ // case 2:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1]);
+ // break;
+ // case 3:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2]);
+ // break;
+ // case 4:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3]);
+ // break;
+ // case 5:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4]);
+ // break;
+ // case 6:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5]);
+ // break;
+ // case 7:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6]);
+ // break;
+ // case 8:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7]);
+ // break;
+ // case 9:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7], newArgs[8]);
+ // break;
+ // case 10:
+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7], newArgs[8], newArgs[9]);
+ // break;
+ //}
+ }
+
+ System.out.println("invokeScript " + methodName + "(..) >> result = " + result);
+ return result;
+ }
+
+
+ /**解析函数
+ * @param function
+ * @param request
+ * @param isSQLFunction
+ * @return
+ * @throws Exception
+ */
@NotNull
public static FunctionBean parseFunction(@NotNull String function, @NotNull JSONObject request, boolean isSQLFunction) throws Exception {
diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
index bcff3f31..085a1354 100755
--- a/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
+++ b/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java
@@ -60,6 +60,7 @@ import apijson.orm.model.Column;
import apijson.orm.model.Document;
import apijson.orm.model.ExtendedProperty;
import apijson.orm.model.Function;
+import apijson.orm.model.Script;
import apijson.orm.model.PgAttribute;
import apijson.orm.model.PgClass;
import apijson.orm.model.Request;
@@ -151,6 +152,7 @@ public abstract class AbstractVerifier implements Verifier,
SYSTEM_ACCESS_MAP.put(Access.class.getSimpleName(), getAccessMap(Access.class.getAnnotation(MethodAccess.class)));
SYSTEM_ACCESS_MAP.put(Function.class.getSimpleName(), getAccessMap(Function.class.getAnnotation(MethodAccess.class)));
+ SYSTEM_ACCESS_MAP.put(Script.class.getSimpleName(), getAccessMap(Script.class.getAnnotation(MethodAccess.class)));
SYSTEM_ACCESS_MAP.put(Request.class.getSimpleName(), getAccessMap(Request.class.getAnnotation(MethodAccess.class)));
if (Log.DEBUG) {
diff --git a/APIJSONORM/src/main/java/apijson/orm/model/Script.java b/APIJSONORM/src/main/java/apijson/orm/model/Script.java
new file mode 100644
index 00000000..ddb60843
--- /dev/null
+++ b/APIJSONORM/src/main/java/apijson/orm/model/Script.java
@@ -0,0 +1,15 @@
+/*Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
+
+This source code is licensed under the Apache License Version 2.0.*/
+
+
+package apijson.orm.model;
+
+import apijson.MethodAccess;
+
+/**代码脚本
+ * @author Lemon
+ */
+@MethodAccess(POST = {}, PUT = {}, DELETE = {})
+public class Script {
+}
\ No newline at end of file