001 package com.softwarementors.extjs.djn.jscodegen; 002 003 import java.io.IOException; 004 import java.io.Reader; 005 import java.io.StringReader; 006 import java.io.StringWriter; 007 import java.io.UnsupportedEncodingException; 008 import java.io.Writer; 009 010 import org.apache.log4j.Logger; 011 import org.mozilla.javascript.ErrorReporter; 012 import org.mozilla.javascript.EvaluatorException; 013 014 import com.softwarementors.extjs.djn.StringUtils; 015 import com.softwarementors.extjs.djn.Timer; 016 import com.yahoo.platform.yui.compressor.JavaScriptCompressor; 017 018 public class Minifier { 019 020 private static final Logger logger = Logger.getLogger( Minifier.class); 021 022 private Minifier() { 023 // Avoid instantation 024 } 025 026 public static String getMinifiedFileName(String file) { 027 assert !StringUtils.isEmpty(file); 028 029 String result = file.replace( ".js", "-min.js" ); 030 return result; 031 } 032 033 public static final String minify( String input, String inputFilename, int debugCodeLength ) throws IOException { 034 assert input != null; 035 assert !StringUtils.isEmpty(inputFilename); 036 assert debugCodeLength > 0; 037 038 try { 039 Timer timer = new Timer(); 040 // logger.debug( "Starting minification for '" + inputFilename + "'..."); 041 Reader in = new StringReader( input ); 042 JavaScriptCompressor compressor = new JavaScriptCompressor(in, new ErrorReporter() { 043 public void warning(String message, String sourceName, 044 int line, String lineSource, int lineOffset) { 045 if (line < 0) { 046 logger.warn("Minifier Warning: " + message); 047 } else { 048 logger.warn("Minifier Warning, " + line + ':' + lineOffset + ':' + message); 049 } 050 } 051 052 public void error(String message, String sourceName, 053 int line, String lineSource, int lineOffset) { 054 if (line < 0) { 055 logger.warn("Minifier Error: " + message); 056 } else { 057 logger.warn("Minifier Error, " + line + ':' + lineOffset + ':' + message); 058 } 059 } 060 061 public EvaluatorException runtimeError(String message, String sourceName, 062 int line, String lineSource, int lineOffset) { 063 error(message, sourceName, line, lineSource, lineOffset); 064 return new EvaluatorException(message); 065 } 066 }); 067 068 // Close the input stream first, and then open the output stream, 069 // in case the output file should override the input file. 070 in.close(); in = null; 071 072 try { 073 Writer out = new StringWriter(); 074 boolean munge = true; 075 boolean preserveAllSemiColons = false; 076 boolean disableOptimizations = false; 077 boolean verbose = false; 078 int linebreakpos = 0; 079 080 compressor.compress(out, linebreakpos, munge, verbose, 081 preserveAllSemiColons, disableOptimizations); 082 out.close(); 083 String result = out.toString(); 084 if( logger.isDebugEnabled() ) { 085 timer.stop(); 086 int compressionPercentage = 100 - (result.length() * 100 / debugCodeLength); 087 timer.logDebugTimeInMilliseconds( "Finished minification for '" + inputFilename + "'. Debug code length: " + debugCodeLength + ", Minified length: " + result.length() + ", Compression: " + compressionPercentage + "%. Time"); 088 } 089 return result; 090 } 091 catch (UnsupportedEncodingException e) { 092 logger.warn( "Unable to minify '" + inputFilename + "'.", e ); 093 return null; 094 } 095 } 096 catch (EvaluatorException e) { 097 logger.warn( "Unable to minify '" + inputFilename + "' due to a problem with the Javascript evaluator.", e ); 098 return null; 099 } 100 } 101 102 }