package org.dtk; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.mozilla.javascript.ContextFactory; import sun.misc.BASE64Encoder; public class BuilderServlet extends HttpServlet { private String builderPath; private String cachePath; // ***************************************************** public void init() throws ServletException { super.init(); // Read in the builderPath. // - context-param // - Java system property ServletContext sc = getServletContext(); builderPath = sc.getInitParameter("builderPath"); cachePath = sc.getInitParameter("cachePath"); if (builderPath == null || builderPath.length() == 0) { builderPath = System.getProperty("builderPath"); cachePath = System.getProperty("cachePath"); } if (cachePath == null || cachePath.length() == 0) { cachePath = System.getProperty("cachePath"); } } // ***************************************************** public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { doGet(req, res); } // ***************************************************** public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //Pull out the parameters. String version = req.getParameter("version"); String cdn = req.getParameter("cdn"); String dependencies = req.getParameter("dependencies"); String optimize = req.getParameter("optimize"); String cacheFile = null; String result = null; boolean isCached = false; Boolean isError = true; //Validate parameters if(!version.equals("1.3.2")) { result = "invalid version: " + version; } if(!cdn.equals("google") && !cdn.equals("aol")) { result = "invalide CDN type: " + cdn; } if(!optimize.equals("comments") && !optimize.equals("shrinksafe") && !optimize.equals("none") && !optimize.equals("shrinksafe.keepLines")) { result = "invalid optimize type: " + optimize; } if(!dependencies.matches("^[\\w\\-\\,\\s\\.]+$")) { result = "invalid dependency list: " + dependencies; } try { //See if we already did the work. MessageDigest md = null; try { md = MessageDigest.getInstance("SHA"); } catch (NoSuchAlgorithmException e) { result = e.getMessage(); } if (result == null) { md.update(dependencies.getBytes()); String digest = (new BASE64Encoder()).encode(md.digest()).replace('+', '~').replace('/', '_').replace('=', '_'); cacheFile = cachePath + "/" + version + "/" + cdn + "/" + digest + "/" + optimize + ".js"; File file = new File(cacheFile); if (file.exists()) { isCached = true; isError = false; } } //Generate the build. if (result == null && !isCached) { BuilderContextAction contextAction = new BuilderContextAction(builderPath, version, cdn, dependencies, optimize); ContextFactory.getGlobal().call(contextAction); Exception exception = contextAction.getException(); if (exception != null) { result = exception.getMessage(); } else { result = contextAction.getResult(); FileUtil.writeToFile(cacheFile, result, null, true); isError = false; } } } catch (Exception e) { result = e.getMessage(); } //Write out response. res.setCharacterEncoding("utf-8"); if (isError) { result = result.replaceAll("\\\"", "\\\""); result = "<html><head><script type=\"text/javascript\">alert(\"" + result + "\");</script></head><body></body></html>"; PrintWriter writer = res.getWriter(); writer.append(result); } else { res.setHeader("Content-Type", "application/x-javascript"); res.setHeader("Content-disposition", "attachment; filename=dojo.js"); res.setHeader("Content-Encoding", "gzip"); //Read in the gzipped bytes of the cached file. File file = new File(cacheFile); BufferedInputStream in = new java.io.BufferedInputStream( new DataInputStream(new FileInputStream(file))); OutputStream out = res.getOutputStream(); byte[] bytes = new byte[64000]; int bytesRead = 0; while (bytesRead != -1) { bytesRead = in.read(bytes); if (bytesRead != -1) { out.write(bytes, 0, bytesRead); } } } } }