Skip to content

Commit 4977331

Browse files
committed
Server:从Parser提取出ObjectParser,大幅简化Parser
1 parent 5822909 commit 4977331

2 files changed

Lines changed: 429 additions & 196 deletions

File tree

Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
package zuo.biao.apijson.server;
2+
3+
import static zuo.biao.apijson.RequestMethod.PUT;
4+
5+
import java.util.LinkedHashMap;
6+
import java.util.LinkedHashSet;
7+
import java.util.Map;
8+
import java.util.Map.Entry;
9+
import java.util.Set;
10+
11+
import javax.validation.constraints.NotNull;
12+
13+
import com.alibaba.fastjson.JSONArray;
14+
import com.alibaba.fastjson.JSONObject;
15+
16+
import zuo.biao.apijson.Log;
17+
import zuo.biao.apijson.RequestMethod;
18+
import zuo.biao.apijson.server.exception.ConflictException;
19+
import zuo.biao.apijson.server.exception.NotExistException;
20+
import zuo.biao.apijson.server.sql.QueryConfig;
21+
22+
/**简化Parser,getObject和getArray(getArrayConfig)都能用
23+
* @author Lemon
24+
*/
25+
public abstract class ObjectParser {
26+
private static final String TAG = "ObjectParser";
27+
28+
29+
/**
30+
* @param path path of target
31+
* @return
32+
*/
33+
protected abstract Object getTarget(String path);
34+
35+
36+
37+
38+
39+
protected RequestMethod requestMethod;
40+
protected String parentPath;
41+
protected String path;
42+
protected String table;
43+
protected final boolean isTableKey;
44+
protected JSONObject request;
45+
46+
public ObjectParser(RequestMethod requestMethod, String parentPath, String name, @NotNull JSONObject request) {
47+
if (request == null) {
48+
throw new IllegalArgumentException(TAG + ".ObjectParser request == null!!!");
49+
}
50+
this.requestMethod = requestMethod;
51+
this.parentPath = parentPath;
52+
this.path = Parser.getAbsPath(parentPath, name);
53+
this.table = Pair.parseEntry(name, true).getKey();
54+
this.isTableKey = Parser.isTableKey(table);
55+
this.request = request;
56+
Log.d(TAG, "ObjectParser table = " + table + "; isTableKey = " + isTableKey);
57+
}
58+
59+
60+
61+
protected JSONObject response;
62+
protected JSONObject childObject;
63+
protected Map<String, Object> customMap;
64+
protected Map<String, String> functionMap;
65+
66+
/**解析成员
67+
* @param request
68+
* @return null or this
69+
* @throws Exception
70+
*/
71+
public ObjectParser parse() throws Exception {
72+
response = new JSONObject(true);//must init
73+
74+
Set<Entry<String, Object>> set = new LinkedHashSet<>(request.entrySet());
75+
if (set != null && set.isEmpty() == false) {//判断换取少几个变量的初始化是否值得?
76+
if (isTableKey) {
77+
customMap = new LinkedHashMap<String, Object>();
78+
functionMap = new LinkedHashMap<String, String>();
79+
}
80+
81+
String key;
82+
Object value;
83+
for (Entry<String, Object> entry : set) {
84+
value = entry.getValue();
85+
if (value == null) {
86+
continue;
87+
}
88+
key = entry.getKey();
89+
90+
if (value instanceof JSONObject) {//JSONObject,往下一级提取
91+
onChildParse(key, (JSONObject) value);
92+
} else if (requestMethod == PUT && value instanceof JSONArray) {//PUT JSONArray
93+
onPUTArrayParse(key, (JSONArray) value);
94+
} else {//JSONArray或其它Object,直接填充
95+
if (onParse(key, value) == false) {
96+
return null;
97+
}
98+
}
99+
}
100+
}
101+
102+
return this;
103+
}
104+
105+
/**
106+
* @param key
107+
* @param value
108+
* @throws Exception
109+
*/
110+
protected void onChildParse(String key, JSONObject value) throws Exception {
111+
childObject.put(key, value);
112+
}
113+
/**
114+
* @return
115+
* @throws Exception
116+
*/
117+
protected JSONObject onSQLExecute() throws Exception {
118+
return response;
119+
}
120+
121+
/**解析普通成员
122+
* @param key
123+
* @param value
124+
* @return whether parse succeed
125+
*/
126+
protected boolean onParse(String key, Object value) throws Exception {
127+
if (key.endsWith("@")) {//StringUtil.isPath((String) value)) {
128+
if (value instanceof String == false) {
129+
throw new IllegalArgumentException("\"key@\": 后面必须为依赖路径String!");
130+
}
131+
// System.out.println("getObject key.endsWith(@) >> parseRelation = " + parseRelation);
132+
String replaceKey = key.substring(0, key.length() - 1);//key{}@ getRealKey
133+
String targetPath = Parser.getValuePath(parentPath, new String((String) value));
134+
135+
//先尝试获取,尽量保留缺省依赖路径,这样就不需要担心路径改变
136+
Object target = getTarget(targetPath);
137+
Log.i(TAG, "getObject targetPath = " + targetPath + ";> + target);
138+
139+
if (target == null) {//String#equals(null)会出错
140+
Log.d(TAG, "getObject null >> continue;");
141+
return true;
142+
}
143+
if (targetPath.equals(target)) {//必须valuePath和保证getValueByPath传进去的一致!
144+
Log.d(TAG, "getObject targetPath.equals(target) >>");
145+
146+
//非查询关键词 @key 不影响查询,直接跳过
147+
if (isTableKey && (key.startsWith("@") == false || QueryConfig.TABLE_KEY_LIST.contains(key))) {
148+
Log.e(TAG, "getObject isTableKey && (key.startsWith(@) == false"
149+
+ " || QueryConfig.TABLE_KEY_LIST.contains(key)) >> return null;");
150+
recycle();
151+
return false;//获取不到就不用再做无效的query了。不考虑 Table:{Table:{}}嵌套
152+
} else {
153+
Log.d(TAG, "getObject isTableKey(table) == false >> continue;");
154+
return true;//舍去,对Table无影响
155+
}
156+
}
157+
158+
159+
//直接替换原来的key@:path为key:target
160+
Log.i(TAG, "getObject >> key = replaceKey; value = target;");
161+
key = replaceKey;
162+
value = target;
163+
Log.d(TAG, "getObject key = " + key + "; value = " + value);
164+
}
165+
166+
if (isTableKey == false) {//不查询,所以不必分开
167+
response.put(key, value);
168+
} else {
169+
if (key.endsWith("()")) {
170+
if (value instanceof String == false) {
171+
throw new IllegalArgumentException(path + "/" + key + "():function() 后面必须为函数String!");
172+
}
173+
functionMap.put(key, (String) value);
174+
} else if (key.startsWith("@") && QueryConfig.TABLE_KEY_LIST.contains(key) == false) {
175+
customMap.put(key, value);
176+
} else {
177+
response.put(key, value);
178+
}
179+
}
180+
181+
return true;
182+
}
183+
184+
185+
/**PUT key:[]
186+
* @param key
187+
* @param array
188+
* @throws Exception
189+
*/
190+
protected void onPUTArrayParse(String key, JSONArray array) throws Exception {
191+
if (isTableKey == false || array == null || array.isEmpty()) {
192+
Log.e(TAG, "onPUTArray isTableKey == false || array == null || array.isEmpty() >> return;");
193+
return;
194+
}
195+
196+
int putType = 0;
197+
if (key.endsWith("+")) {//add
198+
putType = 1;
199+
} else if (key.endsWith("-")) {//remove
200+
putType = 2;
201+
} else {//replace
202+
throw new IllegalAccessException("PUT " + path + ", PUT Array不允许 " + key +
203+
" 这种没有 + 或 - 结尾的key!不允许整个替换掉原来的Array!");
204+
}
205+
String realKey = Parser.getRealKey(requestMethod, key, false, false);
206+
207+
//GET > add all 或 remove all > PUT > remove key
208+
209+
//GET <<<<<<<<<<<<<<<<<<<<<<<<<
210+
JSONObject rq = new JSONObject();
211+
rq.put(QueryConfig.ID, request.get(QueryConfig.ID));
212+
rq.put(JSONRequest.KEY_COLUMN, realKey);
213+
JSONObject rp = new Parser().parseResponse(new JSONRequest(table, rq));
214+
//GET >>>>>>>>>>>>>>>>>>>>>>>>>
215+
216+
217+
//add all 或 remove all <<<<<<<<<<<<<<<<<<<<<<<<<
218+
if (rp != null) {
219+
rp = rp.getJSONObject(table);
220+
}
221+
JSONArray targetArray = rp == null ? null : rp.getJSONArray(realKey);
222+
if (targetArray == null) {
223+
targetArray = new JSONArray();
224+
}
225+
for (Object obj : array) {
226+
if (obj == null) {
227+
continue;
228+
}
229+
if (putType == 1) {
230+
if (targetArray.contains(obj)) {
231+
throw new ConflictException("PUT " + path + ", " + realKey + ":" + obj + " 已存在!");
232+
}
233+
targetArray.add(obj);
234+
} else if (putType == 2) {
235+
if (targetArray.contains(obj) == false) {
236+
throw new NullPointerException("PUT " + path + ", " + realKey + ":" + obj + " 不存在!");
237+
}
238+
targetArray.remove(obj);
239+
}
240+
}
241+
242+
//add all 或 remove all >>>>>>>>>>>>>>>>>>>>>>>>>
243+
244+
//PUT <<<<<<<<<<<<<<<<<<<<<<<<<
245+
response.put(realKey, targetArray);
246+
//PUT >>>>>>>>>>>>>>>>>>>>>>>>>
247+
248+
}
249+
250+
251+
/**SQL查询,for single object
252+
* @return
253+
* @throws Exception
254+
*/
255+
public JSONObject executeSQL() throws Exception {
256+
return executeSQL(1, 0, 0);
257+
}
258+
259+
protected QueryConfig config = null;//array item复用
260+
/**SQL查询,for array item
261+
* @param count
262+
* @param page
263+
* @param position
264+
* @return
265+
* @throws Exception
266+
*/
267+
public JSONObject executeSQL(int count, int page, int position) throws Exception {
268+
boolean query = false;
269+
//执行SQL操作数据库
270+
if (isTableKey()) {//提高性能
271+
query = true;
272+
273+
if (config == null) {
274+
config = QueryConfig.newQueryConfig(requestMethod, table, response);
275+
}
276+
config.setCount(count).setPage(page).setPosition(position);
277+
278+
try {
279+
response = onSQLExecute();
280+
} catch (Exception e) {
281+
Log.e(TAG, "getObject try { response = getSQLObject(config2); } catch (Exception e) {");
282+
if (e instanceof NotExistException) {//非严重异常,有时候只是数据不存在
283+
// e.printStackTrace();
284+
response = null;//内部吃掉异常,put到最外层
285+
// requestObject.put(JSONResponse.KEY_MESSAGE
286+
// , StringUtil.getString(requestObject.get(JSONResponse.KEY_MESSAGE)
287+
// + "; query " + path + " cath NotExistException:"
288+
// + newErrorResult(e).getString(JSONResponse.KEY_MESSAGE)));
289+
} else {
290+
throw e;
291+
}
292+
}
293+
}
294+
295+
if (response == null) {
296+
response = new JSONObject(true);
297+
}
298+
299+
if (customMap != null) {
300+
response.putAll(customMap);
301+
}
302+
if (functionMap != null) {
303+
if (query) {
304+
//解析函数function
305+
Set<String> functionSet = functionMap == null ? null : functionMap.keySet();
306+
if (functionSet != null && functionSet.isEmpty() == false) {
307+
for (String key : functionSet) {
308+
response.put(Parser.getRealKey(requestMethod, key, false, false)
309+
, Function.invoke(response, functionMap.get(key)));
310+
}
311+
}
312+
} else {
313+
response.putAll(functionMap);
314+
}
315+
}
316+
317+
onComplete();
318+
319+
return response;
320+
}
321+
322+
/**
323+
* response has the final value after parse (and query if isTableKey)
324+
*/
325+
protected void onComplete() {
326+
}
327+
328+
329+
/**回收内存
330+
*/
331+
public void recycle() {
332+
requestMethod = null;
333+
parentPath = null;
334+
path = null;
335+
table = null;
336+
337+
// if (response != null) {
338+
// response.clear();//有效果?
339+
// response = null;
340+
// }
341+
342+
response = null;
343+
childObject = null;
344+
functionMap = null;
345+
customMap = null;
346+
}
347+
348+
349+
350+
351+
352+
353+
354+
355+
public String getPath() {
356+
return path;
357+
}
358+
public String getTable() {
359+
return table;
360+
}
361+
public boolean isTableKey() {
362+
return isTableKey;
363+
}
364+
public JSONObject getResponse() {
365+
return response;
366+
}
367+
public JSONObject getChildObject() {
368+
return childObject;
369+
}
370+
public Map<String, String> getFunctionMap() {
371+
return functionMap;
372+
}
373+
public Map<String, Object> getCustomMap() {
374+
return customMap;
375+
}
376+
377+
}

0 commit comments

Comments
 (0)