| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -41,6 +41,7 @@ | |||
| 41 | 41 | import zuo.biao.apijson.NotNull; | |
| 42 | 42 | import zuo.biao.apijson.RequestMethod; | |
| 43 | 43 | import zuo.biao.apijson.StringUtil; | |
| 44 | + import zuo.biao.apijson.server.RemoteFunction.FunctionBean; | ||
| 44 | 45 | import zuo.biao.apijson.server.exception.ConflictException; | |
| 45 | 46 | import zuo.biao.apijson.server.exception.NotExistException; | |
| 46 | 47 | ||
@@ -743,16 +744,19 @@ public void onFunctionResponse(String type) throws Exception { | |||
| 743 | 744 | ||
| 744 | 745 | public void parseFunction(JSONObject json, String key, String value) throws Exception { | |
| 745 | 746 | Object result; | |
| 746 | - if (key.startsWith("@")) { | ||
| 747 | + if (key.startsWith("@")) { //TODO 以后这种小众功能从 ORM 移出,作为一个 plugin/APIJSONProcedure | ||
| 748 | + FunctionBean fb = RemoteFunction.parseFunction(value, json, true); | ||
| 749 | + | ||
| 747 | 750 | SQLConfig config = newSQLConfig(true); | |
| 748 | - config.setProcedure(value); | ||
| 751 | + config.setProcedure(fb.toFunctionCallString(true)); | ||
| 749 | 752 | ||
| 750 | 753 | SQLExecutor executor = null; | |
| 751 | 754 | try { | |
| 752 | 755 | executor = parser.getSQLExecutor(); | |
| 753 | 756 | result = executor.execute(config, true); | |
| 754 | 757 | } | |
| 755 | 758 | catch (NotExistException e) { | |
| 759 | + e.printStackTrace(); | ||
| 756 | 760 | return; | |
| 757 | 761 | } | |
| 758 | 762 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,6 +16,9 @@ | |||
| 16 | 16 | ||
| 17 | 17 | import java.lang.reflect.InvocationTargetException; | |
| 18 | 18 | ||
| 19 | + import javax.activation.UnsupportedDataTypeException; | ||
| 20 | + | ||
| 21 | + import com.alibaba.fastjson.JSONArray; | ||
| 19 | 22 | import com.alibaba.fastjson.JSONObject; | |
| 20 | 23 | ||
| 21 | 24 | import zuo.biao.apijson.NotNull; | |
@@ -35,61 +38,13 @@ public class RemoteFunction { | |||
| 35 | 38 | */ | |
| 36 | 39 | public static Object invoke(@NotNull RemoteFunction fun, @NotNull JSONObject request, @NotNull String function) throws Exception { | |
| 37 | 40 | ||
| 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 | - + "\nfunction必须符合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); | ||
| 87 | 42 | ||
| 88 | 43 | try { | |
| 89 | - return invoke(fun, method, types, values); | ||
| 44 | + return invoke(fun, fb.getMethod(), fb.getTypes(), fb.getValues()); | ||
| 90 | 45 | } catch (Exception e) { | |
| 91 | 46 | if (e instanceof NoSuchMethodException) { | |
| 92 | - throw new IllegalArgumentException("字符 " + function + " 对应的远程函数 " + getFunction(method, keys) + " 不在后端工程的DemoFunction内!" | ||
| 47 | + throw new IllegalArgumentException("字符 " + function + " 对应的远程函数 " + getFunction(fb.getMethod(), fb.getKeys()) + " 不在后端工程的DemoFunction内!" | ||
| 93 | 48 | + "\n请检查函数名和参数数量是否与已定义的函数一致!" | |
| 94 | 49 | + "\n且必须为 function(key0,key1,...) 这种单函数格式!" | |
| 95 | 50 | + "\nfunction必须符合Java函数命名,key是用于在request内取值的键!" | |
@@ -101,13 +56,99 @@ public static Object invoke(@NotNull RemoteFunction fun, @NotNull JSONObject req | |||
| 101 | 56 | throw te instanceof Exception ? (Exception) te : new Exception(te.getMessage()); | |
| 102 | 57 | } | |
| 103 | 58 | throw new IllegalArgumentException("字符 " + function + " 对应的远程函数传参类型错误!" | |
| 104 | - + "\n请检查 key:value 中value的类型是否满足已定义的函数 " + getFunction(method, keys) + " 的要求!"); | ||
| 59 | + + "\n请检查 key:value 中value的类型是否满足已定义的函数 " + getFunction(fb.getMethod(), fb.getKeys()) + " 的要求!"); | ||
| 105 | 60 | } | |
| 106 | 61 | throw e; | |
| 107 | 62 | } | |
| 108 | 63 | ||
| 109 | 64 | } | |
| 110 | 65 | ||
| 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 | + + "\nfunction必须符合 " + (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 | + | ||
| 111 | 152 | ||
| 112 | 153 | /**反射调用 | |
| 113 | 154 | * @param methodName | |
@@ -126,16 +167,93 @@ public static Object invoke(@NotNull RemoteFunction fun, @NotNull String methodN | |||
| 126 | 167 | */ | |
| 127 | 168 | public static String getFunction(String method, String[] keys) { | |
| 128 | 169 | String f = method + "(JSONObject request"; | |
| 129 | - | ||
| 170 | + | ||
| 130 | 171 | if (keys != null) { | |
| 131 | 172 | for (int i = 0; i < keys.length; i++) { | |
| 132 | 173 | f += (", String " + keys[i]); | |
| 133 | 174 | } | |
| 134 | 175 | } | |
| 135 | - | ||
| 176 | + | ||
| 136 | 177 | f += ")"; | |
| 137 | - | ||
| 178 | + | ||
| 138 | 179 | return f; | |
| 139 | 180 | } | |
| 140 | 181 | ||
| 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 | + | ||
| 141 | 259 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments