1616
1717import java .lang .reflect .InvocationTargetException ;
1818
19+ import javax .activation .UnsupportedDataTypeException ;
20+
21+ import com .alibaba .fastjson .JSONArray ;
1922import com .alibaba .fastjson .JSONObject ;
2023
2124import zuo .biao .apijson .NotNull ;
@@ -35,61 +38,13 @@ public class RemoteFunction {
3538 */
3639 public static Object invoke (@ NotNull RemoteFunction fun , @ NotNull JSONObject request , @ NotNull String function ) throws Exception {
3740
38- int start = function .indexOf ("(" );
39- int end = function .lastIndexOf (")" );
40- String method = function .substring (0 , start );
41- if (StringUtil .isEmpty (method , true )) {
42- throw new IllegalArgumentException ("字符 " + function + " 不合法!远程函数的名称function不能为空,"
43- + "且必须为 function(key0,key1,...) 这种单函数格式!"
44- + "\n function必须符合Java函数命名,key是用于在request内取值的键!" );
45- }
46-
47- String [] keys = StringUtil .split (function .substring (start + 1 , end ));
48-
49- int length = keys == null ? 0 : keys .length ;
50-
51- Class <?>[] types = new Class <?>[length + 1 ];
52- types [0 ] = JSONObject .class ;
53-
54- Object [] values = new Object [length + 1 ];
55- values [0 ] = request ;
56-
57- for (int i = 0 ; i < length ; i ++) {
58- types [i + 1 ] = String .class ;
59- values [i + 1 ] = keys [i ];
60- }
61-
62- //碰到null就挂了!!!Number还得各种转换不灵活!不如直接传request和对应的key到函数里,函数内实现时自己 getLongValue,getJSONObject ...
63- // for (int i = 0; i < length; i++) {
64- // v = values[i] = request == null ? null : request.get(keys[i]);
65- // if (v instanceof Boolean) {
66- // types[i] = Boolean.class; //只支持JSON的几种类型
67- // }
68- // else if (v instanceof Number) {
69- // types[i] = Number.class;
70- // }
71- // else if (v instanceof String) {
72- // types[i] = String.class;
73- // }
74- // else if (v instanceof JSONObject) { // Map) {
75- // types[i] = JSONObject.class;
76- // //性能比较差 values[i] = request.getJSONObject(keys[i]);
77- // }
78- // else if (v instanceof JSONArray) { // Collection) {
79- // types[i] = JSONArray.class;
80- // //性能比较差 values[i] = request.getJSONArray(keys[i]);
81- // }
82- // else { //FIXME 碰到null就挂了!!!
83- // throw new UnsupportedDataTypeException(keys[i] + ":value 中value不合法!远程函数 key():" + function + " 中的arg对应的值类型"
84- // + "只能是 [Boolean, Number, String, JSONObject, JSONArray] 中的一种!");
85- // }
86- // }
41+ FunctionBean fb = parseFunction (function , request , false );
8742
8843 try {
89- return invoke (fun , method , types , values );
44+ return invoke (fun , fb . getMethod (), fb . getTypes (), fb . getValues () );
9045 } catch (Exception e ) {
9146 if (e instanceof NoSuchMethodException ) {
92- throw new IllegalArgumentException ("字符 " + function + " 对应的远程函数 " + getFunction (method , keys ) + " 不在后端工程的DemoFunction内!"
47+ throw new IllegalArgumentException ("字符 " + function + " 对应的远程函数 " + getFunction (fb . getMethod (), fb . getKeys () ) + " 不在后端工程的DemoFunction内!"
9348 + "\n 请检查函数名和参数数量是否与已定义的函数一致!"
9449 + "\n 且必须为 function(key0,key1,...) 这种单函数格式!"
9550 + "\n function必须符合Java函数命名,key是用于在request内取值的键!"
@@ -101,13 +56,99 @@ public static Object invoke(@NotNull RemoteFunction fun, @NotNull JSONObject req
10156 throw te instanceof Exception ? (Exception ) te : new Exception (te .getMessage ());
10257 }
10358 throw new IllegalArgumentException ("字符 " + function + " 对应的远程函数传参类型错误!"
104- + "\n 请检查 key:value 中value的类型是否满足已定义的函数 " + getFunction (method , keys ) + " 的要求!" );
59+ + "\n 请检查 key:value 中value的类型是否满足已定义的函数 " + getFunction (fb . getMethod (), fb . getKeys () ) + " 的要求!" );
10560 }
10661 throw e ;
10762 }
10863
10964 }
11065
66+ /**解析函数
67+ * @param function
68+ * @param request
69+ * @param isSQLFunction
70+ * @return
71+ * @throws Exception
72+ */
73+ @ NotNull
74+ public static FunctionBean parseFunction (@ NotNull String function , @ NotNull JSONObject request , boolean isSQLFunction ) throws Exception {
75+
76+ int start = function .indexOf ("(" );
77+ int end = function .lastIndexOf (")" );
78+ String method = end != function .length () - 1 ? null : function .substring (0 , start );
79+ if (StringUtil .isEmpty (method , true )) {
80+ throw new IllegalArgumentException ("字符 " + function + " 不合法!函数的名称 function 不能为空,"
81+ + "且必须为 function(key0,key1,...) 这种单函数格式!"
82+ + "\n function必须符合 " + (isSQLFunction ? "SQL 函数/SQL 存储过程" : "Java 函数" ) + " 命名,key 是用于在 request 内取值的键!" );
83+ }
84+
85+ String [] keys = StringUtil .split (function .substring (start + 1 , end ));
86+
87+ int length = keys == null ? 0 : keys .length ;
88+
89+ Class <?>[] types ;
90+ Object [] values ;
91+
92+ if (isSQLFunction ) {
93+ types = new Class <?>[length ];
94+ values = new Object [length ];
95+
96+ //碰到null就挂了!!!Number还得各种转换不灵活!不如直接传request和对应的key到函数里,函数内实现时自己 getLongValue,getJSONObject ...
97+ Object v ;
98+ for (int i = 0 ; i < length ; i ++) {
99+ v = values [i ] = request .get (keys [i ]);
100+ if (v == null ) {
101+ types [i ] = Object .class ;
102+ values [i ] = null ;
103+ break ;
104+ }
105+
106+ if (v instanceof Boolean ) {
107+ types [i ] = Boolean .class ; //只支持JSON的几种类型
108+ }
109+ else if (v instanceof Number ) {
110+ types [i ] = Number .class ;
111+ }
112+ else if (v instanceof String ) {
113+ types [i ] = String .class ;
114+ }
115+ else if (v instanceof JSONObject ) { // Map) {
116+ types [i ] = JSONObject .class ;
117+ //性能比较差 values[i] = request.getJSONObject(keys[i]);
118+ }
119+ else if (v instanceof JSONArray ) { // Collection) {
120+ types [i ] = JSONArray .class ;
121+ //性能比较差 values[i] = request.getJSONArray(keys[i]);
122+ }
123+ else { //FIXME 碰到null就挂了!!!
124+ throw new UnsupportedDataTypeException (keys [i ] + ":value 中value不合法!远程函数 key():" + function + " 中的arg对应的值类型"
125+ + "只能是 [Boolean, Number, String, JSONObject, JSONArray] 中的一种!" );
126+ }
127+ }
128+ }
129+ else {
130+ types = new Class <?>[length + 1 ];
131+ types [0 ] = JSONObject .class ;
132+
133+ values = new Object [length + 1 ];
134+ values [0 ] = request ;
135+
136+ for (int i = 0 ; i < length ; i ++) {
137+ types [i + 1 ] = String .class ;
138+ values [i + 1 ] = keys [i ];
139+ }
140+ }
141+
142+ FunctionBean fb = new FunctionBean ();
143+ fb .setFunction (function );
144+ fb .setMethod (method );
145+ fb .setKeys (keys );
146+ fb .setTypes (types );
147+ fb .setValues (values );
148+
149+ return fb ;
150+ }
151+
111152
112153 /**反射调用
113154 * @param methodName
@@ -126,16 +167,93 @@ public static Object invoke(@NotNull RemoteFunction fun, @NotNull String methodN
126167 */
127168 public static String getFunction (String method , String [] keys ) {
128169 String f = method + "(JSONObject request" ;
129-
170+
130171 if (keys != null ) {
131172 for (int i = 0 ; i < keys .length ; i ++) {
132173 f += (", String " + keys [i ]);
133174 }
134175 }
135-
176+
136177 f += ")" ;
137-
178+
138179 return f ;
139180 }
140181
182+
183+ public static class FunctionBean {
184+ private String function ;
185+ private String method ;
186+ private String [] keys ;
187+ private Class <?>[] types ;
188+ private Object [] values ;
189+
190+ public String getFunction () {
191+ return function ;
192+ }
193+ public void setFunction (String function ) {
194+ this .function = function ;
195+ }
196+
197+ public String getMethod () {
198+ return method ;
199+ }
200+ public void setMethod (String method ) {
201+ this .method = method ;
202+ }
203+
204+ public String [] getKeys () {
205+ return keys ;
206+ }
207+ public void setKeys (String [] keys ) {
208+ this .keys = keys ;
209+ }
210+
211+ public Class <?>[] getTypes () {
212+ return types ;
213+ }
214+ public void setTypes (Class <?>[] types ) {
215+ this .types = types ;
216+ }
217+
218+ public Object [] getValues () {
219+ return values ;
220+ }
221+ public void setValues (Object [] values ) {
222+ this .values = values ;
223+ }
224+
225+
226+ /**
227+ * @param useValue
228+ * @return
229+ */
230+ public String toFunctionCallString (boolean useValue ) {
231+ return toFunctionCallString (useValue , null );
232+ }
233+ /**
234+ * @param useValue
235+ * @param quote
236+ * @return
237+ */
238+ public String toFunctionCallString (boolean useValue , String quote ) {
239+ String s = getMethod () + "(" ;
240+
241+ Object [] args = useValue ? getValues () : getKeys ();
242+ if (args != null && args .length > 0 ) {
243+ if (quote == null ) {
244+ quote = "'" ;
245+ }
246+
247+ Object arg ;
248+ for (int i = 0 ; i < args .length ; i ++) {
249+ arg = args [i ];
250+ s += (i <= 0 ? "" : "," ) + (arg instanceof Boolean || arg instanceof Number ? arg : quote + arg + quote );
251+ }
252+ }
253+
254+ return s + ")" ;
255+ }
256+
257+ }
258+
141259}
0 commit comments