1 package net_alchim31_maven_yuicompressor;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.io.InputStreamReader;
7 import java.io.OutputStreamWriter;
8 import java.util.zip.GZIPOutputStream;
9
10 import org.apache.maven.plugin.MojoExecutionException;
11 import org.codehaus.plexus.util.FileUtils;
12 import org.codehaus.plexus.util.IOUtil;
13
14 import com.yahoo.platform.yui.compressor.CssCompressor;
15 import com.yahoo.platform.yui.compressor.JavaScriptCompressor;
16
17
18
19
20
21
22
23
24
25
26
27 public class YuiCompressorMojo extends MojoSupport {
28
29
30
31
32
33
34 private String encoding;
35
36
37
38
39
40
41 private String suffix;
42
43
44
45
46
47
48 private boolean nosuffix;
49
50
51
52
53
54
55 private int linebreakpos;
56
57
58
59
60
61
62 private boolean nomunge;
63
64
65
66
67
68
69 private boolean preserveAllSemiColons;
70
71
72
73
74
75
76 private boolean disableOptimizations;
77
78
79
80
81
82
83
84 private boolean force;
85
86
87
88
89
90
91
92
93 private Aggregation[] aggregations;
94
95
96
97
98
99
100 private boolean gzip;
101
102
103
104
105
106
107 private boolean statistics;
108
109 private long inSizeTotal_;
110 private long outSizeTotal_;
111
112 @Override
113 protected String[] getDefaultIncludes() throws Exception {
114 return new String[]{"**/*.css", "**/*.js"};
115 }
116
117 @Override
118 public void beforeProcess() throws Exception {
119 if (nosuffix) {
120 suffix = "";
121 }
122 }
123
124 @Override
125 protected void afterProcess() throws Exception {
126 if (statistics && (inSizeTotal_ > 0)) {
127 getLog().info(String.format("total input (%db) -> output (%db)[%d%%]", inSizeTotal_, outSizeTotal_, ((outSizeTotal_ * 100)/inSizeTotal_)));
128 }
129 if (aggregations != null) {
130 for(Aggregation aggregation : aggregations) {
131 getLog().info("generate aggregation : " + aggregation.output);
132 aggregation.run();
133 File gzipped = gzipIfRequested(aggregation.output);
134 if (statistics) {
135 if (gzipped != null) {
136 getLog().info(String.format("%s (%db) -> %s (%db)[%d%%]", aggregation.output.getName(), aggregation.output.length(), gzipped.getName(), gzipped.length(), ratioOfSize(aggregation.output, gzipped)));
137 } else if (aggregation.output.exists()){
138 getLog().info(String.format("%s (%db)", aggregation.output.getName(), aggregation.output.length()));
139 } else {
140 getLog().warn(String.format("%s not created", aggregation.output.getName()));
141 }
142 }
143 }
144 }
145 }
146
147
148 @Override
149 protected void processFile(SourceFile src) throws Exception {
150 if (getLog().isDebugEnabled()) {
151 getLog().debug("compress file :" + src.toFile()+ " to " + src.toDestFile(suffix));
152 }
153 File inFile = src.toFile();
154 File outFile = src.toDestFile(suffix);
155
156 getLog().debug("only compress if input file is younger than existing output file");
157 if (!force && outFile.exists() && (outFile.lastModified() > inFile.lastModified())) {
158 if (getLog().isInfoEnabled()) {
159 getLog().info("nothing to do, " + outFile + " is younger than original, use 'force' option or clean your target");
160 }
161 return;
162 }
163
164 InputStreamReader in = null;
165 OutputStreamWriter out = null;
166 File outFileTmp = new File(outFile.getAbsolutePath() + ".tmp");
167 FileUtils.forceDelete(outFileTmp);
168 try {
169 in = new InputStreamReader(new FileInputStream(inFile), encoding);
170 if (!outFile.getParentFile().exists() && !outFile.getParentFile().mkdirs()) {
171 throw new MojoExecutionException( "Cannot create resource output directory: " + outFile.getParentFile() );
172 }
173 getLog().debug("use a temporary outputfile (in case in == out)");
174
175 getLog().debug("start compression");
176 out = new OutputStreamWriter(new FileOutputStream(outFileTmp), encoding);
177 if (".js".equalsIgnoreCase(src.getExtension())) {
178 JavaScriptCompressor compressor = new JavaScriptCompressor(in, jsErrorReporter_);
179 compressor.compress(out, linebreakpos, !nomunge, jswarn, preserveAllSemiColons, disableOptimizations);
180 } else if (".css".equalsIgnoreCase(src.getExtension())) {
181 CssCompressor compressor = new CssCompressor(in);
182 compressor.compress(out, linebreakpos);
183 }
184 getLog().debug("end compression");
185 } finally {
186 IOUtil.close(in);
187 IOUtil.close(out);
188 }
189 FileUtils.forceDelete(outFile);
190 FileUtils.rename(outFileTmp, outFile);
191 File gzipped = gzipIfRequested(outFile);
192 if (statistics) {
193 inSizeTotal_ += inFile.length();
194 outSizeTotal_ += outFile.length();
195 getLog().info(String.format("%s (%db) -> %s (%db)[%d%%]", inFile.getName(), inFile.length(), outFile.getName(), outFile.length(), ratioOfSize(inFile, outFile)));
196 if (gzipped != null) {
197 getLog().info(String.format("%s (%db) -> %s (%db)[%d%%]", inFile.getName(), inFile.length(), gzipped.getName(), gzipped.length(), ratioOfSize(inFile, gzipped)));
198 }
199 }
200 }
201
202 protected File gzipIfRequested(File file) throws Exception {
203 if (!gzip || (file == null) || (!file.exists())) {
204 return null;
205 }
206 if (".gz".equalsIgnoreCase(FileUtils.getExtension(file.getName()))) {
207 return null;
208 }
209 File gzipped = new File(file.getAbsolutePath()+".gz");
210 getLog().debug(String.format("create gzip version : %s", gzipped.getName()));
211 GZIPOutputStream out = null;
212 FileInputStream in = null;
213 try {
214 out = new GZIPOutputStream(new FileOutputStream(gzipped));
215 in = new FileInputStream(file);
216 IOUtil.copy(in, out);
217 } finally {
218 IOUtil.close(in);
219 IOUtil.close(out);
220 }
221 return gzipped;
222 }
223
224 protected long ratioOfSize(File file100, File fileX) throws Exception {
225 long v100 = Math.max(file100.length(), 1);
226 long vX = Math.max(fileX.length(), 1);
227 return (vX * 100)/v100;
228 }
229 }