Combining and minifying multiple javascript files into one on the fly

In the On the fly JavaScript minification using Dojo ShrinkSafe entry i built a simple ServletFilter that can be used to minify JavaScript files on the fly.

After i published that entry i got email from a reader that how can we combine and minify multiple JavaScript file into one so i built this filter which can be used to minfiy multiple JavaScript files into one and then minify the resultant file using Dojo Shrinksafe


package com.webspherenotes.performance.minfy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dojotoolkit.shrinksafe.Compressor;

/**
* Servlet implementation class ShrinkSafeAntDemoServlet
*/
public class ShrinkSafeAntDemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* Default constructor.
*/
public ShrinkSafeAntDemoServlet() {
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/javascript");
ArrayList fileList = getFileList(request.getParameter("fileList"));
String combinedFile = getCombinedFile(fileList);
System.out.println("Combined JavaScript " + combinedFile);
String outputJavaScript = Compressor.compressScript(combinedFile, 0, 1, "all");
response.getWriter().println(outputJavaScript);
}

private ArrayList getFileList(String fileListStr){
StringTokenizer st = new StringTokenizer(fileListStr, ",");
ArrayList fileList = new ArrayList();
while(st.hasMoreElements()){
fileList.add((String)st.nextElement());
}
return fileList;
}

private String getCombinedFile(ArrayList fileList) throws IOException{
StringBuffer combinedJavaScript = new StringBuffer();
for(int i = 0 ; i < fileList.size(); i++){
String fileName = (String)fileList.get(i);
System.out.println("Read the file " + fileName);
BufferedReader br = new BufferedReader( new InputStreamReader(
getServletContext().getResourceAsStream(fileName)));
String line = null;
while((line =br.readLine()) != null){
combinedJavaScript.append(line);
combinedJavaScript.append("\n");
}
}
return combinedJavaScript.toString();
}
}


You can call this servlet passing it list of JavaScript files that you want to combine as argument, i am assuming that those files are part of the same web application as that of the servlet. Assume that you have test.js, test1.js and test2.js files in your web application and instead of including each one of them separately on a page you want to include all 3 of them together like this.


< script
src='/shrinksafe/ShrinkSafeAntDemoServlet?fileList=/js/test.js,/js/test1.js,/js/test2.js' >


The ShrinkSafeAntDemoServlet first reads value of fileList parameter and parse it to find out the number of files that you want to combine, then getCombinedFile() method takes list of JavaScript files as argument and reads and combines them into a String. Once the String is read it passes control to Compressor.compressScript() method of Dojo compressor to minify the mulitple JavaScript files