1010import java .lang .reflect .InvocationTargetException ;
1111import java .lang .reflect .Method ;
1212import java .util .Arrays ;
13+ import java .util .Collection ;
1314import java .util .HashMap ;
1415import java .util .List ;
1516import java .util .Map ;
2223import com .alibaba .fastjson .JSON ;
2324import com .alibaba .fastjson .JSONArray ;
2425import com .alibaba .fastjson .JSONObject ;
26+ import com .alibaba .fastjson .parser .ParserConfig ;
27+ import com .alibaba .fastjson .util .TypeUtils ;
2528
2629import apijson .Log ;
2730import apijson .NotNull ;
3437public class AbstractFunctionParser implements FunctionParser {
3538 private static final String TAG = "AbstractFunctionParser" ;
3639
40+ /**是否解析参数 key 的对应的值,不用手动编码 curObj.getString(key)
41+ */
42+ public static boolean IS_PARSE_ARG_VALUE = false ;
43+
3744 /**开启支持远程函数
3845 */
3946 public static boolean ENABLE_REMOTE_FUNCTION = true ;
@@ -155,11 +162,21 @@ public AbstractFunctionParser setCurrentObject(@NotNull JSONObject currentObject
155162 /**反射调用
156163 * @param function 例如get(object,key),参数只允许引用,不能直接传值
157164 * @param currentObject 不作为第一个参数,就不能远程调用invoke,避免死循环
158- * @return {@link #invoke(AbstractFunctionParser, String, JSONObject)}
165+ * @return {@link #invoke(String, JSONObject, boolean )}
159166 */
160167 @ Override
161168 public Object invoke (@ NotNull String function , @ NotNull JSONObject currentObject ) throws Exception {
162- return invoke (this , function , currentObject );
169+ return invoke (function , currentObject , false );
170+ }
171+ /**反射调用
172+ * @param function 例如get(object,key),参数只允许引用,不能直接传值
173+ * @param currentObject 不作为第一个参数,就不能远程调用invoke,避免死循环
174+ * @param containRaw 包含原始 SQL 片段
175+ * @return {@link #invoke(AbstractFunctionParser, String, JSONObject, boolean)}
176+ */
177+ @ Override
178+ public Object invoke (@ NotNull String function , @ NotNull JSONObject currentObject , boolean containRaw ) throws Exception {
179+ return invoke (this , function , currentObject , containRaw );
163180 }
164181
165182 /**反射调用
@@ -168,13 +185,13 @@ public Object invoke(@NotNull String function, @NotNull JSONObject currentObject
168185 * @param currentObject
169186 * @return {@link #invoke(AbstractFunctionParser, String, Class[], Object[])}
170187 */
171- public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String function , @ NotNull JSONObject currentObject ) throws Exception {
188+ public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String function , @ NotNull JSONObject currentObject , boolean containRaw ) throws Exception {
172189 if (ENABLE_REMOTE_FUNCTION == false ) {
173190 throw new UnsupportedOperationException ("AbstractFunctionParser.ENABLE_REMOTE_FUNCTION" +
174191 " == false 时不支持远程函数!如需支持则设置 AbstractFunctionParser.ENABLE_REMOTE_FUNCTION = true !" );
175192 }
176193
177- FunctionBean fb = parseFunction (function , currentObject , false );
194+ FunctionBean fb = parseFunction (function , currentObject , false , containRaw );
178195
179196 JSONObject row = FUNCTION_MAP .get (fb .getMethod ());
180197 if (row == null ) {
@@ -230,17 +247,31 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
230247 }
231248
232249 /**反射调用
233- * @param methodName
234- * @param parameterTypes
235- * @param args
236- * @return
237- */
250+ * @param parser
251+ * @param methodName
252+ * @param parameterTypes
253+ * @param args
254+ * @return {@link #invoke(AbstractFunctionParser, String, Class[], Object[], String, JSONObject, int)}
255+ * @throws Exception
256+ */
238257 public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
239258 , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args ) throws Exception {
240259 return invoke (parser , methodName , parameterTypes , args , null , null , TYPE_REMOTE_FUNCTION );
241260 }
261+ /**反射调用
262+ * @param parser
263+ * @param methodName
264+ * @param parameterTypes
265+ * @param args
266+ * @param returnType
267+ * @param currentObject
268+ * @param type
269+ * @return
270+ * @throws Exception
271+ */
242272 public static Object invoke (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
243- , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args , String returnType , JSONObject currentObject , int type ) throws Exception {
273+ , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args , String returnType
274+ , JSONObject currentObject , int type ) throws Exception {
244275 if (type == TYPE_SCRIPT_FUNCTION ) {
245276 return invokeScript (parser , methodName , parameterTypes , args , returnType , currentObject );
246277 }
@@ -276,11 +307,22 @@ public static Object invoke(@NotNull AbstractFunctionParser parser, @NotNull Str
276307 /*获取执行JavaScript的执行引擎*/
277308 SCRIPT_ENGINE = new ScriptEngineManager ().getEngineByName ("javascript" );
278309 INVOCABLE = (Invocable ) SCRIPT_ENGINE ;
279- } catch (Exception e ) {
310+ }
311+ catch (Exception e ) {
280312 e .printStackTrace ();
281313 }
282314 }
283315
316+ /**Java 调用 JavaScript 函数
317+ * @param parser
318+ * @param methodName
319+ * @param parameterTypes
320+ * @param args
321+ * @param returnType
322+ * @param currentObject
323+ * @return
324+ * @throws Exception
325+ */
284326 public static Object invokeScript (@ NotNull AbstractFunctionParser parser , @ NotNull String methodName
285327 , @ NotNull Class <?>[] parameterTypes , @ NotNull Object [] args , String returnType , JSONObject currentObject ) throws Exception {
286328 JSONObject row = SCRIPT_MAP .get (methodName );
@@ -388,6 +430,17 @@ public static Object invokeScript(@NotNull AbstractFunctionParser parser, @NotNu
388430 */
389431 @ NotNull
390432 public static FunctionBean parseFunction (@ NotNull String function , @ NotNull JSONObject request , boolean isSQLFunction ) throws Exception {
433+ return parseFunction (function , request , isSQLFunction , false );
434+ }
435+ /**解析函数,自动解析的值类型只支持 Boolean, Number, String, Map, List
436+ * @param function
437+ * @param request
438+ * @param isSQLFunction
439+ * @param containRaw
440+ * @return
441+ * @throws Exception
442+ */
443+ public static FunctionBean parseFunction (@ NotNull String function , @ NotNull JSONObject request , boolean isSQLFunction , boolean containRaw ) throws Exception {
391444
392445 int start = function .indexOf ("(" );
393446 int end = function .lastIndexOf (")" );
@@ -405,14 +458,14 @@ public static FunctionBean parseFunction(@NotNull String function, @NotNull JSON
405458 Class <?>[] types ;
406459 Object [] values ;
407460
408- if (isSQLFunction ) {
461+ if (isSQLFunction || IS_PARSE_ARG_VALUE ) {
409462 types = new Class <?>[length ];
410463 values = new Object [length ];
411464
412465 //碰到null就挂了!!!Number还得各种转换不灵活!不如直接传request和对应的key到函数里,函数内实现时自己 getLongValue,getJSONObject ...
413466 Object v ;
414467 for (int i = 0 ; i < length ; i ++) {
415- v = values [i ] = request .get (keys [i ]);
468+ v = values [i ] = getArgValue ( request , keys [ i ], containRaw ); // request.get(keys[i]);
416469 if (v == null ) {
417470 types [i ] = Object .class ;
418471 values [i ] = null ;
@@ -421,24 +474,29 @@ public static FunctionBean parseFunction(@NotNull String function, @NotNull JSON
421474
422475 if (v instanceof Boolean ) {
423476 types [i ] = Boolean .class ; //只支持JSON的几种类型
424- }
477+ } // 怎么都有 bug,如果是引用的值,很多情况下无法指定 // 用 1L 指定为 Long ? 其它的默认按长度分配为 Integer 或 Long?
478+ //else if (v instanceof Long || v instanceof Integer || v instanceof Short) {
479+ // types[i] = Long.class;
480+ //}
425481 else if (v instanceof Number ) {
426482 types [i ] = Number .class ;
427483 }
428484 else if (v instanceof String ) {
429485 types [i ] = String .class ;
430486 }
431- else if (v instanceof JSONObject ) { // Map) {
432- types [i ] = JSONObject .class ;
433- //性能比较差 values[i] = request.getJSONObject(keys[i]);
487+ else if (v instanceof Map ) { // 泛型兼容? // JSONObject
488+ types [i ] = Map .class ;
489+ //性能比较差
490+ //values[i] = TypeUtils.cast(v, Map.class, ParserConfig.getGlobalInstance());
434491 }
435- else if (v instanceof JSONArray ) { // Collection) {
436- types [i ] = JSONArray .class ;
437- //性能比较差 values[i] = request.getJSONArray(keys[i]);
492+ else if (v instanceof Collection ) { // 泛型兼容? // JSONArray
493+ types [i ] = List .class ;
494+ //性能比较差
495+ values [i ] = TypeUtils .cast (v , List .class , ParserConfig .getGlobalInstance ());
438496 }
439- else { //FIXME 碰到null就挂了!!!
440- throw new UnsupportedDataTypeException (keys [i ] + ":value 中value不合法!远程函数 key():" + function + " 中的arg对应的值类型"
441- + "只能是 [Boolean, Number, String, JSONObject, JSONArray] 中的一种!" );
497+ else {
498+ throw new UnsupportedDataTypeException (keys [i ] + ":value 中value不合法!远程函数 key():"
499+ + function + " 中的 arg 对应的值类型只能是 [Boolean, Number, String, JSONObject, JSONArray] 中的一种!" );
442500 }
443501 }
444502 }
@@ -485,6 +543,46 @@ public static String getFunction(String method, String[] keys) {
485543 return f ;
486544 }
487545
546+ public static <T > T getArgValue (@ NotNull JSONObject currentObject , String keyOrValue ) {
547+ return getArgValue (currentObject , keyOrValue , false );
548+ }
549+ public static <T > T getArgValue (@ NotNull JSONObject currentObject , String keyOrValue , boolean containRaw ) {
550+ if (keyOrValue == null ) {
551+ return null ;
552+ }
553+
554+ if (keyOrValue .endsWith ("`" ) && keyOrValue .lastIndexOf ("`" ) == 0 ) {
555+ return (T ) currentObject .get (keyOrValue .substring (1 , keyOrValue .length () - 1 ));
556+ }
557+
558+ if (keyOrValue .endsWith ("'" ) && keyOrValue .lastIndexOf ("'" ) == 0 ) {
559+ return (T ) keyOrValue .substring (1 , keyOrValue .length () - 1 );
560+ }
561+
562+ if (StringUtil .isName (keyOrValue .startsWith ("@" ) ? keyOrValue .substring (1 ) : keyOrValue )) {
563+ return (T ) currentObject .get (keyOrValue );
564+ }
565+
566+ // 传参加上 @raw:"key()" 避免意外情况
567+ Object val = containRaw ? AbstractSQLConfig .RAW_MAP .get (keyOrValue ) : null ;
568+ if (val != null ) {
569+ return (T ) ("" .equals (val ) ? keyOrValue : val );
570+ }
571+
572+ try {
573+ val = JSON .parse (keyOrValue );
574+ if (apijson .JSON .isBooleanOrNumberOrString (val )) {
575+ return (T ) val ;
576+ }
577+ }
578+ catch (Throwable e ) {
579+ Log .d (TAG , "getArgValue try {\n " +
580+ " Object val = JSON.parse(keyOrValue);" +
581+ "} catch (Throwable e) = " + e .getMessage ());
582+ }
583+
584+ return (T ) currentObject .get (keyOrValue );
585+ }
488586
489587 public static class FunctionBean {
490588 private String function ;
0 commit comments