package com.google.sitebricks;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.jcip.annotations.Immutable;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.sitebricks.headless.Reply;
import com.google.sitebricks.headless.ReplyBasedHeadlessRenderer;
import com.google.sitebricks.headless.Request;
import com.google.sitebricks.routing.RoutingDispatcher;
import com.google.sitebricks.routing.RoutingDispatcher.Events;
/**
* @author Dhanji R. Prasanna (dhanji@gmail.com)
*/
@Immutable
@Singleton
class SitebricksFilter implements Filter {
private final RoutingDispatcher dispatcher;
private final Provider<Bootstrapper> bootstrapper;
private final Provider<Shutdowner> teardowner;
private final Provider<Request> requestProvider;
private final ReplyBasedHeadlessRenderer headlessRenderer;
@Inject
public SitebricksFilter(RoutingDispatcher dispatcher, Provider<Bootstrapper> bootstrapper,
Provider<Shutdowner> teardowner, Provider<Request> requestProvider,
ReplyBasedHeadlessRenderer headlessRenderer) {
this.dispatcher = dispatcher;
this.bootstrapper = bootstrapper;
this.teardowner = teardowner;
this.requestProvider = requestProvider;
this.headlessRenderer = headlessRenderer;
}
public void init(FilterConfig filterConfig) throws ServletException {
bootstrapper.get().start();
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//dispatch
Object respondObject = dispatcher.dispatch(this.requestProvider.get(), Events.DURING);
//was there any matching page? (if it was a headless response, we don't need to do anything).
// Also we do not do anything if the page elected to do nothing.
if (null != respondObject && null == request.getAttribute(Reply.NO_REPLY_ATTR)) {
// Only use the string rendering pipeline if this is not a headless request.
if (respondObject instanceof Respond) {
Respond respond = (Respond) respondObject;
//do we need to redirect or was this a successful render?
final String redirect = respond.getRedirect();
if (null != redirect) {
response.sendRedirect(redirect);
} else { //successful render
// by checking if a content type was set, we allow users to override content-type
// on an arbitrary basis
if (null == response.getContentType()) {
response.setContentType(respond.getContentType());
}
response.getWriter().write(respond.toString());
}
} else { // It must be a headless Reply. Render the headless response.
headlessRenderer.render(response, respondObject);
}
} else {
//continue down filter-chain
filterChain.doFilter(request, response);
}
}
public void destroy() {
teardowner.get().shutdown();
}
}