55
66package apijson .orm ;
77
8- import java .io .FileReader ;
8+ import com .alibaba .fastjson .JSONObject ;
9+ import com .alibaba .fastjson .parser .ParserConfig ;
10+ import com .alibaba .fastjson .util .TypeUtils ;
11+
912import java .lang .invoke .WrongMethodTypeException ;
1013import java .lang .reflect .InvocationTargetException ;
1114import java .lang .reflect .Method ;
2023import javax .script .ScriptEngine ;
2124import javax .script .ScriptEngineManager ;
2225
23- import com .alibaba .fastjson .JSON ;
24- import com .alibaba .fastjson .JSONArray ;
25- import com .alibaba .fastjson .JSONObject ;
26- import com .alibaba .fastjson .parser .ParserConfig ;
27- import com .alibaba .fastjson .util .TypeUtils ;
28-
2926import apijson .Log ;
3027import apijson .NotNull ;
3128import apijson .RequestMethod ;
@@ -48,10 +45,6 @@ public class AbstractFunctionParser implements FunctionParser {
4845 */
4946 public static boolean ENABLE_SCRIPT_FUNCTION = true ;
5047
51- public static final int TYPE_REMOTE_FUNCTION = 0 ;
52- //public static final int TYPE_SQL_FUNCTION = 1;
53- public static final int TYPE_SCRIPT_FUNCTION = 1 ;
54-
5548 // <methodName, JSONObject>
5649 // <isContain, <arguments:"array,key", tag:null, methods:null>>
5750 public static Map <String , JSONObject > FUNCTION_MAP ;
@@ -198,15 +191,27 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
198191 throw new UnsupportedOperationException ("不允许调用远程函数 " + fb .getMethod () + " !" );
199192 }
200193
201- int type = row .getIntValue ("type" );
202- if (type < TYPE_REMOTE_FUNCTION || type > TYPE_SCRIPT_FUNCTION ) {
203- throw new UnsupportedOperationException ("type = " + type + " 不合法!必须是 [0, 1] 中的一个 !" );
204- }
205- if (ENABLE_SCRIPT_FUNCTION == false && type == TYPE_SCRIPT_FUNCTION ) {
206- throw new UnsupportedOperationException ("type = " + type + " 不合法!AbstractFunctionParser.ENABLE_SCRIPT_FUNCTION" +
194+ String language = row .getString ("language" );
195+ String lang = "java" .equalsIgnoreCase (language ) ? null : language ;
196+
197+ if (ENABLE_SCRIPT_FUNCTION == false && lang != null ) {
198+ throw new UnsupportedOperationException ("language = " + language + " 不合法!AbstractFunctionParser.ENABLE_SCRIPT_FUNCTION" +
207199 " == false 时不支持远程函数中的脚本形式!如需支持则设置 AbstractFunctionParser.ENABLE_SCRIPT_FUNCTION = true !" );
208200 }
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+ }
209212
213+ SCRIPT_ENGINE_MAP .put (lang , engine );
214+ }
210215
211216 int version = row .getIntValue ("version" );
212217 if (parser .getVersion () < version ) {
@@ -223,14 +228,15 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
223228 }
224229
225230 try {
226- return invoke (parser , fb .getMethod (), fb .getTypes (), fb .getValues (), row .getString ("returnType" ), currentObject , type );
231+ return invoke (parser , fb .getMethod (), fb .getTypes (), fb .getValues (), row .getString ("returnType" ), currentObject , engine );
227232 }
228233 catch (Exception e ) {
229234 if (e instanceof NoSuchMethodException ) {
230- throw new IllegalArgumentException ("字符 " + function + " 对应的远程函数 " + getFunction (fb .getMethod (), fb .getKeys ()) + " 不在后端工程的DemoFunction内!"
235+ throw new IllegalArgumentException ("字符 " + function + " 对应的远程函数 " + getFunction (fb .getMethod (), fb .getKeys ())
236+ + " 不在后端 " + parser .getClass ().getName () + " 内,也不在父类中!如果需要则先新增对应方法!"
231237 + "\n 请检查函数名和参数数量是否与已定义的函数一致!"
232238 + "\n 且必须为 function(key0,key1,...) 这种单函数格式!"
233- + "\n function必须符合Java函数命名,key是用于在request内取值的键 !"
239+ + "\n function 必须符合 Java 函数命名,key 是用于在 curObj 内取值的键 !"
234240 + "\n 调用时不要有空格!" + (Log .DEBUG ? e .getMessage () : "" ));
235241 }
236242 if (e instanceof InvocationTargetException ) {
@@ -252,12 +258,12 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
252258 * @param methodName
253259 * @param parameterTypes
254260 * @param args
255- * @return {@link #invoke(AbstractFunctionParser, String, Class[], Object[], String, JSONObject, int )}
261+ * @return {@link #invoke(AbstractFunctionParser, String, Class[], Object[], String, JSONObject, ScriptEngine )}
256262 * @throws Exception
257263 */
258264 public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
259265 , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args ) throws Exception {
260- return invoke (parser , methodName , parameterTypes , args , null , null , TYPE_REMOTE_FUNCTION );
266+ return invoke (parser , methodName , parameterTypes , args , null , null , null );
261267 }
262268 /**反射调用
263269 * @param parser
@@ -266,15 +272,15 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
266272 * @param args
267273 * @param returnType
268274 * @param currentObject
269- * @param type
275+ * @param engine
270276 * @return
271277 * @throws Exception
272278 */
273279 public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
274280 , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args , String returnType
275- , JSONObject currentObject , int type ) throws Exception {
276- if (type == TYPE_SCRIPT_FUNCTION ) {
277- return invokeScript (parser , methodName , parameterTypes , args , returnType , currentObject );
281+ , JSONObject currentObject , ScriptEngine engine ) throws Exception {
282+ if (engine != null ) {
283+ return invokeScript (parser , methodName , parameterTypes , args , returnType , currentObject , engine );
278284 }
279285
280286 Method m = parser .getClass ().getMethod (methodName , parameterTypes ); // 不用判空,拿不到就会抛异常
@@ -299,6 +305,7 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
299305
300306 public static Invocable INVOCABLE ;
301307 public static ScriptEngine SCRIPT_ENGINE ;
308+ public static Map <String , ScriptEngine > SCRIPT_ENGINE_MAP ;
302309 static {
303310 try {
304311 System .setProperty ("Dnashorn.args" , "language=es6" );
@@ -308,6 +315,11 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
308315 /*获取执行JavaScript的执行引擎*/
309316 SCRIPT_ENGINE = new ScriptEngineManager ().getEngineByName ("javascript" );
310317 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 );
311323 }
312324 catch (Exception e ) {
313325 e .printStackTrace ();
@@ -325,14 +337,18 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
325337 * @throws Exception
326338 */
327339 public static Object invokeScript (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
328- , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args , String returnType , JSONObject currentObject ) throws Exception {
340+ , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args , String returnType , JSONObject currentObject , ScriptEngine engine ) throws Exception {
329341 JSONObject row = SCRIPT_MAP .get (methodName );
330342 if (row == null ) {
331- throw new UnsupportedOperationException ("调用远程函数脚本 " + methodName + " 不存在!" );
343+ throw new UnsupportedOperationException ("调用的远程函数脚本 " + methodName + " 不存在!" );
332344 }
333345
334346 String script = row .getString ("script" );
335- SCRIPT_ENGINE .eval (script ); // 必要,未执行导致下方 INVOCABLE.invokeFunction 报错 NoSuchMethod
347+
348+ if (engine == null ) {
349+ engine = SCRIPT_ENGINE ;
350+ }
351+ engine .eval (script ); // 必要,未执行导致下方 INVOCABLE.invokeFunction 报错 NoSuchMethod
336352
337353 //Object[] newArgs = args == null || args.length <= 0 ? null : new Object[args.length];
338354
@@ -341,9 +357,11 @@ public static Object invokeScript(@NotNull AbstractFunctionParser parser, @NotNu
341357 // return SCRIPT_ENGINE.eval(script);
342358 //}
343359
360+ Invocable invocable = engine instanceof Invocable ? (Invocable ) engine : null ;
361+
344362 Object result ;
345363 if (args == null || args .length <= 0 ) {
346- result = INVOCABLE .invokeFunction (methodName );
364+ result = invocable .invokeFunction (methodName );
347365 }
348366 else {
349367 //args[0] = JSON.toJSONString(args[0]); // Java 调 js 函数只支持传基本类型,改用 invokeMethod ?
@@ -354,7 +372,7 @@ public static Object invokeScript(@NotNull AbstractFunctionParser parser, @NotNu
354372 //}
355373
356374 // 支持 JSONObject
357- result = INVOCABLE .invokeFunction (methodName , args );
375+ result = invocable .invokeFunction (methodName , args );
358376 //result = INVOCABLE.invokeMethod(args[0], methodName, args);
359377
360378 //switch (newArgs.length) {
0 commit comments