Skip to content

Commit e6d6ec9

Browse files
function支持脚本引擎,比如JavaScript、lua等
#495
1 parent ced3fb9 commit e6d6ec9

File tree

2 files changed

+16
-117
lines changed

2 files changed

+16
-117
lines changed

APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java

Lines changed: 14 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
import apijson.NotNull;
2727
import apijson.RequestMethod;
2828
import apijson.StringUtil;
29+
import apijson.framework.APIJSONApplication;
2930
import apijson.orm.exception.UnsupportedDataTypeException;
31+
import apijson.orm.script.ScriptExecutor;
3032

3133
/**可远程调用的函数类
3234
* @author Lemon
@@ -47,11 +49,11 @@ public class AbstractFunctionParser implements FunctionParser {
4749

4850
// <methodName, JSONObject>
4951
// <isContain, <arguments:"array,key", tag:null, methods:null>>
52+
public static Map<String, ScriptExecutor> SCRIPT_EXECUTOR_MAP;
5053
public static Map<String, JSONObject> FUNCTION_MAP;
51-
public static Map<String, JSONObject> SCRIPT_MAP;
5254
static {
5355
FUNCTION_MAP = new HashMap<>();
54-
SCRIPT_MAP = new HashMap<>();
56+
SCRIPT_EXECUTOR_MAP = new HashMap<>();
5557
}
5658

5759
private RequestMethod method;
@@ -198,20 +200,10 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
198200
throw new UnsupportedOperationException("language = " + language + " 不合法!AbstractFunctionParser.ENABLE_SCRIPT_FUNCTION" +
199201
" == false 时不支持远程函数中的脚本形式!如需支持则设置 AbstractFunctionParser.ENABLE_SCRIPT_FUNCTION = true !");
200202
}
201-
ScriptEngine engine = lang == null ? null : SCRIPT_ENGINE_MAP.get(lang);
202-
if (lang != null) {
203-
if (engine == null) {
204-
engine = new ScriptEngineManager().getEngineByName(lang);
205-
}
206-
if (engine == null) {
207-
engine = new ScriptEngineManager(null).getEngineByName(lang);
208-
}
209-
if (engine == null) {
210-
throw new ClassNotFoundException("找不到脚本语言 " + language + " 对应的执行引擎!请先依赖相关库并在后端 ScriptEngineManager 中注册!");
211-
}
212-
213-
SCRIPT_ENGINE_MAP.put(lang, engine);
214-
}
203+
204+
if (lang != null && SCRIPT_EXECUTOR_MAP.get(lang) == null) {
205+
throw new ClassNotFoundException("找不到脚本语言 " + lang + " 对应的执行引擎!请先依赖相关库并在后端 APIJSONFunctionParser 中注册!");
206+
}
215207

216208
int version = row.getIntValue("version");
217209
if (parser.getVersion() < version) {
@@ -228,7 +220,7 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
228220
}
229221

230222
try {
231-
return invoke(parser, fb.getMethod(), fb.getTypes(), fb.getValues(), row.getString("returnType"), currentObject, engine);
223+
return invoke(parser, fb.getMethod(), fb.getTypes(), fb.getValues(), row.getString("returnType"), currentObject, SCRIPT_EXECUTOR_MAP.get(lang));
232224
}
233225
catch (Exception e) {
234226
if (e instanceof NoSuchMethodException) {
@@ -278,9 +270,9 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
278270
*/
279271
public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull String methodName
280272
, @NotNull Class<?>[] parameterTypes, @NotNull Object[] args, String returnType
281-
, JSONObject currentObject, ScriptEngine engine) throws Exception {
282-
if (engine != null) {
283-
return invokeScript(parser, methodName, parameterTypes, args, returnType, currentObject, engine);
273+
, JSONObject currentObject, ScriptExecutor scriptExecutor) throws Exception {
274+
if (scriptExecutor != null) {
275+
return invokeScript(parser, methodName, parameterTypes, args, returnType, currentObject, scriptExecutor);
284276
}
285277

286278
Method m = parser.getClass().getMethod(methodName, parameterTypes); // 不用判空,拿不到就会抛异常
@@ -303,29 +295,6 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
303295
return m.invoke(parser, args);
304296
}
305297

306-
public static Invocable INVOCABLE;
307-
public static ScriptEngine SCRIPT_ENGINE;
308-
public static Map<String, ScriptEngine> SCRIPT_ENGINE_MAP;
309-
static {
310-
try {
311-
System.setProperty("Dnashorn.args", "language=es6");
312-
System.setProperty("Dnashorn.args", "--language=es6");
313-
System.setProperty("-Dnashorn.args", "--language=es6");
314-
315-
/*获取执行JavaScript的执行引擎*/
316-
SCRIPT_ENGINE = new ScriptEngineManager().getEngineByName("javascript");
317-
INVOCABLE = (Invocable) SCRIPT_ENGINE;
318-
319-
SCRIPT_ENGINE_MAP = new HashMap<>();
320-
SCRIPT_ENGINE_MAP.put("JavaScript", SCRIPT_ENGINE);
321-
SCRIPT_ENGINE_MAP.put("javascript", SCRIPT_ENGINE);
322-
SCRIPT_ENGINE_MAP.put("js", SCRIPT_ENGINE);
323-
}
324-
catch (Exception e) {
325-
e.printStackTrace();
326-
}
327-
}
328-
329298
/**Java 调用 JavaScript 函数
330299
* @param parser
331300
* @param methodName
@@ -337,78 +306,8 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
337306
* @throws Exception
338307
*/
339308
public static Object invokeScript(@NotNull AbstractFunctionParser parser, @NotNull String methodName
340-
, @NotNull Class<?>[] parameterTypes, @NotNull Object[] args, String returnType, JSONObject currentObject, ScriptEngine engine) throws Exception {
341-
JSONObject row = SCRIPT_MAP.get(methodName);
342-
if (row == null) {
343-
throw new UnsupportedOperationException("调用的远程函数脚本 " + methodName + " 不存在!");
344-
}
345-
346-
String script = row.getString("script");
347-
348-
if (engine == null) {
349-
engine = SCRIPT_ENGINE;
350-
}
351-
engine.eval(script); // 必要,未执行导致下方 INVOCABLE.invokeFunction 报错 NoSuchMethod
352-
353-
//Object[] newArgs = args == null || args.length <= 0 ? null : new Object[args.length];
354-
355-
// APIJSON 远程函数不应该支持
356-
//if (row.getBooleanValue("simple")) {
357-
// return SCRIPT_ENGINE.eval(script);
358-
//}
359-
360-
Invocable invocable = engine instanceof Invocable ? (Invocable) engine : null;
361-
362-
Object result;
363-
if (args == null || args.length <= 0) {
364-
result = invocable.invokeFunction(methodName);
365-
}
366-
else {
367-
//args[0] = JSON.toJSONString(args[0]); // Java 调 js 函数只支持传基本类型,改用 invokeMethod ?
368-
369-
//for (int i = 0; i < args.length; i++) {
370-
// Object a = currentObject == null ? null : currentObject.get(args[i]);
371-
// newArgs[i] = a == null || apijson.JSON.isBooleanOrNumberOrString(a) ? a : JSON.toJSONString(a);
372-
//}
373-
374-
// 支持 JSONObject
375-
result = invocable.invokeFunction(methodName, args);
376-
//result = INVOCABLE.invokeMethod(args[0], methodName, args);
377-
378-
//switch (newArgs.length) {
379-
// case 1:
380-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0]);
381-
// break;
382-
// case 2:
383-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1]);
384-
// break;
385-
// case 3:
386-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2]);
387-
// break;
388-
// case 4:
389-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3]);
390-
// break;
391-
// case 5:
392-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4]);
393-
// break;
394-
// case 6:
395-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5]);
396-
// break;
397-
// case 7:
398-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6]);
399-
// break;
400-
// case 8:
401-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7]);
402-
// break;
403-
// case 9:
404-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7], newArgs[8]);
405-
// break;
406-
// case 10:
407-
// result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7], newArgs[8], newArgs[9]);
408-
// break;
409-
//}
410-
}
411-
309+
, @NotNull Class<?>[] parameterTypes, @NotNull Object[] args, String returnType, JSONObject currentObject, ScriptExecutor scriptExecutor) throws Exception {
310+
Object result = scriptExecutor.execute(parser, currentObject, methodName, args);
412311
if (Log.DEBUG && result != null) {
413312
Class<?> rt = result.getClass(); // 作为远程函数的 js 类型应该只有 JSON 的几种类型
414313
String fullReturnType = (StringUtil.isSmallName(returnType)

APIJSONORM/src/main/java/apijson/orm/AbstractParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,8 +2120,8 @@ private JSONObject batchVerify(RequestMethod method, String tag, int version, St
21202120
case apijson.JSONObject.KEY_DATABASE:
21212121
object_attributes_map.put(apijson.JSONObject.KEY_DATABASE, objAttrJson.getString(objAttr));
21222122
break;
2123-
case apijson.JSONObject.VERSION:
2124-
object_attributes_map.put(apijson.JSONObject.VERSION, objAttrJson.getString(objAttr));
2123+
case JSONRequest.KEY_VERSION:
2124+
object_attributes_map.put(JSONRequest.KEY_VERSION, objAttrJson.getString(objAttr));
21252125
break;
21262126
case apijson.JSONObject.KEY_ROLE:
21272127
object_attributes_map.put(apijson.JSONObject.KEY_ROLE, objAttrJson.getString(objAttr));

0 commit comments

Comments
 (0)