2626import apijson .NotNull ;
2727import apijson .RequestMethod ;
2828import apijson .StringUtil ;
29+ import apijson .framework .APIJSONApplication ;
2930import 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 )
0 commit comments