Skip to content

Instantly share code, notes, and snippets.

@contextfw
Created August 1, 2011 16:41
Show Gist options
  • Select an option

  • Save contextfw/1118487 to your computer and use it in GitHub Desktop.

Select an option

Save contextfw/1118487 to your computer and use it in GitHub Desktop.
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
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 com.google.inject.Inject;
import com.google.inject.name.Named;
public abstract class ContentServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private ThreadLocal<SimpleDateFormat> format = new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
}
};
private String content;
@Inject
@Named("developmentMode")
private boolean developmentMode;
private final Date modifiedSince = Calendar.getInstance().getTime();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
resp.setContentType(getContentType());
String modifiedHeader = req.getHeader("If-Modified-Since");
Date mod = null;
if (modifiedHeader != null) {
try {
mod = format.get().parse(modifiedHeader);
} catch (Exception e) {
// Just ignore
}
}
if (mod != null && modifiedSince.before(mod)) {
resp.sendError(HttpServletResponse.SC_NOT_MODIFIED);
} else {
resp.getWriter().print(content);
}
}
protected abstract String getContentType();
public boolean isDevelopmentMode() {
return developmentMode;
}
public void setContent(String content) {
this.content = content;
}
}
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import net.contextfw.web.application.DocumentProcessor;
import net.contextfw.web.application.WebApplicationException;
import org.dom4j.Document;
import org.dom4j.Element;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.yahoo.platform.yui.compressor.CssCompressor;
@Singleton
public class CssMinifierServlet extends ContentServlet implements DocumentProcessor {
private static final long serialVersionUID = 1L;
@Inject
@Named("host")
private String host;
@Inject
@Named("started")
private String started;
@Override
public void process(Document document) {
if (isDevelopmentMode()) return;
List<Element> links = document.selectNodes("//html/head/link");
StringBuilder sb = new StringBuilder();
for (Element script : links) {
String src = script.attributeValue("href");
if (src.startsWith("{$contextPath}")) {
src = src.replace("{$contextPath}", "");
URL url;
try {
url = new URL(host + src);
sb.append(compress(url)).append("\n");
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
setContent(sb.toString());
links.get(0).addAttribute("href", "{$contextPath}/minified-"+started+".css");
for (int i = 1; i < links.size(); i++) {
links.get(i).detach();
}
}
private String compress(URL url) {
try {
CssCompressor compressor = new CssCompressor(new InputStreamReader(url.openStream()));
StringWriter writer = new StringWriter();
compressor.compress(writer, 0);
return writer.toString();
} catch (Exception e) {
throw new WebApplicationException(url.toString(), e);
}
}
@Override
protected String getContentType() {
return "text/css";
}
}
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import net.contextfw.web.application.DocumentProcessor;
import net.contextfw.web.application.WebApplicationException;
import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.javascript.jscomp.Compiler;
import com.google.javascript.jscomp.CompilerOptions;
import com.google.javascript.jscomp.JSSourceFile;
@Singleton
public class JsMinifierServlet extends ContentServlet implements DocumentProcessor {
private static final long serialVersionUID = 1L;
@Inject
@Named("host")
private String host;
@Inject
@Named("started")
private String started;
@Override
public void process(Document document) {
if (isDevelopmentMode()) return;
List<Element> scripts = document.selectNodes("//html/head/script[@src]");
StringBuilder sb = new StringBuilder();
for (Element script : scripts) {
String src = script.attributeValue("src");
if (src.startsWith("{$contextPath}")) {
src = src.replace("{$contextPath}", "");
URL url;
try {
url = new URL(host + src);
if (src.contains("jquery")) {
sb.append(IOUtils.toString(url.openStream())).append("\n");
} else {
sb.append(compress(url)).append("\n");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
scripts.get(0).addAttribute("src", "{$contextPath}/minified-"+started+".js");
for (int i = 1; i < scripts.size(); i++) {
scripts.get(i).detach();
}
setContent(sb.toString());
}
private String compress(URL url) {
try {
CompilerOptions options = new CompilerOptions();
Compiler compiler = new Compiler();
JSSourceFile source = JSSourceFile.fromInputStream(url.getFile(), url.openStream());
compiler.compile(new JSSourceFile[] {}, new JSSourceFile[] {source} , options);
return compiler.toSource();
} catch (Exception e) {
throw new WebApplicationException(url.toString(), e);
}
}
@Override
protected String getContentType() {
return "application/javascript";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment