View Javadoc
1   /*
2    *    Copyright 2011-2025 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package com.tunyk.mvn.plugins.htmlcompressor;
17  
18  import com.google.javascript.jscomp.CompilationLevel;
19  import com.google.javascript.jscomp.SourceFile;
20  import com.googlecode.htmlcompressor.compressor.ClosureJavaScriptCompressor;
21  import com.googlecode.htmlcompressor.compressor.Compressor;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.nio.charset.Charset;
26  import java.nio.file.Files;
27  import java.nio.file.Path;
28  import java.text.DecimalFormat;
29  import java.text.NumberFormat;
30  import java.util.ArrayList;
31  import java.util.List;
32  import java.util.regex.Pattern;
33  import java.util.regex.PatternSyntaxException;
34  
35  import org.apache.maven.plugin.AbstractMojo;
36  import org.apache.maven.plugin.MojoExecutionException;
37  import org.apache.maven.plugins.annotations.LifecyclePhase;
38  import org.apache.maven.plugins.annotations.Mojo;
39  import org.apache.maven.plugins.annotations.Parameter;
40  
41  /**
42   * Compress HTML files.
43   */
44  @Mojo(name = "html", defaultPhase = LifecyclePhase.COMPILE, requiresProject = false, threadSafe = true)
45  public class HtmlCompressorMojo extends AbstractMojo {
46  
47      /** file where statistics of html compression is stored. */
48      @Parameter(property = "htmlcompressor.htmlCompressionStatistics", defaultValue = "${project.build.directory}/htmlcompressor/html-compression-statistics.txt")
49      private String htmlCompressionStatistics = "target/htmlcompressor/html-compression-statistics.txt";
50  
51      /**
52       * file types to be processed.
53       *
54       * @deprecated use fileExtensions
55       */
56      @Deprecated
57      @Parameter(property = "htmlcompressor.fileExt")
58      private String[] fileExt;
59  
60      /**
61       * File extensions to be processed.
62       */
63      @Parameter(property = "htmlcompressor.fileExtensions")
64      private String[] fileExtensions;
65  
66      /** if false all compression is off (default is true). */
67      @Parameter(property = "htmlcompressor.enabled", defaultValue = "true")
68      private boolean enabled = true;
69  
70      /** Skip run of plugin. */
71      @Parameter(defaultValue = "false", alias = "skip", property = "skip")
72      private boolean skip;
73  
74      /** if false keeps HTML comments (default is true). */
75      @Parameter(property = "htmlcompressor.removeComments", defaultValue = "true")
76      private boolean removeComments = true;
77  
78      /** if false keeps multiple whitespace characters (default is true). */
79      @Parameter(property = "htmlcompressor.removeMultiSpaces", defaultValue = "true")
80      private boolean removeMultiSpaces = true;
81  
82      /** removes iter-tag whitespace characters. */
83      @Parameter(property = "htmlcompressor.removeIntertagSpaces", defaultValue = "false")
84      private boolean removeIntertagSpaces;
85  
86      /** removes unnecessary tag attribute quotes. */
87      @Parameter(property = "htmlcompressor.removeQuotes", defaultValue = "false")
88      private boolean removeQuotes;
89  
90      /** simplify existing doctype. */
91      @Parameter(property = "htmlcompressor.simpleDoctype", defaultValue = "false")
92      private boolean simpleDoctype;
93  
94      /** remove optional attributes from script tags. */
95      @Parameter(property = "htmlcompressor.removeScriptAttributes", defaultValue = "false")
96      private boolean removeScriptAttributes;
97  
98      /** remove optional attributes from style tags. */
99      @Parameter(property = "htmlcompressor.removeStyleAttributes", defaultValue = "false")
100     private boolean removeStyleAttributes;
101 
102     /** remove optional attributes from link tags. */
103     @Parameter(property = "htmlcompressor.removeLinkAttributes", defaultValue = "false")
104     private boolean removeLinkAttributes;
105 
106     /** remove optional attributes from form tags. */
107     @Parameter(property = "htmlcompressor.removeFormAttributes", defaultValue = "false")
108     private boolean removeFormAttributes;
109 
110     /** remove optional attributes from input tags. */
111     @Parameter(property = "htmlcompressor.removeInputAttributes", defaultValue = "false")
112     private boolean removeInputAttributes;
113 
114     /** remove values from boolean tag attributes. */
115     @Parameter(property = "htmlcompressor.simpleBooleanAttributes", defaultValue = "false")
116     private boolean simpleBooleanAttributes;
117 
118     /** remove "javascript:" from inline event handlers. */
119     @Parameter(property = "htmlcompressor.removeJavaScriptProtocol", defaultValue = "false")
120     private boolean removeJavaScriptProtocol;
121 
122     /** replace "http://" with "//" inside tag attributes. */
123     @Parameter(property = "htmlcompressor.removeHttpProtocol", defaultValue = "false")
124     private boolean removeHttpProtocol;
125 
126     /** replace "https://" with "//" inside tag attributes. */
127     @Parameter(property = "htmlcompressor.removeHttpsProtocol", defaultValue = "false")
128     private boolean removeHttpsProtocol;
129 
130     /** compress inline css. */
131     @Parameter(property = "htmlcompressor.compressCss", defaultValue = "false")
132     private boolean compressCss;
133 
134     /** preserves original line breaks. */
135     @Parameter(property = "htmlcompressor.preserveLineBreaks", defaultValue = "false")
136     private boolean preserveLineBreaks;
137 
138     /** --line-break param for Yahoo YUI Compressor. */
139     @Parameter(property = "htmlcompressor.yuiCssLineBreak", defaultValue = "-1")
140     private int yuiCssLineBreak = -1;
141 
142     /** css compressor. */
143     // TODO JWL 4/22/2023 Unsupported
144     @SuppressWarnings("unused")
145     @Parameter(property = "htmlcompressor.cssCompressor", defaultValue = "")
146     private Compressor cssCompressor;
147 
148     /** compress inline javascript. */
149     @Parameter(property = "htmlcompressor.compressJavaScript", defaultValue = "false")
150     private boolean compressJavaScript;
151 
152     /** javascript compression: "yui" or "closure". */
153     @Parameter(property = "htmlcompressor.jsCompressor", defaultValue = "yui")
154     private String jsCompressor = "yui";
155 
156     /** javascript compression. */
157     // TODO JWL 4/22/2023Unsupported
158     @SuppressWarnings("unused")
159     @Parameter(property = "htmlcompressor.javaScriptCompressor", defaultValue = "")
160     private Compressor javaScriptCompressor;
161 
162     /** --nomunge param for Yahoo YUI Compressor. */
163     @Parameter(property = "htmlcompressor.yuiJsNoMunge", defaultValue = "false")
164     private boolean yuiJsNoMunge;
165 
166     /** --preserve-semi param for Yahoo YUI Compressor. */
167     @Parameter(property = "htmlcompressor.yuiJsPreserveAllSemiColons", defaultValue = "false")
168     private boolean yuiJsPreserveAllSemiColons;
169 
170     /** --line-break param for Yahoo YUI Compressor. */
171     @Parameter(property = "htmlcompressor.yuiJsLineBreak", defaultValue = "-1")
172     private int yuiJsLineBreak = -1;
173 
174     /** closureOptLevel = "simple", "advanced" or "whitespace". */
175     @Parameter(property = "htmlcompressor.closureOptLevel", defaultValue = "simple")
176     private String closureOptLevel = "simple";
177 
178     /** --disable-optimizations param for Yahoo YUI Compressor. */
179     @Parameter(property = "htmlcompressor.yuiJsDisableOptimizations", defaultValue = "false")
180     private boolean yuiJsDisableOptimizations;
181 
182     /**
183      * predefined patterns for most often used custom preservation rules: PHP_TAG_PATTERN and SERVER_SCRIPT_TAG_PATTERN.
184      */
185     @Parameter(property = "htmlcompressor.predefinedPreservePatterns")
186     private String[] predefinedPreservePatterns;
187 
188     /** preserve patterns. */
189     @Parameter(property = "htmlcompressor.preservePatterns")
190     private String[] preservePatterns;
191 
192     /** list of files containing preserve patterns. */
193     @Parameter(property = "htmlcompressor.preservePatternFiles")
194     private File[] preservePatternFiles;
195 
196     /** HTML compression statistics. */
197     @Parameter(property = "htmlcompressor.generateStatistics", defaultValue = "true")
198     private boolean generateStatistics = true;
199 
200     /**
201      * source folder where html files are located.
202      */
203     @Parameter(property = "htmlcompressor.srcFolder", defaultValue = "${basedir}/src/main/resources")
204     private String srcFolder = "src/main/resources";
205 
206     /**
207      * target folder where compressed html files will be placed.
208      */
209     @Parameter(property = "htmlcompressor.targetFolder", defaultValue = "${project.build.directory}/classes")
210     private String targetFolder = "target/classes";
211 
212     /**
213      * Create javascript file which includes all compressed html files as json object. If set to true then
214      * javascriptHtmlSpriteIntegrationFile param is required, otherwise it will throw exception.
215      */
216     @Parameter(property = "htmlcompressor.javascriptHtmlSprite", defaultValue = "true")
217     private boolean javascriptHtmlSprite = true;
218 
219     /**
220      * JavaScript sprite integration file (first occurrence of "%s" will be substituted by json with all compressed html
221      * strings).
222      */
223     @Parameter(property = "htmlcompressor.javascriptHtmlSpriteIntegrationFile", defaultValue = "${basedir}/src/main/resources/html/integration.js")
224     private String javascriptHtmlSpriteIntegrationFile = "src/main/resources/html/integration.js";
225 
226     /**
227      * The target JavaScript sprite file with compressed html files as json object.
228      */
229     @Parameter(property = "htmlcompressor.javascriptHtmlSpriteTargetFile", defaultValue = "${project.build.directory}/htmlcompressor/html/integration.js")
230     private String javascriptHtmlSpriteTargetFile = "target/htmlcompressor/html/integration.js";
231 
232     /** Charset encoding for files to read and create. */
233     @Parameter(property = "htmlcompressor.encoding", defaultValue = "UTF-8")
234     private String encoding = "UTF-8";
235 
236     /**
237      * Disable default built-in closure externs.
238      */
239     @Parameter(property = "htmlcompressor.closureCustomExternsOnly", defaultValue = "false")
240     private boolean closureCustomExternsOnly;
241 
242     /**
243      * Sets custom closure externs file list.
244      */
245     @Parameter(property = "htmlcompressor.closureExterns")
246     private String[] closureExterns;
247 
248     @Override
249     public void execute() throws MojoExecutionException {
250         // Check if plugin run should be skipped
251         if (this.skip) {
252             getLog().info("HtmlCompressor is skipped");
253             return;
254         }
255 
256         if (!enabled) {
257             getLog().info("HTML compression was turned off.");
258             return;
259         }
260 
261         if (!Files.exists(Path.of(srcFolder))) {
262             getLog().warn("Compressor folder does not exist, skipping compression of " + srcFolder);
263             return;
264         }
265 
266         getLog().info("Compressing " + srcFolder);
267         HtmlCompressor htmlCompressor = new HtmlCompressor(srcFolder, targetFolder);
268 
269         // Deprecated
270         if (fileExt != null && fileExtensions == null) {
271             fileExtensions = fileExt;
272         }
273 
274         htmlCompressor.setFileExtensions(fileExtensions);
275         htmlCompressor.setFileEncoding(Charset.forName(encoding));
276         htmlCompressor.setCreateJsonFile(javascriptHtmlSprite);
277         htmlCompressor.setJsonIntegrationFilePath(javascriptHtmlSpriteIntegrationFile);
278         htmlCompressor.setTargetJsonFilePath(javascriptHtmlSpriteTargetFile);
279 
280         com.googlecode.htmlcompressor.compressor.HtmlCompressor htmlCompressorHandler = new com.googlecode.htmlcompressor.compressor.HtmlCompressor();
281         htmlCompressorHandler.setEnabled(enabled);
282         htmlCompressorHandler.setRemoveComments(removeComments);
283         htmlCompressorHandler.setRemoveMultiSpaces(removeMultiSpaces);
284         htmlCompressorHandler.setRemoveIntertagSpaces(removeIntertagSpaces);
285         htmlCompressorHandler.setRemoveQuotes(removeQuotes);
286         htmlCompressorHandler.setSimpleDoctype(simpleDoctype);
287         htmlCompressorHandler.setRemoveScriptAttributes(removeScriptAttributes);
288         htmlCompressorHandler.setRemoveStyleAttributes(removeStyleAttributes);
289         htmlCompressorHandler.setRemoveLinkAttributes(removeLinkAttributes);
290         htmlCompressorHandler.setRemoveFormAttributes(removeFormAttributes);
291         htmlCompressorHandler.setRemoveInputAttributes(removeInputAttributes);
292         htmlCompressorHandler.setSimpleBooleanAttributes(simpleBooleanAttributes);
293         htmlCompressorHandler.setRemoveJavaScriptProtocol(removeJavaScriptProtocol);
294         htmlCompressorHandler.setRemoveHttpProtocol(removeHttpProtocol);
295         htmlCompressorHandler.setRemoveHttpsProtocol(removeHttpsProtocol);
296         htmlCompressorHandler.setCompressCss(compressCss);
297         htmlCompressorHandler.setPreserveLineBreaks(preserveLineBreaks);
298         htmlCompressorHandler.setYuiCssLineBreak(yuiCssLineBreak);
299         htmlCompressorHandler.setCompressJavaScript(compressJavaScript);
300         htmlCompressorHandler.setYuiJsNoMunge(yuiJsNoMunge);
301         htmlCompressorHandler.setYuiJsPreserveAllSemiColons(yuiJsPreserveAllSemiColons);
302         htmlCompressorHandler.setYuiJsLineBreak(yuiJsLineBreak);
303         htmlCompressorHandler.setYuiJsDisableOptimizations(yuiJsDisableOptimizations);
304         htmlCompressorHandler.setGenerateStatistics(generateStatistics);
305 
306         if (jsCompressor.equalsIgnoreCase("closure")) {
307             ClosureJavaScriptCompressor closureCompressor = new ClosureJavaScriptCompressor();
308             if (closureOptLevel != null
309                     && closureOptLevel.equalsIgnoreCase(ClosureJavaScriptCompressor.COMPILATION_LEVEL_ADVANCED)) {
310                 closureCompressor.setCompilationLevel(CompilationLevel.ADVANCED_OPTIMIZATIONS);
311                 closureCompressor.setCustomExternsOnly(closureCustomExternsOnly);
312                 if (closureExterns.length > 0) {
313                     List<SourceFile> externs = new ArrayList<>();
314                     for (String externFile : closureExterns) {
315                         externs.add(SourceFile.fromFile(externFile));
316                     }
317                     closureCompressor.setExterns(externs);
318                 }
319             } else if (closureOptLevel != null
320                     && closureOptLevel.equalsIgnoreCase(ClosureJavaScriptCompressor.COMPILATION_LEVEL_WHITESPACE)) {
321                 closureCompressor.setCompilationLevel(CompilationLevel.WHITESPACE_ONLY);
322             } else {
323                 closureCompressor.setCompilationLevel(CompilationLevel.SIMPLE_OPTIMIZATIONS);
324             }
325 
326             htmlCompressorHandler.setJavaScriptCompressor(closureCompressor);
327         }
328 
329         List<Pattern> preservePatternList = new ArrayList<>();
330         boolean phpTagPatternAdded = false;
331         boolean serverScriptTagPatternAdded = false;
332         if (predefinedPreservePatterns != null) {
333             for (String pattern : predefinedPreservePatterns) {
334                 if (!phpTagPatternAdded && pattern.equalsIgnoreCase("PHP_TAG_PATTERN")) {
335                     preservePatternList.add(com.googlecode.htmlcompressor.compressor.HtmlCompressor.PHP_TAG_PATTERN);
336                     phpTagPatternAdded = true;
337                 } else if (!serverScriptTagPatternAdded && pattern.equalsIgnoreCase("SERVER_SCRIPT_TAG_PATTERN")) {
338                     preservePatternList
339                             .add(com.googlecode.htmlcompressor.compressor.HtmlCompressor.SERVER_SCRIPT_TAG_PATTERN);
340                     serverScriptTagPatternAdded = true;
341                 }
342             }
343         }
344         if (preservePatterns != null) {
345             for (String preservePatternString : preservePatterns) {
346                 if (!preservePatternString.isEmpty()) {
347                     try {
348                         preservePatternList.add(Pattern.compile(preservePatternString));
349                     } catch (PatternSyntaxException e) {
350                         throw new MojoExecutionException(e.getMessage());
351                     }
352                 }
353             }
354         }
355         if (preservePatternFiles != null) {
356             for (File file : preservePatternFiles) {
357                 try {
358                     List<String> fileLines = Files.readAllLines(file.toPath(), Charset.forName(encoding));
359                     for (String line : fileLines) {
360                         if (!line.isEmpty()) {
361                             preservePatternList.add(Pattern.compile(line));
362                         }
363                     }
364                 } catch (IOException | PatternSyntaxException e) {
365                     throw new MojoExecutionException(e.getMessage());
366                 }
367             }
368         }
369         htmlCompressorHandler.setPreservePatterns(preservePatternList);
370         htmlCompressor.setHtmlCompressor(htmlCompressorHandler);
371 
372         try {
373             htmlCompressor.compress();
374         } catch (IOException e) {
375             throw new MojoExecutionException(e.getMessage());
376         }
377 
378         // The system of units (SI) as 1000 rather than 1024
379         boolean systemOfUnits = true;
380 
381         int origFilesizeBytes = -1;
382         try {
383             origFilesizeBytes = htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getFilesize();
384         } catch (NullPointerException e) {
385             getLog().info("No files found to compress, HTML compression completed.");
386             return;
387         }
388 
389         String origFilesize = FileTool.humanReadableByteCount(origFilesizeBytes, systemOfUnits);
390         String origEmptyChars = String
391                 .valueOf(htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getEmptyChars());
392         String origInlineEventSize = FileTool.humanReadableByteCount(
393                 htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getInlineEventSize(),
394                 systemOfUnits);
395         String origInlineScriptSize = FileTool.humanReadableByteCount(
396                 htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getInlineScriptSize(),
397                 systemOfUnits);
398         String origInlineStyleSize = FileTool.humanReadableByteCount(
399                 htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getInlineStyleSize(),
400                 systemOfUnits);
401 
402         int compFilesizeBytes = htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getFilesize();
403         String compFilesize = FileTool.humanReadableByteCount(compFilesizeBytes, systemOfUnits);
404         String compEmptyChars = String
405                 .valueOf(htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getEmptyChars());
406         String compInlineEventSize = FileTool.humanReadableByteCount(
407                 htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getInlineEventSize(),
408                 systemOfUnits);
409         String compInlineScriptSize = FileTool.humanReadableByteCount(
410                 htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getInlineScriptSize(),
411                 systemOfUnits);
412         String compInlineStyleSize = FileTool.humanReadableByteCount(
413                 htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getInlineStyleSize(),
414                 systemOfUnits);
415 
416         String elapsedTime = FileTool.getElapsedHMSTime(htmlCompressor.getHtmlCompressor().getStatistics().getTime());
417         String preservedSize = FileTool.humanReadableByteCount(
418                 htmlCompressor.getHtmlCompressor().getStatistics().getPreservedSize(), systemOfUnits);
419         float compressionRatio = Float.valueOf(compFilesizeBytes) / Float.valueOf(origFilesizeBytes);
420         float spaceSavings = Float.valueOf(1) - compressionRatio;
421 
422         String format = "%-30s%-30s%-30s%-2s";
423         NumberFormat formatter = new DecimalFormat("#0.00");
424         String eol = "\n";
425         String hr = "+-----------------------------+-----------------------------+-----------------------------+";
426         StringBuilder sb = new StringBuilder("HTML compression statistics:").append(eol);
427         sb.append(hr).append(eol);
428         sb.append(String.format(format, "| Category", "| Original", "| Compressed", "|")).append(eol);
429         sb.append(hr).append(eol);
430         sb.append(String.format(format, "| Filesize", "| " + origFilesize, "| " + compFilesize, "|")).append(eol);
431         sb.append(String.format(format, "| Empty Chars", "| " + origEmptyChars, "| " + compEmptyChars, "|"))
432                 .append(eol);
433         sb.append(String.format(format, "| Script Size", "| " + origInlineScriptSize, "| " + compInlineScriptSize, "|"))
434                 .append(eol);
435         sb.append(String.format(format, "| Style Size", "| " + origInlineStyleSize, "| " + compInlineStyleSize, "|"))
436                 .append(eol);
437         sb.append(String.format(format, "| Event Handler Size", "| " + origInlineEventSize, "| " + compInlineEventSize,
438                 "|")).append(eol);
439         sb.append(hr).append(eol);
440         sb.append(String.format("%-90s%-2s",
441                 String.format("| Time: %s, Preserved: %s, Compression Ratio: %s, Savings: %s%%", elapsedTime,
442                         preservedSize, formatter.format(compressionRatio), formatter.format(spaceSavings * 100)),
443                 "|")).append(eol);
444         sb.append(hr).append(eol);
445 
446         String statistics = sb.toString();
447         getLog().info(statistics);
448         try {
449             Files.createDirectories(Path.of(htmlCompressionStatistics).getParent());
450             Files.writeString(Path.of(htmlCompressionStatistics), statistics, Charset.forName(encoding));
451         } catch (IOException e) {
452             throw new MojoExecutionException(e.getMessage());
453         }
454 
455         getLog().info("HTML compression completed.");
456     }
457 
458     /**
459      * Gets the html compression statistics.
460      *
461      * @return the html compression statistics
462      */
463     public String getHtmlCompressionStatistics() {
464         return htmlCompressionStatistics;
465     }
466 
467     /**
468      * Sets the html compression statistics.
469      *
470      * @param htmlCompressionStatistics
471      *            the new html compression statistics
472      */
473     public void setHtmlCompressionStatistics(String htmlCompressionStatistics) {
474         this.htmlCompressionStatistics = htmlCompressionStatistics;
475     }
476 
477     /**
478      * Gets the file ext.
479      *
480      * @return the file ext
481      *
482      * @deprecated use getFileExtensions
483      */
484     @Deprecated
485     public String[] getFileExt() {
486         return fileExt;
487     }
488 
489     /**
490      * Sets the file ext.
491      *
492      * @param fileExt
493      *            the new file ext
494      *
495      * @deprecated use setFileExtensions
496      */
497     @Deprecated
498     public void setFileExt(String[] fileExt) {
499         this.fileExt = fileExt;
500     }
501 
502     /**
503      * Gets the file ext.
504      *
505      * @return the file extensions
506      */
507     public String[] getFileExtensions() {
508         return fileExtensions;
509     }
510 
511     /**
512      * Sets the file ext.
513      *
514      * @param fileExtensions
515      *            the new file ext
516      */
517     public void setFileExtensions(String[] fileExtensions) {
518         this.fileExtensions = fileExtensions;
519     }
520 
521     /**
522      * Gets the enabled.
523      *
524      * @return the enabled
525      */
526     public Boolean getEnabled() {
527         return enabled;
528     }
529 
530     /**
531      * Sets the enabled.
532      *
533      * @param enabled
534      *            the new enabled
535      */
536     public void setEnabled(Boolean enabled) {
537         this.enabled = enabled;
538     }
539 
540     /**
541      * Gets the removes the comments.
542      *
543      * @return the removes the comments
544      */
545     public Boolean getRemoveComments() {
546         return removeComments;
547     }
548 
549     /**
550      * Sets the removes the comments.
551      *
552      * @param removeComments
553      *            the new removes the comments
554      */
555     public void setRemoveComments(Boolean removeComments) {
556         this.removeComments = removeComments;
557     }
558 
559     /**
560      * Gets the removes the multi spaces.
561      *
562      * @return the removes the multi spaces
563      */
564     public Boolean getRemoveMultiSpaces() {
565         return removeMultiSpaces;
566     }
567 
568     /**
569      * Sets the removes the multi spaces.
570      *
571      * @param removeMultiSpaces
572      *            the new removes the multi spaces
573      */
574     public void setRemoveMultiSpaces(Boolean removeMultiSpaces) {
575         this.removeMultiSpaces = removeMultiSpaces;
576     }
577 
578     /**
579      * Gets the removes the intertag spaces.
580      *
581      * @return the removes the intertag spaces
582      */
583     public Boolean getRemoveIntertagSpaces() {
584         return removeIntertagSpaces;
585     }
586 
587     /**
588      * Sets the removes the intertag spaces.
589      *
590      * @param removeIntertagSpaces
591      *            the new removes the intertag spaces
592      */
593     public void setRemoveIntertagSpaces(Boolean removeIntertagSpaces) {
594         this.removeIntertagSpaces = removeIntertagSpaces;
595     }
596 
597     /**
598      * Gets the removes the quotes.
599      *
600      * @return the removes the quotes
601      */
602     public Boolean getRemoveQuotes() {
603         return removeQuotes;
604     }
605 
606     /**
607      * Sets the removes the quotes.
608      *
609      * @param removeQuotes
610      *            the new removes the quotes
611      */
612     public void setRemoveQuotes(Boolean removeQuotes) {
613         this.removeQuotes = removeQuotes;
614     }
615 
616     /**
617      * Gets the simple doctype.
618      *
619      * @return the simple doctype
620      */
621     public Boolean getSimpleDoctype() {
622         return simpleDoctype;
623     }
624 
625     /**
626      * Sets the simple doctype.
627      *
628      * @param simpleDoctype
629      *            the new simple doctype
630      */
631     public void setSimpleDoctype(Boolean simpleDoctype) {
632         this.simpleDoctype = simpleDoctype;
633     }
634 
635     /**
636      * Gets the removes the script attributes.
637      *
638      * @return the removes the script attributes
639      */
640     public Boolean getRemoveScriptAttributes() {
641         return removeScriptAttributes;
642     }
643 
644     /**
645      * Sets the removes the script attributes.
646      *
647      * @param removeScriptAttributes
648      *            the new removes the script attributes
649      */
650     public void setRemoveScriptAttributes(Boolean removeScriptAttributes) {
651         this.removeScriptAttributes = removeScriptAttributes;
652     }
653 
654     /**
655      * Gets the removes the style attributes.
656      *
657      * @return the removes the style attributes
658      */
659     public Boolean getRemoveStyleAttributes() {
660         return removeStyleAttributes;
661     }
662 
663     /**
664      * Sets the removes the style attributes.
665      *
666      * @param removeStyleAttributes
667      *            the new removes the style attributes
668      */
669     public void setRemoveStyleAttributes(Boolean removeStyleAttributes) {
670         this.removeStyleAttributes = removeStyleAttributes;
671     }
672 
673     /**
674      * Gets the removes the link attributes.
675      *
676      * @return the removes the link attributes
677      */
678     public Boolean getRemoveLinkAttributes() {
679         return removeLinkAttributes;
680     }
681 
682     /**
683      * Sets the removes the link attributes.
684      *
685      * @param removeLinkAttributes
686      *            the new removes the link attributes
687      */
688     public void setRemoveLinkAttributes(Boolean removeLinkAttributes) {
689         this.removeLinkAttributes = removeLinkAttributes;
690     }
691 
692     /**
693      * Gets the removes the form attributes.
694      *
695      * @return the removes the form attributes
696      */
697     public Boolean getRemoveFormAttributes() {
698         return removeFormAttributes;
699     }
700 
701     /**
702      * Sets the removes the form attributes.
703      *
704      * @param removeFormAttributes
705      *            the new removes the form attributes
706      */
707     public void setRemoveFormAttributes(Boolean removeFormAttributes) {
708         this.removeFormAttributes = removeFormAttributes;
709     }
710 
711     /**
712      * Gets the removes the input attributes.
713      *
714      * @return the removes the input attributes
715      */
716     public Boolean getRemoveInputAttributes() {
717         return removeInputAttributes;
718     }
719 
720     /**
721      * Sets the removes the input attributes.
722      *
723      * @param removeInputAttributes
724      *            the new removes the input attributes
725      */
726     public void setRemoveInputAttributes(Boolean removeInputAttributes) {
727         this.removeInputAttributes = removeInputAttributes;
728     }
729 
730     /**
731      * Gets the simple boolean attributes.
732      *
733      * @return the simple boolean attributes
734      */
735     public Boolean getSimpleBooleanAttributes() {
736         return simpleBooleanAttributes;
737     }
738 
739     /**
740      * Sets the simple boolean attributes.
741      *
742      * @param simpleBooleanAttributes
743      *            the new simple boolean attributes
744      */
745     public void setSimpleBooleanAttributes(Boolean simpleBooleanAttributes) {
746         this.simpleBooleanAttributes = simpleBooleanAttributes;
747     }
748 
749     /**
750      * Gets the removes the java script protocol.
751      *
752      * @return the removes the java script protocol
753      */
754     public Boolean getRemoveJavaScriptProtocol() {
755         return removeJavaScriptProtocol;
756     }
757 
758     /**
759      * Sets the removes the java script protocol.
760      *
761      * @param removeJavaScriptProtocol
762      *            the new removes the java script protocol
763      */
764     public void setRemoveJavaScriptProtocol(Boolean removeJavaScriptProtocol) {
765         this.removeJavaScriptProtocol = removeJavaScriptProtocol;
766     }
767 
768     /**
769      * Gets the removes the http protocol.
770      *
771      * @return the removes the http protocol
772      */
773     public Boolean getRemoveHttpProtocol() {
774         return removeHttpProtocol;
775     }
776 
777     /**
778      * Sets the removes the http protocol.
779      *
780      * @param removeHttpProtocol
781      *            the new removes the http protocol
782      */
783     public void setRemoveHttpProtocol(Boolean removeHttpProtocol) {
784         this.removeHttpProtocol = removeHttpProtocol;
785     }
786 
787     /**
788      * Gets the removes the https protocol.
789      *
790      * @return the removes the https protocol
791      */
792     public Boolean getRemoveHttpsProtocol() {
793         return removeHttpsProtocol;
794     }
795 
796     /**
797      * Sets the removes the https protocol.
798      *
799      * @param removeHttpsProtocol
800      *            the new removes the https protocol
801      */
802     public void setRemoveHttpsProtocol(Boolean removeHttpsProtocol) {
803         this.removeHttpsProtocol = removeHttpsProtocol;
804     }
805 
806     /**
807      * Gets the compress css.
808      *
809      * @return the compress css
810      */
811     public Boolean getCompressCss() {
812         return compressCss;
813     }
814 
815     /**
816      * Sets the compress css.
817      *
818      * @param compressCss
819      *            the new compress css
820      */
821     public void setCompressCss(Boolean compressCss) {
822         this.compressCss = compressCss;
823     }
824 
825     /**
826      * Gets the preserve line breaks.
827      *
828      * @return the preserve line breaks
829      */
830     public Boolean getPreserveLineBreaks() {
831         return preserveLineBreaks;
832     }
833 
834     /**
835      * Sets the preserve line breaks.
836      *
837      * @param preserveLineBreaks
838      *            the new preserve line breaks
839      */
840     public void setPreserveLineBreaks(Boolean preserveLineBreaks) {
841         this.preserveLineBreaks = preserveLineBreaks;
842     }
843 
844     /**
845      * Gets the yui css line break.
846      *
847      * @return the yui css line break
848      */
849     public Integer getYuiCssLineBreak() {
850         return yuiCssLineBreak;
851     }
852 
853     /**
854      * Sets the yui css line break.
855      *
856      * @param yuiCssLineBreak
857      *            the new yui css line break
858      */
859     public void setYuiCssLineBreak(Integer yuiCssLineBreak) {
860         this.yuiCssLineBreak = yuiCssLineBreak;
861     }
862 
863     /**
864      * Gets the compress java script.
865      *
866      * @return the compress java script
867      */
868     public Boolean getCompressJavaScript() {
869         return compressJavaScript;
870     }
871 
872     /**
873      * Sets the compress java script.
874      *
875      * @param compressJavaScript
876      *            the new compress java script
877      */
878     public void setCompressJavaScript(Boolean compressJavaScript) {
879         this.compressJavaScript = compressJavaScript;
880     }
881 
882     /**
883      * Gets the js compressor.
884      *
885      * @return the js compressor
886      */
887     public String getJsCompressor() {
888         return jsCompressor;
889     }
890 
891     /**
892      * Sets the js compressor.
893      *
894      * @param jsCompressor
895      *            the new js compressor
896      */
897     public void setJsCompressor(String jsCompressor) {
898         this.jsCompressor = jsCompressor;
899     }
900 
901     /**
902      * Gets the yui js no munge.
903      *
904      * @return the yui js no munge
905      */
906     public Boolean getYuiJsNoMunge() {
907         return yuiJsNoMunge;
908     }
909 
910     /**
911      * Sets the yui js no munge.
912      *
913      * @param yuiJsNoMunge
914      *            the new yui js no munge
915      */
916     public void setYuiJsNoMunge(Boolean yuiJsNoMunge) {
917         this.yuiJsNoMunge = yuiJsNoMunge;
918     }
919 
920     /**
921      * Gets the yui js preserve all semi colons.
922      *
923      * @return the yui js preserve all semi colons
924      */
925     public Boolean getYuiJsPreserveAllSemiColons() {
926         return yuiJsPreserveAllSemiColons;
927     }
928 
929     /**
930      * Sets the yui js preserve all semi colons.
931      *
932      * @param yuiJsPreserveAllSemiColons
933      *            the new yui js preserve all semi colons
934      */
935     public void setYuiJsPreserveAllSemiColons(Boolean yuiJsPreserveAllSemiColons) {
936         this.yuiJsPreserveAllSemiColons = yuiJsPreserveAllSemiColons;
937     }
938 
939     /**
940      * Gets the yui js line break.
941      *
942      * @return the yui js line break
943      */
944     public Integer getYuiJsLineBreak() {
945         return yuiJsLineBreak;
946     }
947 
948     /**
949      * Sets the yui js line break.
950      *
951      * @param yuiJsLineBreak
952      *            the new yui js line break
953      */
954     public void setYuiJsLineBreak(Integer yuiJsLineBreak) {
955         this.yuiJsLineBreak = yuiJsLineBreak;
956     }
957 
958     /**
959      * Gets the closure opt level.
960      *
961      * @return the closure opt level
962      */
963     public String getClosureOptLevel() {
964         return closureOptLevel;
965     }
966 
967     /**
968      * Sets the closure opt level.
969      *
970      * @param closureOptLevel
971      *            the new closure opt level
972      */
973     public void setClosureOptLevel(String closureOptLevel) {
974         this.closureOptLevel = closureOptLevel;
975     }
976 
977     /**
978      * Gets the yui js disable optimizations.
979      *
980      * @return the yui js disable optimizations
981      */
982     public Boolean getYuiJsDisableOptimizations() {
983         return yuiJsDisableOptimizations;
984     }
985 
986     /**
987      * Sets the yui js disable optimizations.
988      *
989      * @param yuiJsDisableOptimizations
990      *            the new yui js disable optimizations
991      */
992     public void setYuiJsDisableOptimizations(Boolean yuiJsDisableOptimizations) {
993         this.yuiJsDisableOptimizations = yuiJsDisableOptimizations;
994     }
995 
996     /**
997      * Gets the predefined preserve patterns.
998      *
999      * @return the predefined preserve patterns
1000      */
1001     public String[] getPredefinedPreservePatterns() {
1002         return predefinedPreservePatterns;
1003     }
1004 
1005     /**
1006      * Sets the predefined preserve patterns.
1007      *
1008      * @param predefinedPreservePatterns
1009      *            the new predefined preserve patterns
1010      */
1011     public void setPredefinedPreservePatterns(String[] predefinedPreservePatterns) {
1012         this.predefinedPreservePatterns = predefinedPreservePatterns;
1013     }
1014 
1015     /**
1016      * Gets the preserve patterns.
1017      *
1018      * @return the preserve patterns
1019      */
1020     public String[] getPreservePatterns() {
1021         return preservePatterns;
1022     }
1023 
1024     /**
1025      * Sets the preserve patterns.
1026      *
1027      * @param preservePatterns
1028      *            the new preserve patterns
1029      */
1030     public void setPreservePatterns(String[] preservePatterns) {
1031         this.preservePatterns = preservePatterns;
1032     }
1033 
1034     /**
1035      * Gets the preserve pattern files.
1036      *
1037      * @return the preserve pattern files
1038      */
1039     public File[] getPreservePatternFiles() {
1040         return preservePatternFiles;
1041     }
1042 
1043     /**
1044      * Sets the preserve pattern files.
1045      *
1046      * @param preservePatternFiles
1047      *            the new preserve pattern files
1048      */
1049     public void setPreservePatternFiles(File[] preservePatternFiles) {
1050         this.preservePatternFiles = preservePatternFiles;
1051     }
1052 
1053     /**
1054      * Gets the generate statistics.
1055      *
1056      * @return the generate statistics
1057      */
1058     public Boolean getGenerateStatistics() {
1059         return generateStatistics;
1060     }
1061 
1062     /**
1063      * Sets the generate statistics.
1064      *
1065      * @param generateStatistics
1066      *            the new generate statistics
1067      */
1068     public void setGenerateStatistics(Boolean generateStatistics) {
1069         this.generateStatistics = generateStatistics;
1070     }
1071 
1072     /**
1073      * Gets the src folder.
1074      *
1075      * @return the src folder
1076      */
1077     public String getSrcFolder() {
1078         return srcFolder;
1079     }
1080 
1081     /**
1082      * Sets the src folder.
1083      *
1084      * @param srcFolder
1085      *            the new src folder
1086      */
1087     public void setSrcFolder(String srcFolder) {
1088         this.srcFolder = srcFolder;
1089     }
1090 
1091     /**
1092      * Gets the target folder.
1093      *
1094      * @return the target folder
1095      */
1096     public String getTargetFolder() {
1097         return targetFolder;
1098     }
1099 
1100     /**
1101      * Sets the target folder.
1102      *
1103      * @param targetFolder
1104      *            the new target folder
1105      */
1106     public void setTargetFolder(String targetFolder) {
1107         this.targetFolder = targetFolder;
1108     }
1109 
1110     /**
1111      * Gets the javascript html sprite.
1112      *
1113      * @return the javascript html sprite
1114      */
1115     public Boolean getJavascriptHtmlSprite() {
1116         return javascriptHtmlSprite;
1117     }
1118 
1119     /**
1120      * Sets the javascript html sprite.
1121      *
1122      * @param javascriptHtmlSprite
1123      *            the new javascript html sprite
1124      */
1125     public void setJavascriptHtmlSprite(Boolean javascriptHtmlSprite) {
1126         this.javascriptHtmlSprite = javascriptHtmlSprite;
1127     }
1128 
1129     /**
1130      * Gets the javascript html sprite integration file.
1131      *
1132      * @return the javascript html sprite integration file
1133      */
1134     public String getJavascriptHtmlSpriteIntegrationFile() {
1135         return javascriptHtmlSpriteIntegrationFile;
1136     }
1137 
1138     /**
1139      * Sets the javascript html sprite integration file.
1140      *
1141      * @param javascriptHtmlSpriteIntegrationFile
1142      *            the new javascript html sprite integration file
1143      */
1144     public void setJavascriptHtmlSpriteIntegrationFile(String javascriptHtmlSpriteIntegrationFile) {
1145         this.javascriptHtmlSpriteIntegrationFile = javascriptHtmlSpriteIntegrationFile;
1146     }
1147 
1148     /**
1149      * Gets the javascript html sprite target file.
1150      *
1151      * @return the javascript html sprite target file
1152      */
1153     public String getJavascriptHtmlSpriteTargetFile() {
1154         return javascriptHtmlSpriteTargetFile;
1155     }
1156 
1157     /**
1158      * Sets the javascript html sprite target file.
1159      *
1160      * @param javascriptHtmlSpriteTargetFile
1161      *            the new javascript html sprite target file
1162      */
1163     public void setJavascriptHtmlSpriteTargetFile(String javascriptHtmlSpriteTargetFile) {
1164         this.javascriptHtmlSpriteTargetFile = javascriptHtmlSpriteTargetFile;
1165     }
1166 
1167     /**
1168      * Gets the encoding.
1169      *
1170      * @return the encoding
1171      */
1172     public String getEncoding() {
1173         return encoding;
1174     }
1175 
1176     /**
1177      * Sets the encoding.
1178      *
1179      * @param encoding
1180      *            the new encoding
1181      */
1182     public void setEncoding(String encoding) {
1183         this.encoding = encoding;
1184     }
1185 
1186     /**
1187      * Gets the closure custom externs only.
1188      *
1189      * @return the closure custom externs only
1190      */
1191     public Boolean getClosureCustomExternsOnly() {
1192         return closureCustomExternsOnly;
1193     }
1194 
1195     /**
1196      * Sets the closure custom externs only.
1197      *
1198      * @param closureCustomExternsOnly
1199      *            the new closure custom externs only
1200      */
1201     public void setClosureCustomExternsOnly(Boolean closureCustomExternsOnly) {
1202         this.closureCustomExternsOnly = closureCustomExternsOnly;
1203     }
1204 
1205     /**
1206      * Gets the closure externs.
1207      *
1208      * @return the closure externs
1209      */
1210     public String[] getClosureExterns() {
1211         return closureExterns;
1212     }
1213 
1214     /**
1215      * Sets the closure externs.
1216      *
1217      * @param closureExterns
1218      *            the new closure externs
1219      */
1220     public void setClosureExterns(String[] closureExterns) {
1221         this.closureExterns = closureExterns;
1222     }
1223 }