package org.slim3.controller;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slim3.controller.validator.Errors;
import org.slim3.util.AppEngineUtil;
import scenic3.AppUrlsInitializeException;
import scenic3.ScenicController;
import scenic3.Urls;
/**
* FrontController for Scenic3
* @author shuji.w6e
* @since 0.1.0
*/
public class ScenicFrontController extends FrontController {
/** Urls */
private Urls urls;
boolean overideHttpMethod = false;
/**
* init controller
*/
@Override
public void init(FilterConfig config) throws ServletException {
super.init(config);
urls = getUrls();
String ohm = config.getInitParameter("scenic3.httpMethodOveride");
this.overideHttpMethod = ohm != null && ohm.equalsIgnoreCase("true");
}
/**
* Init AppUrls
* @return
* @throws AppUrlsInitializeException
*/
protected Urls initUrls() throws AppUrlsInitializeException {
String className = rootPackageName + "." + getControllerPackageName() + ".AppUrls";
try {
Class<?> clazz = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
return (Urls) clazz.newInstance();
} catch (Throwable t) {
String msg = "You should create a class '" + className + "' implements scenic3.Urls .";
throw new AppUrlsInitializeException(msg, t);
}
}
/**
* Return {@link Urls}.
* <p>If urls is not init or development environment, call initUrls to create.
* @return
*/
protected Urls getUrls() {
if (urls == null || AppEngineUtil.isDevelopment()) {
return initUrls();
}
return urls;
}
@Override
protected Controller getController(HttpServletRequest request, HttpServletResponse response, String path) {
Controller controller = createController(path, getMethodForREST(request));
if (controller == null || controller == ScenicController.STATIC_CONTROLLER) {
return null;
}
request.setAttribute(ControllerConstants.CONTROLLER_KEY, controller);
controller.servletContext = servletContext;
controller.request = request;
controller.response = response;
int pos = path.lastIndexOf('/');
controller.basePath = path.substring(0, pos + 1);
Errors errors = (Errors) request.getAttribute(ControllerConstants.ERRORS_KEY);
if (errors == null) {
errors = new Errors();
request.setAttribute(ControllerConstants.ERRORS_KEY, errors);
}
controller.errors = errors;
return controller;
}
// POST Override
String getMethodForREST(HttpServletRequest request) {
if (!this.overideHttpMethod) return request.getMethod();
String xMethod = request.getHeader("X-HTTP-Override-Method");
if (xMethod != null) return xMethod;
String method = request.getMethod();
xMethod = request.getParameter("_method");
if (xMethod == null) return method;
if (method.equalsIgnoreCase("POST") && (xMethod.equalsIgnoreCase("PUT") || xMethod.equalsIgnoreCase("DELETE"))) {
return xMethod;
}
return method;
}
@Override
protected Controller createController(String path) throws IllegalStateException {
throw new AssertionError("use createController(path, method) when using scenic3");
}
protected Controller createController(String path, String method) throws IllegalStateException {
Controller controller = getUrls().createController(path, method);
if (controller != null) return controller;
return super.createController(path);
}
}