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