Yesterday I briefly explained how I was loading CSS files from a JAR and forcing their content through Velocity to evaluate expressions. A co-worker offered up a more simple solution, it’s after the break.
Carlos really comments his code well so this shouldn’t be too hard to follow.
package com.blakgeek.dynamicss.servlet;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* User: chenry
* Date: 6/20/11
* Time: 12:02 PM
*/
public class CssServlet extends HttpServlet {
private JspFactory jspFactory = JspFactory.getDefaultFactory();
private ExpressionFactory expressionFactory;
private List paths = new ArrayList();
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
expressionFactory = jspFactory.getJspApplicationContext(getServletContext()).getExpressionFactory();
// get the list paths to try from init params
String pathsStr = config.getInitParameter("paths");
if (pathsStr != null) {
String[] paths = pathsStr.trim().split(",");
for (String path : paths) {
this.paths.add(path.trim());
}
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream cssInputStream = null;
// set the proper content type so it will work even if its chunked
resp.setContentType("text/css");
// get the filename from url path
String cssFilename = getFilename(req.getRequestURI());
// see if its possible to load the resource from any of the defined paths
for (String path : this.paths) {
// I know string concatenation is bad but this just an example;
if (!path.endsWith("/")) path += "/";
cssInputStream = getClass().getResourceAsStream(path + cssFilename);
// as soon as you find a good resource use it
if (cssInputStream != null) break;
}
if (cssInputStream != null) {
String evaluatedCss = evaluateEL(inputStreamToString(cssInputStream), req, resp);
resp.getWriter().write(evaluatedCss);
}
}
private String inputStreamToString(InputStream is) {
return new Scanner(is).useDelimiter("\\A").next();
}
private String evaluateEL(String content, HttpServletRequest req, HttpServletResponse resp) {
ELContext elContext = jspFactory.getPageContext(this, req, resp, null, true, 8192, true).getELContext();
ValueExpression expression = expressionFactory.createValueExpression(elContext, content, String.class);
return (String) expression.getValue(elContext);
}
public String getFilename(String fullPath) {
int sep = fullPath.lastIndexOf("/");
return fullPath.substring(sep);
}
}
The next blog post should probably be about integrating this solution with WRO4J in order to bulk-load CSS and JS even from jar files.
Pingback: Loading CSS from a JAR file | Cribbs Technologies