package org.siqisource.mozo.servlets;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileDeleteStrategy;
import org.apache.commons.io.FileUtils;
import org.siqisource.mozo.context.Path;
import com.yahoo.platform.yui.compressor.CssCompressor;
import com.yahoo.platform.yui.compressor.JavaScriptCompressor;
public class YuiCombineServlet extends HttpServlet {
private static Map<String, String> cachedResources = new HashMap<String, String>();
private String cacheContextPath = "uilibrary/yui/cache/" ;
private String cacheDir = Path.getPhysicalPath() + cacheContextPath;
int linebreakpos = - 1 ;
boolean munge = true ;
boolean verbose = false ;
boolean preserveAllSemiColons = false ;
boolean disableOptimizations = false ;
@Override
public void init() throws ServletException {
File catchedDir = new File(cacheDir);
if (catchedDir.exists()) {
FileDeleteStrategy strategy = FileDeleteStrategy.FORCE;
try {
strategy.delete(catchedDir);
} catch (IOException e) {
e.printStackTrace();
}
}
catchedDir.mkdirs();
super .init();
}
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String queryString = request.getQueryString();
String resourcePath = cachedResources.get(queryString);
if (resourcePath == null ) {
String[] resources = queryString.split( "&" );
String firstResource = resources[ 0 ];
String fileName = UUID.randomUUID().toString();
if (firstResource.endsWith( ".js" )) {
fileName += ".js" ;
Writer writer = new FileWriter(cacheDir + fileName);
for (String resource : resources) {
Reader reader = new FileReader(Path.getPhysicalPath()
+ resource);
JavaScriptCompressor compressor = new JavaScriptCompressor(
reader, null );
compressor.compress(writer, linebreakpos, munge, verbose,
preserveAllSemiColons, disableOptimizations);
reader.close();
}
writer.flush();
writer.close();
} else if (resources[ 0 ].endsWith( ".css" )) {
fileName += ".css" ;
Writer writer = new FileWriter(cacheDir + fileName);
for (String resource : resources) {
Reader reader = new FileReader(replacedUrlFile(resource));
CssCompressor compressor = new CssCompressor(reader);
compressor.compress(writer, linebreakpos);
reader.close();
}
writer.flush();
writer.close();
}
resourcePath = cacheContextPath + fileName;
cachedResources.put(queryString, resourcePath);
}
request.getRequestDispatcher(resourcePath).forward(request, response);
return ;
}
public String replacedUrlFile(String fileName) throws IOException {
String cssfilePath = Path.getPhysicalPath() + fileName;
File cssFile = new File(cssfilePath);
String tempCssFilePath = cacheDir + "tmp-css-" + cssFile.getName();
File tempCssFile = new File(tempCssFilePath);
if (tempCssFile.exists()) {
return tempCssFilePath;
}
String css = FileUtils.readFileToString(cssFile);
int maxIndex = css.length() - 1 ;
int appendIndex = 0 ;
Pattern p = Pattern.compile( "url\\(\\s*([\"']?)" );
if (!p.matcher(css).find()) {
return cssfilePath;
}
Matcher m = p.matcher(css);
String url = fileName.substring( 0 , fileName.lastIndexOf( '/' ));
url = Path.getContextPath() + "/" + url + "/" ;
StringBuffer replacedUrlCss = new StringBuffer();
while (m.find()) {
int startIndex = m.start() + 4 ;
String terminator = m.group( 1 );
if (terminator.length() == 0 ) {
terminator = ")" ;
}
boolean foundTerminator = false ;
int endIndex = m.end() - 1 ;
while (foundTerminator == false && endIndex + 1 <= maxIndex) {
endIndex = css.indexOf(terminator, endIndex + 1 );
if ((endIndex > 0 ) && (css.charAt(endIndex - 1 ) != '\\' )) {
foundTerminator = true ;
if (! ")" .equals(terminator)) {
endIndex = css.indexOf( ")" , endIndex);
}
}
}
replacedUrlCss.append(css.substring(appendIndex, m.start()));
if (foundTerminator) {
String token = css.substring(startIndex, endIndex);
token = token.replaceAll( "\\s+" , "" );
String preserver = "url('" + url + token + "')" ;
replacedUrlCss.append(preserver);
appendIndex = endIndex + 1 ;
} else {
replacedUrlCss.append(css.substring(m.start(), m.end()));
appendIndex = m.end();
}
}
FileUtils.writeStringToFile(tempCssFile, replacedUrlCss.toString());
return tempCssFilePath;
}
}
|