20
20
import java .io .FileInputStream ;
21
21
import java .io .FileOutputStream ;
22
22
import java .io .IOException ;
23
+ import java .io .InputStream ;
23
24
import java .io .OutputStream ;
24
25
import java .io .PrintStream ;
25
26
import java .io .UncheckedIOException ;
26
27
import java .nio .file .Files ;
27
28
import java .nio .file .attribute .BasicFileAttributeView ;
28
29
import java .nio .file .attribute .FileTime ;
30
+ import java .util .Enumeration ;
29
31
import java .util .List ;
30
32
import java .util .Locale ;
31
33
import java .util .Map ;
32
34
import java .util .Set ;
33
35
import java .util .jar .JarEntry ;
36
+ import java .util .jar .JarFile ;
34
37
import java .util .jar .JarOutputStream ;
35
38
import java .util .jar .Manifest ;
36
39
import java .util .zip .ZipEntry ;
@@ -157,8 +160,8 @@ private void printError(PrintStream out, String message) {
157
160
private void extractLibraries (FileResolver fileResolver , JarStructure jarStructure , Map <Option , String > options )
158
161
throws IOException {
159
162
String librariesDirectory = getLibrariesDirectory (options );
160
- extractArchive (fileResolver , (zipEntry ) -> {
161
- Entry entry = jarStructure .resolve (zipEntry );
163
+ extractArchive (fileResolver , (jarEntry ) -> {
164
+ Entry entry = jarStructure .resolve (jarEntry );
162
165
if (isType (entry , Type .LIBRARY )) {
163
166
return librariesDirectory + entry .location ();
164
167
}
@@ -212,22 +215,22 @@ private JarStructure getJarStructure() {
212
215
}
213
216
214
217
private void extractArchive (FileResolver fileResolver ) throws IOException {
215
- extractArchive (fileResolver , ZipEntry ::getName );
218
+ extractArchive (fileResolver , JarEntry ::getName );
216
219
}
217
220
218
221
private void extractArchive (FileResolver fileResolver , EntryNameTransformer entryNameTransformer )
219
222
throws IOException {
220
- withZipEntries (this .context .getArchiveFile (), (stream , zipEntry ) -> {
221
- if (zipEntry .isDirectory ()) {
223
+ withJarEntries (this .context .getArchiveFile (), (stream , jarEntry ) -> {
224
+ if (jarEntry .isDirectory ()) {
222
225
return ;
223
226
}
224
- String name = entryNameTransformer .getName (zipEntry );
227
+ String name = entryNameTransformer .getName (jarEntry );
225
228
if (name == null ) {
226
229
return ;
227
230
}
228
- File file = fileResolver .resolve (zipEntry , name );
231
+ File file = fileResolver .resolve (jarEntry , name );
229
232
if (file != null ) {
230
- extractEntry (stream , zipEntry , file );
233
+ extractEntry (stream , jarEntry , file );
231
234
}
232
235
});
233
236
}
@@ -249,11 +252,11 @@ private void createApplication(JarStructure jarStructure, FileResolver fileResol
249
252
Manifest manifest = jarStructure .createLauncherManifest ((library ) -> librariesDirectory + library );
250
253
mkDirs (file .getParentFile ());
251
254
try (JarOutputStream output = new JarOutputStream (new FileOutputStream (file ), manifest )) {
252
- withZipEntries (this .context .getArchiveFile (), ((stream , zipEntry ) -> {
253
- Entry entry = jarStructure .resolve (zipEntry );
255
+ withJarEntries (this .context .getArchiveFile (), ((stream , jarEntry ) -> {
256
+ Entry entry = jarStructure .resolve (jarEntry );
254
257
if (isType (entry , Type .APPLICATION_CLASS_OR_RESOURCE ) && StringUtils .hasLength (entry .location ())) {
255
- JarEntry jarEntry = createJarEntry (entry .location (), zipEntry );
256
- output .putNextEntry (jarEntry );
258
+ JarEntry newJarEntry = createJarEntry (entry .location (), jarEntry );
259
+ output .putNextEntry (newJarEntry );
257
260
StreamUtils .copy (stream , output );
258
261
output .closeEntry ();
259
262
}
@@ -275,51 +278,74 @@ private static boolean isType(Entry entry, Type type) {
275
278
return entry .type () == type ;
276
279
}
277
280
278
- private static void extractEntry (ZipInputStream zip , ZipEntry entry , File file ) throws IOException {
281
+ private static void extractEntry (InputStream stream , JarEntry entry , File file ) throws IOException {
279
282
mkDirs (file .getParentFile ());
280
283
try (OutputStream out = new FileOutputStream (file )) {
281
- StreamUtils .copy (zip , out );
284
+ StreamUtils .copy (stream , out );
282
285
}
283
286
try {
284
287
Files .getFileAttributeView (file .toPath (), BasicFileAttributeView .class )
285
- .setTimes (entry . getLastModifiedTime (), entry . getLastAccessTime (), entry . getCreationTime ());
288
+ .setTimes (getLastModifiedTime (entry ), getLastAccessTime (entry ), getCreationTime (entry ));
286
289
}
287
290
catch (IOException ex ) {
288
291
// File system does not support setting time attributes. Continue.
289
292
}
290
293
}
291
294
295
+ private static FileTime getCreationTime (JarEntry entry ) {
296
+ if (entry .getCreationTime () != null ) {
297
+ return entry .getCreationTime ();
298
+ }
299
+ return entry .getLastModifiedTime ();
300
+ }
301
+
302
+ private static FileTime getLastAccessTime (JarEntry entry ) {
303
+ if (entry .getLastAccessTime () != null ) {
304
+ return entry .getLastAccessTime ();
305
+ }
306
+ return getLastModifiedTime (entry );
307
+ }
308
+
309
+ private static FileTime getLastModifiedTime (JarEntry entry ) {
310
+ if (entry .getLastModifiedTime () != null ) {
311
+ return entry .getLastModifiedTime ();
312
+ }
313
+ return entry .getCreationTime ();
314
+ }
315
+
292
316
private static void mkDirs (File file ) throws IOException {
293
317
if (!file .exists () && !file .mkdirs ()) {
294
318
throw new IOException ("Unable to create directory " + file );
295
319
}
296
320
}
297
321
298
- private static JarEntry createJarEntry (String location , ZipEntry originalEntry ) {
322
+ private static JarEntry createJarEntry (String location , JarEntry originalEntry ) {
299
323
JarEntry jarEntry = new JarEntry (location );
300
- FileTime lastModifiedTime = originalEntry . getLastModifiedTime ();
324
+ FileTime lastModifiedTime = getLastModifiedTime (originalEntry );
301
325
if (lastModifiedTime != null ) {
302
326
jarEntry .setLastModifiedTime (lastModifiedTime );
303
327
}
304
- FileTime lastAccessTime = originalEntry . getLastAccessTime ();
328
+ FileTime lastAccessTime = getLastAccessTime (originalEntry );
305
329
if (lastAccessTime != null ) {
306
330
jarEntry .setLastAccessTime (lastAccessTime );
307
331
}
308
- FileTime creationTime = originalEntry . getCreationTime ();
332
+ FileTime creationTime = getCreationTime (originalEntry );
309
333
if (creationTime != null ) {
310
334
jarEntry .setCreationTime (creationTime );
311
335
}
312
336
return jarEntry ;
313
337
}
314
338
315
- private static void withZipEntries (File file , ThrowingConsumer callback ) throws IOException {
316
- try (ZipInputStream stream = new ZipInputStream (new FileInputStream (file ))) {
317
- ZipEntry entry = stream .getNextEntry ();
318
- while (entry != null ) {
339
+ private static void withJarEntries (File file , ThrowingConsumer callback ) throws IOException {
340
+ try (JarFile jarFile = new JarFile (file )) {
341
+ Enumeration <JarEntry > entries = jarFile .entries ();
342
+ while (entries .hasMoreElements ()) {
343
+ JarEntry entry = entries .nextElement ();
319
344
if (StringUtils .hasLength (entry .getName ())) {
320
- callback .accept (stream , entry );
345
+ try (InputStream stream = jarFile .getInputStream (entry )) {
346
+ callback .accept (stream , entry );
347
+ }
321
348
}
322
- entry = stream .getNextEntry ();
323
349
}
324
350
}
325
351
}
@@ -336,14 +362,14 @@ private static File assertFileIsContainedInDirectory(File directory, File file,
336
362
@ FunctionalInterface
337
363
private interface EntryNameTransformer {
338
364
339
- String getName (ZipEntry entry );
365
+ String getName (JarEntry entry );
340
366
341
367
}
342
368
343
369
@ FunctionalInterface
344
370
private interface ThrowingConsumer {
345
371
346
- void accept (ZipInputStream stream , ZipEntry entry ) throws IOException ;
372
+ void accept (InputStream stream , JarEntry entry ) throws IOException ;
347
373
348
374
}
349
375
@@ -356,14 +382,14 @@ private interface FileResolver {
356
382
void createDirectories () throws IOException ;
357
383
358
384
/**
359
- * Resolves the given {@link ZipEntry } to a file.
360
- * @param entry the zip entry
385
+ * Resolves the given {@link JarEntry } to a file.
386
+ * @param entry the jar entry
361
387
* @param newName the new name of the file
362
388
* @return file where the contents should be written or {@code null} if this entry
363
389
* should be skipped
364
390
* @throws IOException if something went wrong
365
391
*/
366
- default File resolve (ZipEntry entry , String newName ) throws IOException {
392
+ default File resolve (JarEntry entry , String newName ) throws IOException {
367
393
return resolve (entry .getName (), newName );
368
394
}
369
395
0 commit comments