package net.contextfw.web.commons.minifier;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.contextfw.web.application.ResourceCleaner;
import net.contextfw.web.application.WebApplicationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
abstract class ContentServlet extends HttpServlet {
private static final int SECOND = 1000;
private static final long serialVersionUID = 1L;
Logger logger = LoggerFactory.getLogger(ContentServlet.class);
private ThreadLocal<SimpleDateFormat> format = new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
}
};
private volatile String content;
private final String host;
private final String minifiedPath;
private final String version;
private final long started;
private static final long EXPIRATION = 60 * 60 * 1000 * 8;
private ResourceCleaner cleaner;
protected ContentServlet(String host,
String minifiedPath,
long started,
String version) {
this.host = host;
this.started = started;
this.version = version;
this.minifiedPath = minifiedPath;
this.modifiedSince = new Date(started);
}
protected URL getUrl(String src) {
try {
return new URL(host + src);
} catch (MalformedURLException e) {
throw new WebApplicationException(e);
}
}
String getMinifiedPath() {
return minifiedPath.replaceFirst("<version>", version);
}
private final Date modifiedSince;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
if (content == null) {
synchronized (this) {
if (content == null) {
cleaner.clean();
}
}
}
resp.setContentType(getContentType());
String modifiedHeader = req.getHeader("If-Modified-Since");
Date mod = null;
if (modifiedHeader != null) {
try {
mod = format.get().parse(modifiedHeader);
} catch (ParseException e) {
logger.error("Error while parsing", e);
}
}
HttpServletResponse httpResponse = (HttpServletResponse) resp;
httpResponse.setDateHeader("Expires", started + EXPIRATION);
httpResponse.setDateHeader("Date", started);
httpResponse.setDateHeader("Last-Modified", started+SECOND);
httpResponse.setHeader("Cache-Control", "max-age=2246400, must-revalidate");
httpResponse.setHeader("Pragma", "cache");
if (content != null && mod != null && modifiedSince.before(mod)) {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
} else {
resp.getWriter().print(content);
}
}
protected abstract String getContentType();
public void setContent(String content) {
this.content = content;
}
@Inject
public void setCleaner(ResourceCleaner cleaner) {
this.cleaner = cleaner;
}
}