• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / htmlcompressor-maven-plugin / 86

20 Apr 2025 08:12PM UTC coverage: 36.479% (+0.2%) from 36.249%
86

push

github

hazendaz
[maven-release-plugin] prepare release htmlcompressor-maven-plugin-1.10.2

44 of 218 branches covered (20.18%)

Branch coverage included in aggregate %.

273 of 651 relevant lines covered (41.94%)

0.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

39.24
/src/main/java/com/tunyk/mvn/plugins/htmlcompressor/HtmlCompressorMojo.java
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 {
1✔
46

47
    /** file where statistics of html compression is stored. */
48
    @Parameter(property = "htmlcompressor.htmlCompressionStatistics", defaultValue = "${project.build.directory}/htmlcompressor/html-compression-statistics.txt")
1✔
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")
1✔
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")
1✔
76
    private boolean removeComments = true;
77

78
    /** if false keeps multiple whitespace characters (default is true). */
79
    @Parameter(property = "htmlcompressor.removeMultiSpaces", defaultValue = "true")
1✔
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")
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")
1✔
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")
1✔
172
    private int yuiJsLineBreak = -1;
173

174
    /** closureOptLevel = "simple", "advanced" or "whitespace". */
175
    @Parameter(property = "htmlcompressor.closureOptLevel", defaultValue = "simple")
1✔
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")
1✔
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")
1✔
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")
1✔
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")
1✔
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")
1✔
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")
1✔
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")
1✔
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) {
1!
252
            getLog().info("HtmlCompressor is skipped");
×
253
            return;
×
254
        }
255

256
        if (!enabled) {
1!
257
            getLog().info("HTML compression was turned off.");
×
258
            return;
×
259
        }
260

261
        if (!Files.exists(Path.of(srcFolder))) {
1!
262
            getLog().warn("Compressor folder does not exist, skipping compression of " + srcFolder);
×
263
            return;
×
264
        }
265

266
        getLog().info("Compressing " + srcFolder);
1✔
267
        HtmlCompressor htmlCompressor = new HtmlCompressor(srcFolder, targetFolder);
1✔
268

269
        // Deprecated
270
        if (fileExt != null && fileExtensions == null) {
1!
271
            fileExtensions = fileExt;
×
272
        }
273

274
        htmlCompressor.setFileExtensions(fileExtensions);
1✔
275
        htmlCompressor.setFileEncoding(Charset.forName(encoding));
1✔
276
        htmlCompressor.setCreateJsonFile(javascriptHtmlSprite);
1✔
277
        htmlCompressor.setJsonIntegrationFilePath(javascriptHtmlSpriteIntegrationFile);
1✔
278
        htmlCompressor.setTargetJsonFilePath(javascriptHtmlSpriteTargetFile);
1✔
279

280
        com.googlecode.htmlcompressor.compressor.HtmlCompressor htmlCompressorHandler = new com.googlecode.htmlcompressor.compressor.HtmlCompressor();
1✔
281
        htmlCompressorHandler.setEnabled(enabled);
1✔
282
        htmlCompressorHandler.setRemoveComments(removeComments);
1✔
283
        htmlCompressorHandler.setRemoveMultiSpaces(removeMultiSpaces);
1✔
284
        htmlCompressorHandler.setRemoveIntertagSpaces(removeIntertagSpaces);
1✔
285
        htmlCompressorHandler.setRemoveQuotes(removeQuotes);
1✔
286
        htmlCompressorHandler.setSimpleDoctype(simpleDoctype);
1✔
287
        htmlCompressorHandler.setRemoveScriptAttributes(removeScriptAttributes);
1✔
288
        htmlCompressorHandler.setRemoveStyleAttributes(removeStyleAttributes);
1✔
289
        htmlCompressorHandler.setRemoveLinkAttributes(removeLinkAttributes);
1✔
290
        htmlCompressorHandler.setRemoveFormAttributes(removeFormAttributes);
1✔
291
        htmlCompressorHandler.setRemoveInputAttributes(removeInputAttributes);
1✔
292
        htmlCompressorHandler.setSimpleBooleanAttributes(simpleBooleanAttributes);
1✔
293
        htmlCompressorHandler.setRemoveJavaScriptProtocol(removeJavaScriptProtocol);
1✔
294
        htmlCompressorHandler.setRemoveHttpProtocol(removeHttpProtocol);
1✔
295
        htmlCompressorHandler.setRemoveHttpsProtocol(removeHttpsProtocol);
1✔
296
        htmlCompressorHandler.setCompressCss(compressCss);
1✔
297
        htmlCompressorHandler.setPreserveLineBreaks(preserveLineBreaks);
1✔
298
        htmlCompressorHandler.setYuiCssLineBreak(yuiCssLineBreak);
1✔
299
        htmlCompressorHandler.setCompressJavaScript(compressJavaScript);
1✔
300
        htmlCompressorHandler.setYuiJsNoMunge(yuiJsNoMunge);
1✔
301
        htmlCompressorHandler.setYuiJsPreserveAllSemiColons(yuiJsPreserveAllSemiColons);
1✔
302
        htmlCompressorHandler.setYuiJsLineBreak(yuiJsLineBreak);
1✔
303
        htmlCompressorHandler.setYuiJsDisableOptimizations(yuiJsDisableOptimizations);
1✔
304
        htmlCompressorHandler.setGenerateStatistics(generateStatistics);
1✔
305

306
        if (jsCompressor.equalsIgnoreCase("closure")) {
1!
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<>();
1✔
330
        boolean phpTagPatternAdded = false;
1✔
331
        boolean serverScriptTagPatternAdded = false;
1✔
332
        if (predefinedPreservePatterns != null) {
1!
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) {
1!
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) {
1!
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);
1✔
370
        htmlCompressor.setHtmlCompressor(htmlCompressorHandler);
1✔
371

372
        try {
373
            htmlCompressor.compress();
1✔
374
        } catch (IOException e) {
×
375
            throw new MojoExecutionException(e.getMessage());
×
376
        }
1✔
377

378
        // The system of units (SI) as 1000 rather than 1024
379
        boolean systemOfUnits = true;
1✔
380

381
        int origFilesizeBytes = -1;
1✔
382
        try {
383
            origFilesizeBytes = htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getFilesize();
1✔
384
        } catch (NullPointerException e) {
×
385
            getLog().info("No files found to compress, HTML compression completed.");
×
386
            return;
×
387
        }
1✔
388

389
        String origFilesize = FileTool.humanReadableByteCount(origFilesizeBytes, systemOfUnits);
1✔
390
        String origEmptyChars = String
1✔
391
                .valueOf(htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getEmptyChars());
1✔
392
        String origInlineEventSize = FileTool.humanReadableByteCount(
1✔
393
                htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getInlineEventSize(),
1✔
394
                systemOfUnits);
395
        String origInlineScriptSize = FileTool.humanReadableByteCount(
1✔
396
                htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getInlineScriptSize(),
1✔
397
                systemOfUnits);
398
        String origInlineStyleSize = FileTool.humanReadableByteCount(
1✔
399
                htmlCompressor.getHtmlCompressor().getStatistics().getOriginalMetrics().getInlineStyleSize(),
1✔
400
                systemOfUnits);
401

402
        int compFilesizeBytes = htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getFilesize();
1✔
403
        String compFilesize = FileTool.humanReadableByteCount(compFilesizeBytes, systemOfUnits);
1✔
404
        String compEmptyChars = String
1✔
405
                .valueOf(htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getEmptyChars());
1✔
406
        String compInlineEventSize = FileTool.humanReadableByteCount(
1✔
407
                htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getInlineEventSize(),
1✔
408
                systemOfUnits);
409
        String compInlineScriptSize = FileTool.humanReadableByteCount(
1✔
410
                htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getInlineScriptSize(),
1✔
411
                systemOfUnits);
412
        String compInlineStyleSize = FileTool.humanReadableByteCount(
1✔
413
                htmlCompressor.getHtmlCompressor().getStatistics().getCompressedMetrics().getInlineStyleSize(),
1✔
414
                systemOfUnits);
415

416
        String elapsedTime = FileTool.getElapsedHMSTime(htmlCompressor.getHtmlCompressor().getStatistics().getTime());
1✔
417
        String preservedSize = FileTool.humanReadableByteCount(
1✔
418
                htmlCompressor.getHtmlCompressor().getStatistics().getPreservedSize(), systemOfUnits);
1✔
419
        float compressionRatio = Float.valueOf(compFilesizeBytes) / Float.valueOf(origFilesizeBytes);
1✔
420
        float spaceSavings = Float.valueOf(1) - compressionRatio;
1✔
421

422
        String format = "%-30s%-30s%-30s%-2s";
1✔
423
        NumberFormat formatter = new DecimalFormat("#0.00");
1✔
424
        String eol = "\n";
1✔
425
        String hr = "+-----------------------------+-----------------------------+-----------------------------+";
1✔
426
        StringBuilder sb = new StringBuilder("HTML compression statistics:").append(eol);
1✔
427
        sb.append(hr).append(eol);
1✔
428
        sb.append(String.format(format, "| Category", "| Original", "| Compressed", "|")).append(eol);
1✔
429
        sb.append(hr).append(eol);
1✔
430
        sb.append(String.format(format, "| Filesize", "| " + origFilesize, "| " + compFilesize, "|")).append(eol);
1✔
431
        sb.append(String.format(format, "| Empty Chars", "| " + origEmptyChars, "| " + compEmptyChars, "|"))
1✔
432
                .append(eol);
1✔
433
        sb.append(String.format(format, "| Script Size", "| " + origInlineScriptSize, "| " + compInlineScriptSize, "|"))
1✔
434
                .append(eol);
1✔
435
        sb.append(String.format(format, "| Style Size", "| " + origInlineStyleSize, "| " + compInlineStyleSize, "|"))
1✔
436
                .append(eol);
1✔
437
        sb.append(String.format(format, "| Event Handler Size", "| " + origInlineEventSize, "| " + compInlineEventSize,
1✔
438
                "|")).append(eol);
1✔
439
        sb.append(hr).append(eol);
1✔
440
        sb.append(String.format("%-90s%-2s",
1✔
441
                String.format("| Time: %s, Preserved: %s, Compression Ratio: %s, Savings: %s%%", elapsedTime,
1✔
442
                        preservedSize, formatter.format(compressionRatio), formatter.format(spaceSavings * 100)),
1✔
443
                "|")).append(eol);
1✔
444
        sb.append(hr).append(eol);
1✔
445

446
        String statistics = sb.toString();
1✔
447
        getLog().info(statistics);
1✔
448
        try {
449
            Files.createDirectories(Path.of(htmlCompressionStatistics).getParent());
1✔
450
            Files.writeString(Path.of(htmlCompressionStatistics), statistics, Charset.forName(encoding));
1✔
451
        } catch (IOException e) {
×
452
            throw new MojoExecutionException(e.getMessage());
×
453
        }
1✔
454

455
        getLog().info("HTML compression completed.");
1✔
456
    }
1✔
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;
1✔
1089
    }
1✔
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;
1✔
1108
    }
1✔
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;
1✔
1146
    }
1✔
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
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc