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