package net.contextfw.web.commons.minifier; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringWriter; import java.net.URL; import java.util.Iterator; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Singleton; import com.yahoo.platform.yui.compressor.CssCompressor; @Singleton class CssMinifierServlet extends ContentServlet implements DocumentProcessor { private MinifierFilter filter; CssMinifierServlet(String host, String minifiedPath, MinifierFilter filter, long started, String version) { super(host, minifiedPath, started, version); this.filter = filter; } private static final Logger LOG = LoggerFactory.getLogger(CssMinifierServlet.class); private static final long serialVersionUID = 1L; @Override public void process(Document document) { @SuppressWarnings("unchecked") List<Element> links = document.selectNodes("//html/head//link"); StringBuilder sb = new StringBuilder(); Element firstMinified = null; Iterator<Element> iter = links.iterator(); while (iter.hasNext()) { Element link = iter.next(); String src = link.attributeValue("href"); if (src.startsWith("{$contextPath}") && filter.include(src)) { LOG.info("Including CSS: {}", src); URL url = getUrl(src.replace("{$contextPath}", this.getServletContext().getContextPath())); if (filter.minify(src)) { LOG.info("Minifying CSS: {}", url.toString()); sb.append(compress(url)).append("\n"); } else { try { LOG.info("Not minifying CSS: {}", url.toString()); sb.append(IOUtils.toString(url.openStream())).append("\n"); } catch (IOException e) { throw new WebApplicationException(e); } } if (firstMinified == null) { firstMinified = link; } else { link.detach(); } } } if (firstMinified != null) { firstMinified.addAttribute("href", "{$contextPath}" + getMinifiedPath()); } setContent(sb.toString()); } 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"; } }