package org.rendersnake.servlet;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.rendersnake.HtmlCanvas;
import org.rendersnake.HtmlCanvasFactory;
import org.rendersnake.Renderable;
import org.rendersnake.error.MissingComponentError;
import org.rendersnake.error.RenderException;
import org.rendersnake.internal.HtmlServletCanvas;
/**
* RenderSnakeServlet dispatches GET and POST request to a component which is
* detected by a RequestToComponentResolver.
*
* @author e.micklei
*
*/
public class RenderSnakeServlet extends HttpServlet {
private static final long serialVersionUID = 908531579551509272L;
private static final Logger LOG = Logger.getLogger("org.rendersnake.servlet");
/**
* On default, use the QualifiedClassNameResolver Example:
* {context-path}/{servlet-path}/org.rendersnake.HomePage
*/
private RequestToComponentResolver resolver = new QualifiedClassNameResolver();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
HtmlCanvas html = HtmlCanvasFactory.createCanvas(request, response, response.getWriter());
Renderable component = resolver.renderComponentForRequest(request);
if (component == null) {
component = new MissingComponentError(resolver);
}
try {
html.render(component);
} catch (RenderException rex) {
LOG.log(Level.SEVERE,"[renderSnake render failure]",rex);
html.render(rex);
} catch (Exception ex) {
LOG.log(Level.SEVERE,"[renderSnake render failure]",ex);
html.render(RenderException.caught(ex));
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
try {
this.safeHandle(request, response);
} catch (Exception ex) {
LOG.log(Level.SEVERE,"[renderSnake form validate|handle failure]",ex);
final HtmlCanvas html = new HtmlServletCanvas(request, response, response.getWriter());
html.render(RenderException.caught(ex));
}
}
private void safeHandle(HttpServletRequest request, HttpServletResponse response) throws IOException {
final FormHandler handler = resolver.formHandlerForRequest(request);
final FormDataPopulator populator = new FormDataPopulator();
populator.populate(request, handler);
// requires validation?
if (handler instanceof FormValidator) {
final FormValidator validator = (FormValidator)handler;
if (!validator.validate(request)) {
response.sendRedirect(request.getHeader("referer")); // TODO where is the constant in Java?
return;
}
}
FormResponseAction action = handler.handle(request, response);
// redirect to this component unless a response has been written
if (!response.isCommitted()) {
String path = action.redirectToUrl;
if (action.component != null) {
path = resolver.requestPathForComponentClass(action.component.getClass());
}
response.sendRedirect(response.encodeRedirectURL(
request.getContextPath()
+ request.getServletPath()
+ "/"
+ path));
}
}
public RequestToComponentResolver getResolver() {
return resolver;
}
public void setResolver(RequestToComponentResolver resolver) {
this.resolver = resolver;
}
@Override
public void init(ServletConfig config) throws ServletException {
this.initInspectParameter(config);
this.initResolverChain(config);
}
private void initResolverChain(ServletConfig config) throws ServletException {
// read the resolver
super.init(config);
String className = config.getInitParameter("resolver");
if (className == null || className.length() == 0) {
LOG.log(Level.INFO,"[renderSnake uses default resolver (QualifiedClassNameResolver)]");
return;
}
try {
Class<?> resolverClass = Class.forName(className);
RequestToComponentResolver newResolver = (RequestToComponentResolver) (resolverClass.newInstance());
newResolver.init(config);
// connect to current
newResolver.setNextResolver(this.resolver);
// and replace
this.setResolver(newResolver);
} catch (Exception e) {
LOG.log(Level.SEVERE,"[renderSnake init failure]",e);
throw new ServletException("[org.rendersnake.servlet.RenderSnake.init] failed", e);
}
}
private void initInspectParameter(ServletConfig config) {
// read the inspect parameter
String inspectParameter = config.getInitParameter("inspect-query-parameter");
HtmlCanvasFactory.INSPECT_QUERY_PARAM = inspectParameter == null ? "inspect" : inspectParameter;
LOG.log(Level.INFO,"[renderSnake init] inspect option activated by ?"+ HtmlCanvasFactory.INSPECT_QUERY_PARAM);
}
}