• R/O
  • SSH
  • HTTPS

jsonic: コミット


コミットメタ情報

リビジョン1843 (tree)
日時2014-10-26 17:05:02
作者hizuno

ログメッセージ

(メッセージはありません)

変更サマリ

差分

--- trunk/jsonic-1.3/src/net/arnx/jsonic/web/RESTServlet.java (revision 1842)
+++ trunk/jsonic-1.3/src/net/arnx/jsonic/web/RESTServlet.java (revision 1843)
@@ -1,12 +1,12 @@
1-/*
1+/*
22 * Copyright 2014 Hidekatsu Izuno
3- *
3+ *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
66 * You may obtain a copy of the License at
7- *
7+ *
88 * http://www.apache.org/licenses/LICENSE-2.0
9- *
9+ *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1212 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -50,13 +50,13 @@
5050 public class RESTServlet extends HttpServlet {
5151 private static final Map<String, String> DEFAULT_METHOD = new HashMap<String, String>();
5252 private static final Set<String> DEFAULT_VERB = new HashSet<String>();
53-
53+
5454 static {
5555 DEFAULT_METHOD.put("GET", "find");
5656 DEFAULT_METHOD.put("POST", "create");
5757 DEFAULT_METHOD.put("PUT", "update");
5858 DEFAULT_METHOD.put("DELETE", "delete");
59-
59+
6060 DEFAULT_VERB.add("HEAD");
6161 DEFAULT_VERB.add("GET");
6262 DEFAULT_VERB.add("POST");
@@ -64,31 +64,31 @@
6464 DEFAULT_VERB.add("DELETE");
6565 DEFAULT_VERB.add("OPTIONS");
6666 }
67-
67+
6868 static class Config {
6969 public Class<? extends Container> container;
70-
70+
7171 @JSONHint(anonym="target")
7272 public Map<String, RouteMapping> mappings;
73-
73+
7474 public Map<String, Pattern> definitions;
7575 public Map<String, Integer> errors;
7676 public Map<String, String> method;
7777 public Set<String> verb;
7878 }
79-
79+
8080 protected Container container;
81-
81+
8282 Config config;
83-
83+
8484 @Override
8585 public void init(ServletConfig servletConfig) throws ServletException {
8686 super.init(servletConfig);
87-
87+
8888 String configText = servletConfig.getInitParameter("config");
89-
89+
9090 JSON json = new JSON();
91-
91+
9292 if (configText == null) {
9393 Map<String, String> map = new HashMap<String, String>();
9494 Enumeration<String> e = cast(servletConfig.getInitParameterNames());
@@ -97,7 +97,7 @@
9797 }
9898 configText = json.format(map);
9999 }
100-
100+
101101 try {
102102 config = json.parse(configText, Config.class);
103103 if (config.container == null) config.container = Container.class;
@@ -106,73 +106,73 @@
106106 } catch (Exception e) {
107107 throw new ServletException(e);
108108 }
109-
109+
110110 if (config.definitions == null) config.definitions = new HashMap<String, Pattern>();
111111 if (!config.definitions.containsKey("package")) config.definitions.put("package", Pattern.compile(".+"));
112-
112+
113113 if (config.errors == null) config.errors = Collections.emptyMap();
114-
114+
115115 if (config.method == null) config.method = DEFAULT_METHOD;
116116 if (config.verb == null) config.verb = DEFAULT_VERB;
117-
117+
118118 if (config.mappings == null) config.mappings = Collections.emptyMap();
119119 for (Map.Entry<String, RouteMapping> entry : config.mappings.entrySet()) {
120120 entry.getValue().init(entry.getKey(), config);
121121 }
122122 }
123-
123+
124124 @Override
125125 protected void doHead(HttpServletRequest request, HttpServletResponse response)
126126 throws ServletException, IOException {
127127 doREST(request, response);
128128 }
129-
129+
130130 @Override
131131 protected void doGet(HttpServletRequest request, HttpServletResponse response)
132132 throws ServletException, IOException {
133133 doREST(request, response);
134134 }
135-
135+
136136 @Override
137137 protected void doPost(HttpServletRequest request, HttpServletResponse response)
138138 throws ServletException, IOException {
139139 doREST(request, response);
140140 }
141-
141+
142142 @Override
143143 protected void doPut(HttpServletRequest request, HttpServletResponse response)
144144 throws ServletException, IOException {
145145 doREST(request, response);
146146 }
147-
147+
148148 @Override
149- protected void doDelete(HttpServletRequest request, HttpServletResponse response)
149+ protected void doDelete(HttpServletRequest request, HttpServletResponse response)
150150 throws ServletException, IOException {
151151 doREST(request, response);
152152 }
153-
153+
154154 @Override
155155 protected void doOptions(HttpServletRequest request, HttpServletResponse response)
156156 throws ServletException, IOException {
157157 doREST(request, response);
158158 }
159-
159+
160160 protected void doREST(HttpServletRequest request, HttpServletResponse response)
161161 throws ServletException, IOException {
162-
162+
163163 int status = SC_OK;
164164 JSON json = null;
165165 String callback = null;
166166 Object result = null;
167-
167+
168168 try {
169- ExternalContext.start(getServletConfig(), getServletContext(), request, response);
169+ ExternalContext.start(getServletConfig(), getServletContext(), request, response);
170170 container.start(request, response);
171-
171+
172172 String uri = (request.getContextPath().equals("/")) ?
173- request.getRequestURI() :
173+ request.getRequestURI() :
174174 request.getRequestURI().substring(request.getContextPath().length());
175-
175+
176176 Route route = null;
177177 for (RouteMapping m : config.mappings.values()) {
178178 if ((route = m.matches(request, uri)) != null) {
@@ -180,32 +180,32 @@
180180 break;
181181 }
182182 }
183-
183+
184184 if (route == null) {
185185 response.sendError(SC_NOT_FOUND, "Not Found");
186186 return;
187187 }
188-
188+
189189 if (route.getHttpMethod() == null || route.getRestMethod() == null) {
190190 container.debug("Method mapping not found: " + route.getHttpMethod());
191191 response.sendError(SC_METHOD_NOT_ALLOWED, "Method Not Allowed");
192- return;
192+ return;
193193 }
194-
194+
195195 if ("GET".equals(request.getMethod())) {
196196 callback = route.getParameter("callback");
197197 } else if ("POST".equals(route.getHttpMethod())) {
198198 status = SC_CREATED;
199199 }
200-
200+
201201 json = container.createJSON(request.getLocale());
202-
202+
203203 String className = route.getComponentClass(container);
204204 Object component = container.getComponent(className);
205205 if (component == null) {
206206 throw new ClassNotFoundException("Component not found: " + className);
207207 }
208-
208+
209209 List<Object> params = null;
210210 if (isJSONType(request.getContentType())) {
211211 Object o = json.parse(request.getReader());
@@ -221,18 +221,19 @@
221221 params = new ArrayList<Object>(1);
222222 params.add(route.mergeParameterMap((Map<?, ?>)o));
223223 } else {
224- throw new IllegalArgumentException("failed to convert parameters from JSON.");
224+ params = new ArrayList<Object>(1);
225+ params.add(o);
225226 }
226227 } else {
227228 params = new ArrayList<Object>(1);
228- params.add(route.getParameterMap());
229+ params.add(route.getParameterMap());
229230 }
230-
231+
231232 Method method = container.getMethod(component, route.getRestMethod(), params);
232233 if (method == null) {
233- throw new NoSuchMethodException("Method not found: " + route.getRestMethod());
234+ throw new NoSuchMethodException("Method not found: " + route.getRestMethod());
234235 }
235-
236+
236237 json.setContext(component);
237238 result = container.execute(json, component, method, params);
238239 } catch (Exception e) {
@@ -256,10 +257,10 @@
256257 if (cause instanceof Error) {
257258 throw (Error)cause;
258259 }
259-
260+
260261 container.debug("Cause error on invocation.", cause);
261262 container.exception((Exception)cause, request, response);
262-
263+
263264 if (cause instanceof IllegalStateException || cause instanceof UnsupportedOperationException) {
264265 response.sendError(SC_NOT_FOUND, "Not Found");
265266 response.flushBuffer();
@@ -276,7 +277,7 @@
276277 }
277278 }
278279 if (errorCode != null) {
279- response.setStatus(errorCode);
280+ response.setStatus(errorCode);
280281 Map<String, Object> error = new LinkedHashMap<String, Object>();
281282 error.put("name", cause.getClass().getSimpleName());
282283 error.put("message", cause.getMessage());
@@ -283,7 +284,7 @@
283284 error.put("data", container.getErrorData(cause));
284285 result = error;
285286 } else {
286- response.sendError(SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
287+ response.sendError(SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
287288 response.flushBuffer();
288289 }
289290 }
@@ -290,19 +291,19 @@
290291 } else {
291292 container.error("Internal error occurred.", e);
292293 container.exception(e, request, response);
293- response.sendError(SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
294+ response.sendError(SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
294295 response.flushBuffer();
295296 }
296297 } finally {
297298 try {
298- container.end(request, response);
299+ container.end(request, response);
299300 } finally {
300- ExternalContext.end();
301+ ExternalContext.end();
301302 }
302303 }
303-
304+
304305 if (response.isCommitted()) return;
305-
306+
306307 if (result == null
307308 || result instanceof CharSequence
308309 || result instanceof Boolean
@@ -318,31 +319,31 @@
318319 if (callback != null) writer.append(");");
319320 }
320321 }
321-
322+
322323 @Override
323324 public void destroy() {
324325 container.destory();
325326 super.destroy();
326327 }
327-
328+
328329 static class RouteMapping {
329330 static final Pattern PLACE_PATTERN = Pattern.compile("\\{\\s*(\\p{javaJavaIdentifierStart}[\\p{javaJavaIdentifierPart}\\.-]*)\\s*(?::\\s*((?:[^{}]|\\{[^{}]*\\})*)\\s*)?\\}");
330331 static final Pattern DEFAULT_PATTERN = Pattern.compile("[^/().]+");
331-
332+
332333 public String target;
333334 public Map<String, String> method;
334335 public Set<String> verb;
335-
336+
336337 Config config;
337338 Pattern pattern;
338339 List<String> names;
339-
340+
340341 public RouteMapping() {
341342 }
342-
343+
343344 public void init(String path, Config config) {
344345 this.config = config;
345-
346+
346347 this.names = new ArrayList<String>();
347348 StringBuffer sb = new StringBuffer("^\\Q");
348349 Matcher m = PLACE_PATTERN.matcher(path);
@@ -353,7 +354,7 @@
353354 if (p == null && config.definitions.containsKey(name)) {
354355 p = config.definitions.get(name);
355356 }
356- if (p == null) p = DEFAULT_PATTERN;
357+ if (p == null) p = DEFAULT_PATTERN;
357358 m.appendReplacement(sb, "\\\\E(" + p.pattern().replaceAll("\\((?!\\?)", "(?:").replace("\\", "\\\\") + ")\\\\Q");
358359 }
359360 m.appendTail(sb);
@@ -360,12 +361,12 @@
360361 sb.append("\\E$");
361362 this.pattern = Pattern.compile(sb.toString());
362363 }
363-
364+
364365 @SuppressWarnings({"unchecked", "rawtypes"})
365366 public Route matches(HttpServletRequest request, String path) throws IOException {
366367 Matcher m = pattern.matcher(path);
367368 if (m.matches()) {
368- Map<String, Object> params = new HashMap<String, Object>();
369+ Map<String, Object> params = new HashMap<String, Object>();
369370 for (int i = 0; i < names.size(); i++) {
370371 String key = names.get(i);
371372 Object value = m.group(i+1);
@@ -382,7 +383,7 @@
382383 params.put(key, value);
383384 }
384385 }
385-
386+
386387 String httpMethod = request.getParameter("_method");
387388 if (httpMethod == null) httpMethod = request.getMethod();
388389 if (httpMethod != null) httpMethod = httpMethod.toUpperCase();
@@ -392,7 +393,7 @@
392393 } else if (!config.verb.contains(httpMethod)) {
393394 httpMethod = null;
394395 }
395-
396+
396397 Object restMethod = params.get("method");
397398 if (restMethod instanceof List<?>) {
398399 List<?> list = ((List<?>)restMethod);
@@ -404,13 +405,13 @@
404405 if (restMethod == null) {
405406 restMethod = config.method.get(httpMethod);
406407 }
407-
408+
408409 parseParameter(request.getParameterMap(), (Map)params);
409410 return new Route(httpMethod, (String)restMethod, target, params);
410411 }
411412 return null;
412413 }
413-
414+
414415 @SuppressWarnings("unchecked")
415416 static void parseParameter(Map<String, String[]> pairs, Map<Object, Object> params) {
416417 for (Map.Entry<String, String[]> entry : pairs.entrySet()) {
@@ -421,7 +422,7 @@
421422 multiValue = true;
422423 }
423424 String[] values = entry.getValue();
424-
425+
425426 int start = 0;
426427 char old = '\0';
427428 Map<Object, Object> current = params;
@@ -430,7 +431,7 @@
430431 if (c == '.' || c == '[') {
431432 String key = name.substring(start, (old == ']') ? i-1 : i);
432433 Object target = current.get(key);
433-
434+
434435 if (target instanceof Map) {
435436 current = (Map<Object, Object>)target;
436437 } else {
@@ -443,9 +444,9 @@
443444 }
444445 old = c;
445446 }
446-
447+
447448 name = name.substring(start, (old == ']') ? name.length()-1 : name.length());
448-
449+
449450 Object key = name;
450451 if (name.length() > 0 && name.charAt(0) >= '0' && name.charAt(0) <= '9') {
451452 try {
@@ -454,10 +455,10 @@
454455 key = name;
455456 }
456457 }
457-
458+
458459 if (current.containsKey(key)) {
459460 Object target = current.get(key);
460-
461+
461462 if (target instanceof Map) {
462463 Map<Object, Object> map = (Map<Object, Object>)target;
463464 if (map.containsKey(null)) {
@@ -476,7 +477,7 @@
476477 for (String value : values) list.add(value);
477478 map.put(null, list);
478479 } else {
479- map.put(null, (values.length > 0) ? values[0] : null);
480+ map.put(null, (values.length > 0) ? values[0] : null);
480481 }
481482 } else if (target instanceof List) {
482483 List<Object> list = ((List<Object>)target);
@@ -497,15 +498,15 @@
497498 }
498499 }
499500 }
500-
501+
501502 static class Route {
502503 static final Pattern REPLACE_PATTERN = Pattern.compile("\\$\\{(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)\\}");
503-
504+
504505 String target;
505506 String httpMethod;
506507 String restMethod;
507508 Map<Object, Object> params;
508-
509+
509510 public Route(String httpMethod, String restMethod, String target, Map<String, Object> params) throws IOException {
510511 this.httpMethod = httpMethod;
511512 this.restMethod = restMethod;
@@ -512,35 +513,35 @@
512513 this.target = target;
513514 this.params = cast(params);
514515 }
515-
516+
516517 public String getHttpMethod() {
517518 return httpMethod;
518519 }
519-
520+
520521 public String getRestMethod() {
521522 return restMethod;
522523 }
523-
524+
524525 public String getParameter(String name) {
525526 Object o = params.get(name);
526-
527+
527528 if (o instanceof Map<?, ?>) {
528529 Map<?, ?> map = (Map<?, ?>)o;
529- if (map.containsKey(null)) o = map.get(null);
530+ if (map.containsKey(null)) o = map.get(null);
530531 }
531-
532+
532533 if (o instanceof List<?>) {
533534 List<?> list = (List<?>)o;
534535 if (!list.isEmpty()) o = list.get(0);
535536 }
536-
537+
537538 return (o instanceof String) ? (String)o : null;
538539 }
539-
540+
540541 public Map<?, ?> getParameterMap() {
541542 return params;
542543 }
543-
544+
544545 public String getComponentClass(Container container) {
545546 Matcher m = REPLACE_PATTERN.matcher(target);
546547 StringBuffer sb = new StringBuffer();
@@ -547,25 +548,25 @@
547548 while (m.find()) {
548549 String key = m.group(1);
549550 String value = getParameter(key);
550-
551+
551552 if (key.equals("class") && container.namingConversion) {
552553 value = ClassUtil.toUpperCamel(value);
553554 } else if (key.equals("package")) {
554555 value = value.replace('/', '.');
555556 }
556-
557+
557558 m.appendReplacement(sb, (value != null) ? value : "");
558559 }
559560 m.appendTail(sb);
560561 return sb.toString();
561562 }
562-
563+
563564 @SuppressWarnings("unchecked")
564565 public Map<?, ?> mergeParameterMap(Map<?, ?> newParams) {
565566 for (Map.Entry<?, ?> entry : newParams.entrySet()) {
566567 if (params.containsKey(entry.getKey())) {
567568 Object target = params.get(entry.getKey());
568-
569+
569570 if (target instanceof Map) {
570571 Map<Object, Object> map = (Map<Object, Object>)target;
571572 if (map.containsKey(null)) {
旧リポジトリブラウザで表示