55
66package apijson .orm ;
77
8+ import java .io .FileReader ;
89import java .lang .reflect .InvocationTargetException ;
910import java .util .Arrays ;
1011import java .util .HashMap ;
1112import java .util .List ;
1213import java .util .Map ;
1314
1415import javax .activation .UnsupportedDataTypeException ;
16+ import javax .script .Invocable ;
17+ import javax .script .ScriptEngine ;
18+ import javax .script .ScriptEngineManager ;
1519
20+ import com .alibaba .fastjson .JSON ;
1621import com .alibaba .fastjson .JSONArray ;
1722import com .alibaba .fastjson .JSONObject ;
1823
2732public class AbstractFunctionParser implements FunctionParser {
2833 // private static final String TAG = "AbstractFunctionParser";
2934
35+ public static final int TYPE_REMOTE_FUNCTION = 0 ;
36+ //public static final int TYPE_SQL_FUNCTION = 1;
37+ public static final int TYPE_SCRIPT_FUNCTION = 1 ;
38+
3039 // <methodName, JSONObject>
3140 // <isContain, <arguments:"array,key", tag:null, methods:null>>
3241 public static Map <String , JSONObject > FUNCTION_MAP ;
42+ public static Map <String , JSONObject > SCRIPT_MAP ;
3343 static {
3444 FUNCTION_MAP = new HashMap <>();
45+ SCRIPT_MAP = new HashMap <>();
3546 }
3647
3748 private RequestMethod method ;
@@ -157,13 +168,19 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
157168 throw new UnsupportedOperationException ("不允许调用远程函数 " + fb .getMethod () + " !" );
158169 }
159170
160- int v = row .getIntValue ("version" );
161- if (parser .getVersion () < v ) {
162- throw new UnsupportedOperationException ("不允许 version = " + parser .getVersion () + " 的请求调用远程函数 " + fb .getMethod () + " ! 必须满足 version >= " + v + " !" );
171+ int type = row .getIntValue ("type" );
172+ if (type < TYPE_REMOTE_FUNCTION || type > TYPE_SCRIPT_FUNCTION ) {
173+ throw new UnsupportedOperationException ("type = " + type + " 不合法!必须是 [0, 1, 2] 中的一个 !" );
174+ }
175+
176+
177+ int version = row .getIntValue ("version" );
178+ if (parser .getVersion () < version ) {
179+ throw new UnsupportedOperationException ("不允许 version = " + parser .getVersion () + " 的请求调用远程函数 " + fb .getMethod () + " ! 必须满足 version >= " + version + " !" );
163180 }
164- String t = row .getString ("tag" );
165- if (t != null && t .equals (parser .getTag ()) == false ) {
166- throw new UnsupportedOperationException ("不允许 tag = " + parser .getTag () + " 的请求调用远程函数 " + fb .getMethod () + " ! 必须满足 tag = " + t + " !" );
181+ String tag = row .getString ("tag" );
182+ if (tag != null && tag .equals (parser .getTag ()) == false ) {
183+ throw new UnsupportedOperationException ("不允许 tag = " + parser .getTag () + " 的请求调用远程函数 " + fb .getMethod () + " ! 必须满足 tag = " + tag + " !" );
167184 }
168185 String [] methods = StringUtil .split (row .getString ("methods" ));
169186 List <String > ml = methods == null || methods .length <= 0 ? null : Arrays .asList (methods );
@@ -172,7 +189,7 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
172189 }
173190
174191 try {
175- return invoke (parser , fb .getMethod (), fb .getTypes (), fb .getValues ());
192+ return invoke (parser , fb .getMethod (), fb .getTypes (), fb .getValues (), currentObject , type );
176193 } catch (Exception e ) {
177194 if (e instanceof NoSuchMethodException ) {
178195 throw new IllegalArgumentException ("字符 " + function + " 对应的远程函数 " + getFunction (fb .getMethod (), fb .getKeys ()) + " 不在后端工程的DemoFunction内!"
@@ -201,17 +218,114 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
201218 * @param args
202219 * @return
203220 */
204- public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args ) throws Exception {
205- return parser .getClass ().getMethod (methodName , parameterTypes ).invoke (parser , args );
221+ public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
222+ , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args ) throws Exception {
223+ return invoke (parser , methodName , parameterTypes , args , null , TYPE_REMOTE_FUNCTION );
224+ }
225+ public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
226+ , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args , JSONObject currentObject , int type ) throws Exception {
227+ if (type == TYPE_SCRIPT_FUNCTION ) {
228+ return invokeScript (parser , methodName , parameterTypes , args , currentObject );
229+ }
230+ return parser .getClass ().getMethod (methodName , parameterTypes ).invoke (parser , args );
206231 }
207232
208- /**解析函数
209- * @param function
210- * @param request
211- * @param isSQLFunction
212- * @return
213- * @throws Exception
214- */
233+ public static Invocable INVOCABLE ;
234+ public static ScriptEngine SCRIPT_ENGINE ;
235+ static {
236+ try {
237+ System .setProperty ("Dnashorn.args" , "language=es6" );
238+ System .setProperty ("Dnashorn.args" , "--language=es6" );
239+ System .setProperty ("-Dnashorn.args" , "--language=es6" );
240+
241+ /*获取执行JavaScript的执行引擎*/
242+ SCRIPT_ENGINE = new ScriptEngineManager ().getEngineByName ("javascript" );
243+ INVOCABLE = (Invocable ) SCRIPT_ENGINE ;
244+ } catch (Exception e ) {
245+ e .printStackTrace ();
246+ }
247+ }
248+
249+ public static Object invokeScript (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
250+ , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args , JSONObject currentObject ) throws Exception {
251+ JSONObject row = SCRIPT_MAP .get (methodName );
252+ if (row == null ) {
253+ throw new UnsupportedOperationException ("调用远程函数脚本 " + methodName + " 不存在!" );
254+ }
255+
256+ String script = row .getString ("script" );
257+ //SCRIPT_ENGINE.eval(script);
258+ //Object[] newArgs = args == null || args.length <= 0 ? null : new Object[args.length];
259+
260+ SCRIPT_ENGINE .eval (script );
261+
262+ // APIJSON 远程函数不应该支持
263+ //if (row.getBooleanValue("simple")) {
264+ // return SCRIPT_ENGINE.eval(script);
265+ //}
266+
267+ Object result ;
268+ if (args == null || args .length <= 0 ) {
269+ result = INVOCABLE .invokeFunction (methodName );
270+ }
271+ else {
272+ //args[0] = JSON.toJSONString(args[0]); // Java 调 js 函数只支持传基本类型,改用 invokeMethod ?
273+
274+ //for (int i = 0; i < args.length; i++) {
275+ // Object a = currentObject == null ? null : currentObject.get(args[i]);
276+ // newArgs[i] = a == null || apijson.JSON.isBooleanOrNumberOrString(a) ? a : JSON.toJSONString(a);
277+ //}
278+
279+ // TODO 先试试这个
280+ result = INVOCABLE .invokeFunction (methodName , args );
281+ //result = INVOCABLE.invokeMethod(args[0], methodName, args);
282+
283+ //switch (newArgs.length) {
284+ // case 1:
285+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0]);
286+ // break;
287+ // case 2:
288+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1]);
289+ // break;
290+ // case 3:
291+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2]);
292+ // break;
293+ // case 4:
294+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3]);
295+ // break;
296+ // case 5:
297+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4]);
298+ // break;
299+ // case 6:
300+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5]);
301+ // break;
302+ // case 7:
303+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6]);
304+ // break;
305+ // case 8:
306+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7]);
307+ // break;
308+ // case 9:
309+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7], newArgs[8]);
310+ // break;
311+ // case 10:
312+ // result = INVOCABLE.invokeFunction(methodName, newArgs[0], newArgs[1], newArgs[2], newArgs[3], newArgs[4], newArgs[5], newArgs[6], newArgs[7], newArgs[8], newArgs[9]);
313+ // break;
314+ //}
315+ }
316+
317+ System .out .println ("invokeScript " + methodName + "(..) >> result = " + result );
318+ return result ;
319+ }
320+
321+
322+ /**解析函数
323+ * @param function
324+ * @param request
325+ * @param isSQLFunction
326+ * @return
327+ * @throws Exception
328+ */
215329 @ NotNull
216330 public static FunctionBean parseFunction (@ NotNull String function , @ NotNull JSONObject request , boolean isSQLFunction ) throws Exception {
217331
0 commit comments