PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/src/dovetaildb/dbrepository/ParsedRequest.java

http://dovetaildb.googlecode.com/
Java | 380 lines | 293 code | 44 blank | 43 comment | 25 complexity | c90c4a8eba4c77ec9262a5eeb4d4e1b9 MD5 | raw file
  1. package dovetaildb.dbrepository;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.Reader;
  5. import java.io.StringReader;
  6. import java.net.URLDecoder;
  7. import java.util.ArrayList;
  8. import java.util.Enumeration;
  9. import java.util.HashMap;
  10. import java.util.List;
  11. import java.util.Map;
  12. import java.util.regex.Pattern;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import org.json.simple.parser.JSONParser;
  16. import org.json.simple.parser.ParseException;
  17. import dovetaildb.Action;
  18. import dovetaildb.api.ApiException;
  19. import dovetaildb.util.Util;
  20. public class ParsedRequest {
  21. private String db;
  22. private String bagName;
  23. private String id;
  24. private Object entry;
  25. private Action action;
  26. private String functionName;
  27. private String code;
  28. private Object query;
  29. private String options;
  30. private String arguments;
  31. private HttpServletRequest request;
  32. private Map<String, String> parameterMap;
  33. private HttpServletResponse response;
  34. static final Pattern slashRegexp = Pattern.compile("/+");
  35. static final Map<String,Action> cannonicalActionStrings;
  36. static {
  37. cannonicalActionStrings = new HashMap<String,Action>();
  38. cannonicalActionStrings.put("query",Action.query);
  39. cannonicalActionStrings.put("execute",Action.execute);
  40. cannonicalActionStrings.put("put",Action.put);
  41. cannonicalActionStrings.put("remove",Action.remove);
  42. cannonicalActionStrings.put("call",Action.call);
  43. }
  44. class MyReader extends StringReader {
  45. JSONParser parser;
  46. boolean atEnd = false;
  47. MyReader(String s) {
  48. super(s);
  49. parser = new JSONParser();
  50. }
  51. public String readUntil(char end) {
  52. if (atEnd) return null;
  53. try {
  54. int ch;
  55. StringBuffer buf = new StringBuffer();
  56. while(true) {
  57. ch = this.read();
  58. if (ch == end) break;
  59. if (ch == -1) {atEnd=true; break;}
  60. buf.append((char)ch);
  61. }
  62. return URLDecoder.decode(buf.toString(), "UTF-8");
  63. } catch(IOException e) {
  64. throw new RuntimeException(e);
  65. }
  66. }
  67. public String readAll() {
  68. if (atEnd) return null;
  69. try {
  70. int ch;
  71. StringBuffer buf = new StringBuffer();
  72. while(true) {
  73. ch = this.read();
  74. if (ch == -1) {atEnd=true; break;}
  75. buf.append((char)ch);
  76. }
  77. return URLDecoder.decode(buf.toString(), "UTF-8");
  78. } catch(IOException e) {
  79. throw new RuntimeException(e);
  80. }
  81. }
  82. public Object readItem() {
  83. try {
  84. try {
  85. Object ret = parser.parse(this);
  86. int ch = read();
  87. if (ch != -1 && ch != '/') {
  88. throw new ApiException("InvalidRequestUrl", "Url request is invalid");
  89. }
  90. return ret;
  91. } catch (ParseException e) {
  92. throw new ApiException("InvalidRequestUrl", "Url request is invalid");
  93. }
  94. } catch(IOException e) {
  95. throw new RuntimeException(e);
  96. }
  97. }
  98. public int peek() {
  99. if (atEnd) return -1;
  100. try {
  101. mark(1);
  102. char ch = (char)this.read();
  103. reset();
  104. return ch;
  105. } catch(IOException e) {
  106. throw new RuntimeException(e);
  107. }
  108. }
  109. }
  110. public ParsedRequest(String url, boolean insertOrUpdate, HttpServletRequest request, HttpServletResponse response, Map<String, String> params) {
  111. parameterMap = params;
  112. MyReader reader = new MyReader(url);
  113. char firstChar = ' ';
  114. try {
  115. firstChar = (char)reader.read();
  116. } catch(IOException e) {}
  117. if (firstChar != '/') {
  118. throw new ApiException("InvalidRequestUrl", "Url request is invalid");
  119. }
  120. db = reader.readUntil('/');
  121. String actionString = reader.readUntil('/');
  122. action = cannonicalActionStrings.get(actionString);
  123. if (action == null) {
  124. throw new ApiException("UnsupportedAction", "Unsupported action: \""+actionString+"\"");
  125. }
  126. this.request = request;
  127. this.response = response;
  128. parseUsingMap(parameterMap);
  129. }
  130. // private Object produceValue(String specifier, int idx, Object cur) {
  131. // int firstClose = specifier.indexOf(']');
  132. // if (firstClose <= 0) {
  133. // if (firstClose == -1) {
  134. // throw new ApiException("InvalidRequestUrl", "Invalid parameter key: "+specifier);
  135. // } else {
  136. // // array
  137. // ArrayList<Object> array;
  138. // if (cur == null) {
  139. // cur = array = new ArrayList<Object>();
  140. // } else if (!(cur instanceof ArrayList)) {
  141. // throw new ApiException("InvalidRequestUrl", "Invalid parameter key: "+specifier);
  142. // } else {
  143. // array = (ArrayList<Object>) cur;
  144. // }
  145. // }
  146. // }
  147. //
  148. // String key = specifier.substring(0, firstClose);
  149. //
  150. // }
  151. // private Map<String,Object> deepMap(HttpServletRequest request2) {
  152. // Map<String,Object> root = Util.literalSMap();
  153. // Object cur;
  154. // for(Enumeration<String> e = request.getParameterNames(); e.hasMoreElements();) {
  155. // cur = root;
  156. // String specifier = e.nextElement();
  157. // int firstOpen = specifier.indexOf('[');
  158. // if (firstOpen == -1) {
  159. // root.put(specifier, request.getParameter(specifier));
  160. // } else {
  161. // String key = specifier.substring(0,firstOpen);
  162. // Object val = (root.containsKey(key)) ? root.get(key) : null;
  163. // Object result = produceValue(specifier, firstOpen, val);
  164. // if (! root.containsKey(key)) {
  165. // root.put(key, cur=)
  166. // cur = root.get(key);
  167. // }
  168. // cur = root.get();
  169. // }
  170. // }
  171. // return null;
  172. // }
  173. public static String chkGet(Map<String,String> map, String key) {
  174. String val = map.get(key);
  175. if (val == null) throw new ApiException("MissingParameter", "A parameter named \""+key+"\" is required in this call");
  176. return val;
  177. }
  178. private void parseUsingMap(Map map) {
  179. this.setRequest(request);
  180. switch(action) {
  181. case put:
  182. case remove:
  183. case query:
  184. bagName = chkGet(map,"bag");
  185. switch(action) {
  186. case query:
  187. String queryString = chkGet(map,"query");
  188. try {
  189. query = Util.jsonDecode(queryString);
  190. } catch(Util.JsonParseRuntimeException e) {
  191. throw new ApiException("InvalidQuery", "Query is not JSON decodable: "+ e.getMessage());
  192. }
  193. options = (String)map.get("options");
  194. break;
  195. case put:
  196. String entryString = chkGet(map,"entry");
  197. try {
  198. entry = Util.jsonDecode(entryString);
  199. } catch(Util.JsonParseRuntimeException e) {
  200. throw new ApiException("InvalidEntry", "Entry is not JSON decodable: "+ e.getMessage());
  201. }
  202. break;
  203. case remove:
  204. id = chkGet(map,"id");
  205. break;
  206. }
  207. break;
  208. case call:
  209. bagName = null;
  210. functionName = chkGet(map,"function");
  211. arguments = chkGet(map,"args");
  212. break;
  213. case execute:
  214. code = chkGet(map,"code");
  215. break;
  216. }
  217. }
  218. public ParsedRequest(String db, String action, String bag, String query, String id, String entry, String method, String args, String code) {
  219. parameterMap = new HashMap();
  220. this.db = db;
  221. this.action = cannonicalActionStrings.get(action);
  222. this.bagName = bag;
  223. if (query != null)
  224. this.query = Util.jsonDecode(query);
  225. this.id = id;
  226. if (entry != null)
  227. this.entry = Util.jsonDecode(entry);
  228. this.functionName = method;
  229. this.arguments = args;
  230. this.code = code;
  231. }
  232. public static ParsedRequest makePut(String db, String bag, String entry) {
  233. return new ParsedRequest(db, "put", bag, null, null, entry, null, null, null);
  234. }
  235. public static ParsedRequest makeRemove(String db, String bag, String id) {
  236. return new ParsedRequest(db, "remove", bag, null, id, null, null, null, null);
  237. }
  238. public static ParsedRequest makeQuery(String db, String bag, String query) {
  239. return new ParsedRequest(db, "query", bag, query, null, null, null, null, null);
  240. }
  241. public static ParsedRequest makeCall(String db, String method, String args) {
  242. return new ParsedRequest(db, "call", null, null, null, null, method, args, null);
  243. }
  244. public static ParsedRequest makeExecute(String db, String code) {
  245. return new ParsedRequest(db, "execute", null, null, null, null, null, null, code);
  246. }
  247. public void setDb(String db) {
  248. this.db = db;
  249. }
  250. public String getDb() {
  251. return db;
  252. }
  253. public void setBagName(String bagName) {
  254. this.bagName = bagName;
  255. }
  256. public String getBagName() {
  257. return bagName;
  258. }
  259. public void setId(String id) {
  260. this.id = id;
  261. }
  262. public String getId() {
  263. return id;
  264. }
  265. public void setEntry(String entry) {
  266. this.entry = entry;
  267. }
  268. public Object getEntry() {
  269. return entry;
  270. }
  271. public void setAction(Action action) {
  272. this.action = action;
  273. }
  274. public Action getAction() {
  275. return action;
  276. }
  277. public String getActionString() {
  278. return action.toString();
  279. }
  280. public void setFunctionName(String methodName) {
  281. this.functionName = methodName;
  282. }
  283. public String getFunctionName() {
  284. return functionName;
  285. }
  286. public void setCode(String code) {
  287. this.code = code;
  288. }
  289. public String getCode() {
  290. return code;
  291. }
  292. public void setQuery(String query) {
  293. this.query = query;
  294. }
  295. public Object getQuery() {
  296. return query;
  297. }
  298. public void setArguments(String arguments) {
  299. this.arguments = arguments;
  300. }
  301. public String getArguments() {
  302. return arguments;
  303. }
  304. public void setRequest(HttpServletRequest request) {
  305. this.request = request;
  306. }
  307. public HttpServletRequest getRequest() {
  308. return request;
  309. }
  310. public void setResponse(HttpServletResponse response) {
  311. this.response = response;
  312. }
  313. public HttpServletResponse getResponse() {
  314. return response;
  315. }
  316. public Object getParameter(String name) {
  317. return parameterMap.get(name);
  318. }
  319. public void setParameter(String name, String value) {
  320. parameterMap.put(name, value);
  321. }
  322. public Map<String, String> getParameterMap() {
  323. return parameterMap;
  324. }
  325. public String getOptions() {
  326. return options;
  327. }
  328. public void setOptions(String options) {
  329. this.options = options;
  330. }
  331. public Map<String, Object> getOptionsAsMap() {
  332. String optionStr = getOptions();
  333. if (optionStr == null) return Util.EMPTY_SMAP;
  334. return (Map<String, Object>) Util.jsonDecode(optionStr);
  335. }
  336. }