2323import static apijson .orm .Operation .UNIQUE ;
2424import static apijson .orm .Operation .UPDATE ;
2525import static apijson .orm .Operation .VERIFY ;
26- import static apijson .orm .Operation .ON ;
26+ import static apijson .orm .Operation .IF ;
27+ //import static apijson.orm.Operation.CODE;
2728
2829import java .net .URL ;
2930import java .time .LocalDate ;
3334import java .util .regex .Matcher ;
3435import java .util .regex .Pattern ;
3536
37+ import apijson .orm .script .JavaScriptExecutor ;
38+ import apijson .orm .script .ScriptExecutor ;
3639import com .alibaba .fastjson .JSONArray ;
3740import com .alibaba .fastjson .JSONObject ;
3841
6568import apijson .orm .model .AllColumnComment ;
6669import apijson .orm .model .TestRecord ;
6770
71+ import javax .script .ScriptEngine ;
72+ import javax .script .ScriptEngineFactory ;
73+ import javax .script .ScriptEngineManager ;
74+
6875/**校验器(权限、请求参数、返回结果等)
6976 * TODO 合并 Structure 的代码
7077 * @author Lemon
@@ -107,6 +114,10 @@ public abstract class AbstractVerifier<T extends Object> implements Verifier<T>,
107114 */
108115 public static final String ADMIN = "ADMIN" ;
109116
117+ public static ParserCreator PARSER_CREATOR ;
118+
119+ public static ScriptEngineManager SCRIPT_ENGINE_MANAGER ;
120+ public static ScriptEngine SCRIPT_ENGINE ;
110121
111122 // 共享 STRUCTURE_MAP 则不能 remove 等做任何变更,否则在并发情况下可能会出错,加锁效率又低,所以这里改为忽略对应的 key
112123 public static Map <String , Entry <String , Object >> ROLE_MAP ;
@@ -133,6 +144,9 @@ public abstract class AbstractVerifier<T extends Object> implements Verifier<T>,
133144 @ NotNull
134145 public static final Map <String , Pattern > COMPILE_MAP ;
135146 static {
147+ SCRIPT_ENGINE_MANAGER = new ScriptEngineManager ();
148+ SCRIPT_ENGINE = SCRIPT_ENGINE_MANAGER .getEngineByName ("js" );
149+
136150 ROLE_MAP = new LinkedHashMap <>();
137151 ROLE_MAP .put (UNKNOWN , new Entry <String , Object >());
138152 ROLE_MAP .put (LOGIN , new Entry <String , Object >("userId>" , 0 ));
@@ -152,7 +166,8 @@ public abstract class AbstractVerifier<T extends Object> implements Verifier<T>,
152166 OPERATION_KEY_LIST .add (REMOVE .name ());
153167 OPERATION_KEY_LIST .add (MUST .name ());
154168 OPERATION_KEY_LIST .add (REFUSE .name ());
155- OPERATION_KEY_LIST .add (ON .name ());
169+ OPERATION_KEY_LIST .add (IF .name ());
170+ // OPERATION_KEY_LIST.add(CODE.name());
156171 OPERATION_KEY_LIST .add (ALLOW_PARTIAL_UPDATE_FAIL .name ());
157172
158173
@@ -914,7 +929,19 @@ public static <T extends Object> JSONObject parse(@NotNull final RequestMethod m
914929 String remove = StringUtil .getString (target .getString (REMOVE .name ()));
915930 String must = StringUtil .getString (target .getString (MUST .name ()));
916931 String refuse = StringUtil .getString (target .getString (REFUSE .name ()));
917- JSONObject on = target .getJSONObject (ON .name ());
932+
933+ Object _if = target .get (IF .name ());
934+ boolean ifIsStr = _if instanceof String && StringUtil .isNotEmpty (_if , true );
935+ JSONObject ifObj = ifIsStr == false && _if instanceof JSONObject ? (JSONObject ) _if : null ;
936+ // : (_if instanceof String ? new apijson.JSONRequest((String) _if, "" /* "throw new Error('')" */ ) : null);
937+ if (ifObj == null && _if != null && ifIsStr == false ) {
938+ // if (_if instanceof JSONArray) {
939+ // }
940+ throw new IllegalArgumentException (name + ": { " + IF .name () + ": value } 中 value 类型错误!只允许 String, JSONObject!" );
941+ }
942+
943+ // Object code = target.get(CODE.name());
944+
918945 String allowPartialUpdateFail = StringUtil .getString (target .getString (ALLOW_PARTIAL_UPDATE_FAIL .name ()));
919946
920947
@@ -1143,7 +1170,7 @@ public static <T extends Object> JSONObject parse(@NotNull final RequestMethod m
11431170 long exceptId = real .getLongValue (finalIdKey );
11441171 Map <String ,Object > map = new HashMap <>();
11451172 for (String u : uniques ) {
1146- map .put (u ,real .get (u ));
1173+ map .put (u , real .get (u ));
11471174 }
11481175 verifyRepeat (name , map , exceptId , finalIdKey , creator );
11491176 }
@@ -1176,38 +1203,111 @@ public static <T extends Object> JSONObject parse(@NotNull final RequestMethod m
11761203 // 校验并配置允许部分批量增删改失败>>>>>>>>>>>>>>>>>>>
11771204
11781205
1179- String [] nks = on == null ? null : StringUtil .split (real .getString (JSONRequest .KEY_NULL ));
1206+ String [] nks = ifObj == null ? null : StringUtil .split (real .getString (JSONRequest .KEY_NULL ));
11801207 Collection <?> nkl = nks == null || nks .length <= 0 ? new HashSet <>() : Arrays .asList (nks );
11811208
1182- Set <Map .Entry <String , Object >> onSet = on == null ? null : on .entrySet ();
1183- if (onSet != null ) {
1209+ Set <Map .Entry <String , Object >> ifSet = ifObj == null ? null : ifObj .entrySet ();
1210+ if (ifIsStr || ( ifSet != null && ifSet . isEmpty () == false ) ) {
11841211 // 没必要限制,都是后端配置的,安全可控,而且可能确实有特殊需求,需要 id, @column 等
11851212// List<String> condKeys = new ArrayList<>(Arrays.asList(apijson.JSONRequest.KEY_ID, apijson.JSONRequest.KEY_ID_IN
11861213// , apijson.JSONRequest.KEY_USER_ID, apijson.JSONRequest.KEY_USER_ID_IN));
11871214// condKeys.addAll(JSONRequest.TABLE_KEY_LIST);
11881215
1189- for (Map .Entry <String , Object > entry : onSet ) {
1190- String k = entry == null ? null : entry .getKey ();
1216+ String preCode = "var curObj = " + JSON .format (real ) + ";" ;
1217+
1218+ // 未传的 key 在后面 eval 时总是报错 undefined,而且可能有冲突,例如对象里有 "curObj": val 键值对,就会覆盖当前对象定义,还不如都是 curObj.sex 这样取值
1219+ // Set<Map.Entry<String, Object>> rset = real.entrySet();
1220+ // for (Map.Entry<String, Object> entry : rset) {
1221+ // String k = entry == null ? null : entry.getKey();
1222+ // if (StringUtil.isEmpty(k)) {
1223+ // continue;
1224+ // }
1225+ // String vn = JSONResponse.formatOtherKey(k);
1226+ // if (StringUtil.isName(vn) == false) { // 通过 curObj['id@'] 这样取值,写在 IF 配置里
1227+ // continue;
1228+ // }
1229+ //
1230+ // Object v = entry.getValue();
1231+ // String vs = v instanceof String ? "\"" + ((String) v).replaceAll("\"", "\\\"") + "\""
1232+ // : (JSON.isBooleanOrNumberOrString(v) ? v.toString() : JSON.format(v));
1233+ // preCode += "\nvar " + vn + " = " + vs + ";";
1234+ // }
1235+
1236+ if (ifIsStr ) {
1237+ String ifStr = (String ) _if ;
1238+ int ind = ifStr .indexOf (":" );
1239+ String lang = ind < 0 ? null : ifStr .substring (0 , ind );
1240+ ScriptEngine engine = getScriptEngine (lang );
1241+ engine .eval (preCode + "\n " + _if );
1242+ }
1243+ else {
1244+ for (Map .Entry <String , Object > entry : ifSet ) {
1245+ String k = entry == null ? null : entry .getKey ();
11911246// if (condKeys.contains(k)) {
11921247// throw new IllegalArgumentException("Request 表 structure 配置的 " + ON.name()
11931248// + ":{ " + k + ":value } 中 key 不合法,不允许传 [" + StringUtil.join(condKeys.toArray(new String[]{})) + "] 中的任何一个 !");
11941249// }
11951250
1196- Object v = k == null ? null : entry .getValue ();
1197- if (v instanceof JSONObject == false ) {
1198- throw new IllegalArgumentException ("Request 表 structure 配置的 " + ON .name ()
1199- + ":{ " + k + ":value } 中 value 不合法,必须是 JSONObject {} !" );
1200- }
1251+ Object v = k == null ? null : entry .getValue ();
1252+ if (v instanceof String ) {
1253+ int ind = k .indexOf (":" );
1254+ String lang = ind < 0 ? null : k .substring (0 , ind );
1255+ ScriptEngine engine = getScriptEngine (lang );
1256+ k = ind < 0 ? k : k .substring (ind + 1 );
1257+
1258+ boolean isElse = StringUtil .isEmpty (k , false ); // 其它直接报错,不允许传 StringUtil.isEmpty(k, true) || "ELSE".equals(k);
1259+ // String code = preCode + "\n\n" + (StringUtil.isEmpty(v, false) ? k : (isElse ? v : "if (" + k + ") {\n " + v + "\n}"));
1260+ String code = preCode + "\n \n " + (isElse ? v : "if (" + k + ") {\n " + v + "\n }" );
1261+
1262+ // ScriptExecutor executor = new JavaScriptExecutor();
1263+ // executor.execute(null, real, )
12011264
1202- if (nkl .contains (k ) || real .get (k ) != null ) {
1203- real = parse (method , name , (JSONObject ) v , real , database , schema , datasource , idCallback , creator , callback );
1265+ engine .eval (code );
1266+
1267+ // PARSER_CREATOR.createFunctionParser()
1268+ // .setCurrentObject(real)
1269+ // .setKey(k)
1270+ // .setMethod(method)
1271+ // .invoke()
1272+ continue ;
1273+ }
1274+
1275+ if (v instanceof JSONObject == false ) {
1276+ throw new IllegalArgumentException ("Request 表 structure 配置的 " + IF .name ()
1277+ + ":{ " + k + ":value } 中 value 不合法,必须是 JSONObject {} !" );
1278+ }
1279+
1280+ if (nkl .contains (k ) || real .get (k ) != null ) {
1281+ real = parse (method , name , (JSONObject ) v , real , database , schema , datasource , idCallback , creator , callback );
1282+ }
12041283 }
12051284 }
12061285 }
12071286 Log .i (TAG , "parse return real = " + JSON .toJSONString (real ));
12081287 return real ;
12091288 }
12101289
1290+ public static ScriptEngine getScriptEngine (String lang ) {
1291+ List <ScriptEngineFactory > list = StringUtil .isEmpty (lang , true ) ? null : SCRIPT_ENGINE_MANAGER .getEngineFactories ();
1292+
1293+ ScriptEngine engine = null ;
1294+ if (list == null || list .isEmpty ()) {
1295+ engine = SCRIPT_ENGINE ; // StringUtil.isEmpty(lang) ? SCRIPT_ENGINE : null;
1296+ }
1297+ else {
1298+ for (ScriptEngineFactory sef : list ) {
1299+ if (sef != null && lang .equals (sef .getEngineName ())) {
1300+ engine = sef .getScriptEngine ();
1301+ }
1302+ }
1303+ }
1304+
1305+ if (engine == null ) {
1306+ throw new NullPointerException ("找不到可执行 " + (StringUtil .isEmpty (lang , true ) ? "js" : lang ) + " 脚本的引擎!engine == null!" );
1307+ }
1308+
1309+ return engine ;
1310+ }
12111311
12121312
12131313 /**执行操作
0 commit comments