status = SC_CREATED;
}
container.start(request, response);
JSON json = container.createJSON(request.getLocale());
try {
String className = route.getComponentClass(container);
Object component = container.getComponent(className);
if (component == null) {
throw new ClassNotFoundException("Component not found: " + className);
}
List<Object> params = null;
if (isJSONType(request.getContentType())) {
Object o = json.parse(request.getReader());
if (o instanceof List<?>) {
params = cast(o);
if (params.isEmpty()) {
params = new ArrayList<Object>(1);
params.add(route.getParameterMap());
} else if (params.get(0) instanceof Map<?, ?>) {
params.set(0, route.mergeParameterMap((Map<?, ?>)params.get(0)));
}
} else if (o instanceof Map<?, ?>) {
params = new ArrayList<Object>(1);
params.add(route.mergeParameterMap((Map<?, ?>)o));
} else {
throw new IllegalArgumentException("failed to convert parameters from JSON.");
}
} else {
params = new ArrayList<Object>(1);
params.add(route.getParameterMap());
}
Method method = container.getMethod(component, route.getRestMethod(), params);
if (method == null) {
throw new NoSuchMethodException("Method not found: " + route.getRestMethod());
}
json.setContext(component);
result = container.execute(json, component, method, params);
} catch (Exception e) {
if (e instanceof ClassNotFoundException) {
container.debug("Class Not Found.", e);
response.sendError(SC_NOT_FOUND, "Not Found");
response.flushBuffer();
} else if (e instanceof NoSuchMethodException) {
container.debug("Method Not Found.", e);
response.sendError(SC_NOT_FOUND, "Not Found");
response.flushBuffer();
} else if (e instanceof JSONException) {
container.debug("Fails to parse JSON.", e);
response.sendError(SC_BAD_REQUEST, "Bad Request");
response.flushBuffer();
} else if (e instanceof InvocationTargetException) {
Throwable cause = e.getCause();
container.debug("Cause error on invocation.", cause);
if (cause instanceof Error) {
throw (Error)cause;
} else if (cause instanceof IllegalStateException || cause instanceof UnsupportedOperationException) {
response.sendError(SC_NOT_FOUND, "Not Found");
response.flushBuffer();
} else if (cause instanceof IllegalArgumentException) {
response.sendError(SC_BAD_REQUEST, "Bad Request");
response.flushBuffer();
} else {
Integer errorCode = null;
for (Map.Entry<Class<? extends Exception>, Integer> entry : config.errors.entrySet()) {
if (entry.getKey().isAssignableFrom(cause.getClass()) && entry.getValue() != null) {
errorCode = entry.getValue();
break;
}
}
if (errorCode != null) {
response.setStatus(errorCode);
Map<String, Object> error = new LinkedHashMap<String, Object>();
error.put("name", cause.getClass().getSimpleName());
error.put("message", cause.getMessage());
error.put("data", cause);
result = error;
} else {
response.sendError(SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
response.flushBuffer();
}
}
} else {
container.error("Internal error occurred.", e);
response.sendError(SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
response.flushBuffer();
}
} finally {
container.end(request, response);
}
if (response.isCommitted()) return;
if (result == null
|| result instanceof CharSequence
|| result instanceof Boolean
|| result instanceof Number
|| result instanceof Date) {
if (status != SC_CREATED) status = SC_NO_CONTENT;
response.setStatus(status);
} else {
response.setContentType((callback != null) ? "text/javascript" : "application/json");
Writer writer = response.getWriter();
json.setPrettyPrint(container.isDebugMode());
if (callback != null) writer.append(callback).append("(");
json.format(result, writer);
if (callback != null) writer.append(");");
}
}