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

hazendaz / htmlcompressor-maven-plugin / 75

20 Apr 2025 06:38PM UTC coverage: 36.479% (+0.2%) from 36.249%
75

push

github

hazendaz
Change %s injector to be quoted "%s" instead

the underlying code with %s is invalid javascript.  By doing it this way, its now compliant.  The result is the same.  This is a breaking change for those using this.

44 of 218 branches covered (20.18%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

133 existing lines in 5 files now uncovered.

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

80.0
/src/main/java/com/tunyk/mvn/plugins/htmlcompressor/FileTool.java
1
/*
2
 * Copyright (c) 2011-2025 Alex Tunyk <alex at tunyk.com>.
3
 * Copyright (c) 2011-2025 Hazendaz <github.com/hazendaz>.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *   https://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 * See the NOTICE file distributed with this work for additional information
18
 * regarding copyright ownership.
19
 */
20
package com.tunyk.mvn.plugins.htmlcompressor;
21

22
import java.io.IOException;
23
import java.nio.charset.Charset;
24
import java.nio.file.Files;
25
import java.nio.file.Path;
26
import java.util.Arrays;
27
import java.util.List;
28
import java.util.Map;
29
import java.util.Map.Entry;
30
import java.util.concurrent.ConcurrentHashMap;
31
import java.util.concurrent.ConcurrentMap;
32
import java.util.regex.Matcher;
33
import java.util.stream.Collectors;
34
import java.util.stream.Stream;
35

36
import org.json.JSONException;
37
import org.json.JSONObject;
38

39
/**
40
 * The Class FileTool.
41
 */
42
public class FileTool {
43

44
    /** The root dir path. */
45
    private String rootDirPath;
46

47
    /** The file extensions. */
48
    private String[] fileExtensions;
49

50
    /** The recursive. */
51
    private boolean recursive;
52

53
    /** The file encoding. */
54
    private Charset fileEncoding;
55

56
    /**
57
     * Instantiates a new file tool.
58
     *
59
     * @param rootDir
60
     *            the root dir
61
     * @param fileExtensions
62
     *            the file ext
63
     * @param recursive
64
     *            the recursive
65
     *
66
     * @throws IOException
67
     *             Signals that an I/O exception has occurred.
68
     */
69
    public FileTool(String rootDir, String[] fileExtensions, boolean recursive) throws IOException {
1✔
70
        this.setRootDirPath(rootDir);
1✔
71
        this.fileExtensions = fileExtensions;
1✔
72
        this.recursive = recursive;
1✔
73
    }
1✔
74

75
    /**
76
     * Gets the files.
77
     *
78
     * @return the files
79
     *
80
     * @throws IOException
81
     *             Signals that an I/O exception has occurred.
82
     */
83
    public ConcurrentMap<String, String> getFiles() throws IOException {
84
        ConcurrentMap<String, String> map = new ConcurrentHashMap<>();
1✔
85
        Path rootDir = Path.of(rootDirPath);
1✔
86
        List<Path> paths;
87
        try (Stream<Path> walk = Files.walk(rootDir)) {
1✔
88
            paths = walk.map(Path::normalize).filter(Files::isRegularFile)
1✔
89
                    .filter(path -> Arrays.stream(fileExtensions).anyMatch(path.getFileName().toString()::endsWith))
1✔
90
                    .collect(Collectors.toList());
1✔
91
        }
92
        int truncationIndex = 0;
1✔
93
        for (Path path : paths) {
1✔
94
            String normalizedFilePath = path.toFile().getCanonicalPath().replace("\\", "/");
1✔
95
            if (truncationIndex == 0) {
1✔
96
                truncationIndex = normalizedFilePath.indexOf(rootDirPath) + rootDirPath.length() + 1;
1✔
97
            }
98
            String key = normalizedFilePath.substring(truncationIndex);
1✔
99
            String value = Files.readString(path, getFileEncoding());
1✔
100
            map.put(key, value);
1✔
101
        }
1✔
102
        return map;
1✔
103
    }
104

105
    /**
106
     * Write files.
107
     *
108
     * @param map
109
     *            the map
110
     * @param targetDir
111
     *            the target dir
112
     *
113
     * @throws IOException
114
     *             Signals that an I/O exception has occurred.
115
     */
116
    public void writeFiles(Map<String, String> map, String targetDir) throws IOException {
117
        for (Entry<String, String> entry : map.entrySet()) {
1✔
118
            Path path = Path.of(targetDir + '/' + entry.getKey());
1✔
119
            Files.createDirectories(path.getParent());
1✔
120
            Files.writeString(path, entry.getValue(), getFileEncoding());
1✔
121
        }
1✔
122
    }
1✔
123

124
    /**
125
     * Write to json file.
126
     *
127
     * @param map
128
     *            the map
129
     * @param targetFile
130
     *            the target file
131
     * @param integrationCode
132
     *            the integration code
133
     *
134
     * @throws IOException
135
     *             Signals that an I/O exception has occurred.
136
     * @throws JSONException
137
     *             the JSON exception
138
     */
139
    public void writeToJsonFile(Map<String, String> map, String targetFile, String integrationCode)
140
            throws IOException, JSONException {
141
        String replacePattern = "\"%s\"";
1✔
142
        Path path = Path.of(targetFile);
1✔
143
        JSONObject json = new JSONObject();
1✔
144
        for (Entry<String, String> entry : map.entrySet()) {
1✔
145
            json.put(entry.getKey(), entry.getValue());
1✔
146
        }
1✔
147
        if (integrationCode == null) {
1!
UNCOV
148
            integrationCode = replacePattern;
×
149
        }
150
        if (integrationCode.indexOf(replacePattern) == -1) {
1✔
151
            integrationCode += replacePattern;
1✔
152
        }
153
        String contents = integrationCode.replaceFirst(replacePattern, Matcher.quoteReplacement(json.toString()));
1✔
154
        Files.createDirectories(path.getParent());
1✔
155
        Files.writeString(path, contents, getFileEncoding());
1✔
156
    }
1✔
157

158
    /**
159
     * Human readable byte count.
160
     *
161
     * @param bytes
162
     *            the bytes
163
     * @param systemOfUnits
164
     *            the systemOfUnits
165
     *
166
     * @return the string
167
     */
168
    // TODO JWL 4/22/2023 Didn't see a good way to handle as it gets flagged to remove unnecessary cast if I fix this
169
    // per error-prone, so ignoring it
170
    @SuppressWarnings("LongDoubleConversion")
171
    public static String humanReadableByteCount(long bytes, boolean systemOfUnits) {
172
        int unit = systemOfUnits ? 1000 : 1024;
1!
173
        if (bytes < unit) {
1!
174
            return bytes + " B";
1✔
175
        }
176
        int exp = (int) (Math.log(bytes) / Math.log(unit));
×
177
        String pre = (systemOfUnits ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (systemOfUnits ? "" : "i");
×
UNCOV
178
        return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
×
179
    }
180

181
    /**
182
     * Gets the elapsed HMS time.
183
     *
184
     * @param elapsedTime
185
     *            the elapsed time
186
     *
187
     * @return the elapsed HMS time
188
     */
189
    public static String getElapsedHMSTime(long elapsedTime) {
190
        String format = String.format("%%0%dd", 2);
1✔
191
        elapsedTime = elapsedTime / 1000;
1✔
192
        String seconds = String.format(format, elapsedTime % 60);
1✔
193
        String minutes = String.format(format, (elapsedTime % 3600) / 60);
1✔
194
        String hours = String.format(format, elapsedTime / 3600);
1✔
195
        return hours + ":" + minutes + ":" + seconds;
1✔
196
    }
197

198
    /**
199
     * Gets the root dir path.
200
     *
201
     * @return the root dir path
202
     */
203
    public String getRootDirPath() {
UNCOV
204
        return rootDirPath;
×
205
    }
206

207
    /**
208
     * Sets the root dir path.
209
     *
210
     * @param rootDirPath
211
     *            the new root dir path
212
     *
213
     * @throws IOException
214
     *             Signals that an I/O exception has occurred.
215
     */
216
    public void setRootDirPath(String rootDirPath) throws IOException {
217
        Path path = Path.of(rootDirPath);
1✔
218
        this.rootDirPath = path.toFile().getCanonicalPath().replace("\\", "/").replaceAll("/$", "");
1✔
219
    }
1✔
220

221
    /**
222
     * Gets the file extensions.
223
     *
224
     * @return the file extensions
225
     */
226
    public String[] getFileExtensions() {
UNCOV
227
        return fileExtensions;
×
228
    }
229

230
    /**
231
     * Sets the file extensions.
232
     *
233
     * @param fileExtensions
234
     *            the new file extensions
235
     */
236
    public void setFileExtensions(String[] fileExtensions) {
237
        this.fileExtensions = fileExtensions;
×
UNCOV
238
    }
×
239

240
    /**
241
     * Checks if is recursive.
242
     *
243
     * @return true, if is recursive
244
     */
245
    public boolean isRecursive() {
UNCOV
246
        return recursive;
×
247
    }
248

249
    /**
250
     * Sets the recursive.
251
     *
252
     * @param recursive
253
     *            the new recursive
254
     */
255
    public void setRecursive(boolean recursive) {
256
        this.recursive = recursive;
×
UNCOV
257
    }
×
258

259
    /**
260
     * Gets the file encoding.
261
     *
262
     * @return the file encoding
263
     */
264
    public Charset getFileEncoding() {
265
        return fileEncoding == null ? Charset.defaultCharset() : fileEncoding;
1✔
266
    }
267

268
    /**
269
     * Sets the file encoding.
270
     *
271
     * @param fileEncoding
272
     *            the new file encoding
273
     */
274
    public void setFileEncoding(Charset fileEncoding) {
275
        this.fileEncoding = fileEncoding == null ? Charset.defaultCharset() : fileEncoding;
1✔
276
    }
1✔
277
}
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