44import com .genexus .GXBaseCollection ;
55import com .genexus .SdtMessages_Message ;
66import com .genexus .StructSdtMessages_Message ;
7- import org .apache .commons .compress .compressors .gzip .GzipCompressorInputStream ;
87import org .apache .commons .compress .compressors .gzip .GzipCompressorOutputStream ;
8+ import org .apache .commons .compress .compressors .gzip .GzipParameters ;
99import org .apache .logging .log4j .Logger ;
1010
1111import org .apache .commons .compress .archivers .sevenz .SevenZArchiveEntry ;
1818import java .io .*;
1919import java .nio .file .Files ;
2020import java .util .ArrayList ;
21- import java .util .Enumeration ;
2221import java .util .Stack ;
2322import java .util .jar .JarEntry ;
24- import java .util .jar .JarFile ;
23+ import java .util .jar .JarInputStream ;
2524import java .util .jar .JarOutputStream ;
2625import java .util .zip .*;
2726
@@ -287,62 +286,106 @@ private static void addFileToTar(TarArchiveOutputStream tarOut, File file, Strin
287286 }
288287
289288 private static void compressToGzip (File [] files , String outputPath ) throws IOException {
289+ if (files == null || files .length == 0 ) {
290+ throw new IllegalArgumentException ("No files to compress" );
291+ }
290292 if (outputPath == null || outputPath .isEmpty ()) {
291293 throw new IllegalArgumentException ("Output path is null or empty" );
292294 }
293295 File outputFile = new File (outputPath );
294296 if (outputFile .exists () && !outputFile .canWrite ()) {
295297 throw new IOException ("Cannot write to output file" );
296- } else {
297- File parentDir = outputFile .getParentFile ();
298- if (parentDir != null && !parentDir .exists () && !parentDir .mkdirs ()) {
299- throw new IOException ("Failed to create output directory" );
300- }
301298 }
302- try (FileOutputStream fos = new FileOutputStream (outputFile );
303- BufferedOutputStream bos = new BufferedOutputStream (fos );
304- GzipCompressorOutputStream gcos = new GzipCompressorOutputStream (bos );
305- TarArchiveOutputStream taos = new TarArchiveOutputStream (gcos )) {
306- taos .setLongFileMode (TarArchiveOutputStream .LONGFILE_GNU );
307- Stack <File > stack = new Stack <>();
308- Stack <String > pathStack = new Stack <>();
309- for (File file : files ) {
310- if (file == null ) continue ;
311- stack .push (file );
312- pathStack .push ("" );
299+ File parentDir = outputFile .getParentFile ();
300+ if (parentDir != null && !parentDir .exists () && !parentDir .mkdirs ()) {
301+ throw new IOException ("Failed to create output directory" );
302+ }
303+ boolean singleFile = files .length == 1 && files [0 ].isFile ();
304+ File tempFile = File .createTempFile ("compress_" , ".tmp" , parentDir );
305+ if (singleFile ) {
306+ try (
307+ FileInputStream fis = new FileInputStream (files [0 ]);
308+ FileOutputStream fos = new FileOutputStream (tempFile );
309+ BufferedOutputStream bos = new BufferedOutputStream (fos );
310+ GzipCompressorOutputStream gcos = new GzipCompressorOutputStream (bos )
311+ ) {
312+ byte [] buffer = new byte [8192 ];
313+ int len ;
314+ while ((len = fis .read (buffer )) != -1 ) {
315+ gcos .write (buffer , 0 , len );
316+ }
313317 }
314- while (!stack .isEmpty ()) {
315- File currentFile = stack .pop ();
316- String path = pathStack .pop ();
317- String entryName = path + currentFile .getName ();
318- if (currentFile .isDirectory ()) {
319- File [] dirFiles = currentFile .listFiles ();
320- if (dirFiles != null ) {
321- if (dirFiles .length == 0 ) {
318+ } else {
319+ try (
320+ FileOutputStream fos = new FileOutputStream (tempFile );
321+ BufferedOutputStream bos = new BufferedOutputStream (fos );
322+ GzipCompressorOutputStream gcos = new GzipCompressorOutputStream (bos );
323+ TarArchiveOutputStream taos = new TarArchiveOutputStream (gcos )
324+ ) {
325+ taos .setLongFileMode (TarArchiveOutputStream .LONGFILE_GNU );
326+ Stack <File > fileStack = new Stack <>();
327+ Stack <String > pathStack = new Stack <>();
328+ for (File f : files ) {
329+ if (f != null ) {
330+ fileStack .push (f );
331+ pathStack .push ("" );
332+ }
333+ }
334+ while (!fileStack .isEmpty ()) {
335+ File currentFile = fileStack .pop ();
336+ String path = pathStack .pop ();
337+ String entryName = path + currentFile .getName ();
338+ if (currentFile .isDirectory ()) {
339+ File [] children = currentFile .listFiles ();
340+ if (children != null && children .length > 0 ) {
341+ for (File child : children ) {
342+ fileStack .push (child );
343+ pathStack .push (entryName + "/" );
344+ }
345+ } else {
322346 TarArchiveEntry entry = new TarArchiveEntry (entryName + "/" );
323347 taos .putArchiveEntry (entry );
324348 taos .closeArchiveEntry ();
325- } else {
326- for (File child : dirFiles ) {
327- stack .push (child );
328- pathStack .push (entryName + "/" );
329- }
330349 }
331- }
332- } else {
333- TarArchiveEntry entry = new TarArchiveEntry ( currentFile , entryName );
334- taos . putArchiveEntry ( entry );
335- try ( FileInputStream fis = new FileInputStream ( currentFile )) {
336- byte [] buffer = new byte [ 1024 ] ;
337- int len ;
338- while (( len = fis . read (buffer )) != - 1 ) {
339- taos . write ( buffer , 0 , len );
350+ } else {
351+ TarArchiveEntry entry = new TarArchiveEntry ( currentFile , entryName );
352+ taos . putArchiveEntry ( entry );
353+ try ( FileInputStream fis = new FileInputStream ( currentFile )) {
354+ byte [] buffer = new byte [ 8192 ];
355+ int len ;
356+ while (( len = fis . read ( buffer )) != - 1 ) {
357+ taos . write (buffer , 0 , len );
358+ }
340359 }
360+ taos .closeArchiveEntry ();
341361 }
342- taos .closeArchiveEntry ();
343362 }
344363 }
345364 }
365+ if (!tempFile .exists ()) {
366+ throw new IOException ("Failed to create the archive" );
367+ }
368+ String finalName = outputPath ;
369+ if (singleFile ) {
370+ if (!finalName .toLowerCase ().endsWith (".gz" )) {
371+ finalName += ".gz" ;
372+ }
373+ } else {
374+ if (finalName .toLowerCase ().endsWith (".tar.gz" )) {
375+ // do nothing
376+ } else if (finalName .toLowerCase ().endsWith (".gz" )) {
377+ finalName = finalName .substring (0 , finalName .length () - 3 ) + ".tar.gz" ;
378+ } else {
379+ finalName += ".tar.gz" ;
380+ }
381+ }
382+ File finalFile = new File (finalName );
383+ if (finalFile .exists () && !finalFile .delete ()) {
384+ throw new IOException ("Failed to delete existing file with desired name" );
385+ }
386+ if (!tempFile .renameTo (finalFile )) {
387+ throw new IOException ("Failed to rename archive to desired name" );
388+ }
346389 }
347390
348391 private static void compressToJar (File [] files , String outputPath ) throws IOException {
@@ -481,54 +524,117 @@ private static void decompressTar(File archive, String directory) throws IOExcep
481524 }
482525
483526 private static void decompressGzip (File archive , String directory ) throws IOException {
484- byte [] buffer = new byte [8192 ];
485- InputStream fi = Files .newInputStream (archive .toPath ());
486- InputStream bi = new BufferedInputStream (fi );
487- InputStream gzi = new GzipCompressorInputStream (bi );
488- String fileName = archive .getName ();
489- if (fileName .endsWith (".gz" )) {
490- fileName = fileName .substring (0 , fileName .length () - 3 );
491- }
492- File outputFile = new File (directory , fileName );
493- File parent = outputFile .getParentFile ();
494- if (!parent .exists ()) {
495- parent .mkdirs ();
496- }
497- OutputStream fo = Files .newOutputStream (outputFile .toPath ());
498- int len ;
499- while ((len = gzi .read (buffer )) != -1 ) {
500- fo .write (buffer , 0 , len );
501- }
502- fo .close ();
503- gzi .close ();
504- }
527+ if (!archive .exists () || !archive .isFile ()) {
528+ throw new IllegalArgumentException ("The archive file does not exist or is not a file." );
529+ }
530+ File targetDir = new File (directory );
531+ if (!targetDir .exists () || !targetDir .isDirectory ()) {
532+ throw new IllegalArgumentException ("The specified directory does not exist or is not a directory." );
533+ }
534+ File tempFile = File .createTempFile ("decompressed_" , ".tmp" );
535+ try (
536+ FileInputStream fis = new FileInputStream (archive );
537+ GZIPInputStream gzipInputStream = new GZIPInputStream (fis );
538+ FileOutputStream fos = new FileOutputStream (tempFile )
539+ ) {
540+ byte [] buffer = new byte [8192 ];
541+ int len ;
542+ while ((len = gzipInputStream .read (buffer )) != -1 ) {
543+ fos .write (buffer , 0 , len );
544+ }
545+ }
505546
506- private static void decompressJar (File archive , String directory ) throws IOException {
507- byte [] buffer = new byte [1024 ];
508- JarFile jarFile = new JarFile (archive );
509- Enumeration <JarEntry > entries = jarFile .entries ();
510- while (entries .hasMoreElements ()) {
511- JarEntry entry = entries .nextElement ();
512- File newFile = new File (directory , entry .getName ());
513- if (entry .isDirectory ()) {
514- if (!newFile .isDirectory () && !newFile .mkdirs ()) {
515- throw new IOException ("Failed to create directory " + newFile );
547+ boolean isTar = false ;
548+ try (FileInputStream tempFis = new FileInputStream (tempFile );
549+ TarArchiveInputStream testTar = new TarArchiveInputStream (tempFis )) {
550+ TarArchiveEntry testEntry = testTar .getNextTarEntry ();
551+ if (testEntry != null ) {
552+ isTar = true ;
553+ }
554+ } catch (IOException ignored ) {}
555+ if (isTar ) {
556+ try (FileInputStream tarFis = new FileInputStream (tempFile );
557+ TarArchiveInputStream tarInput = new TarArchiveInputStream (tarFis )) {
558+
559+ TarArchiveEntry entry ;
560+ while ((entry = tarInput .getNextTarEntry ()) != null ) {
561+ File outFile = new File (targetDir , entry .getName ());
562+ if (entry .isDirectory ()) {
563+ if (!outFile .exists () && !outFile .mkdirs ()) {
564+ throw new IOException ("Failed to create directory: " + outFile );
565+ }
566+ } else {
567+ File parent = outFile .getParentFile ();
568+ if (!parent .exists () && !parent .mkdirs ()) {
569+ throw new IOException ("Failed to create directory: " + parent );
570+ }
571+ try (FileOutputStream os = new FileOutputStream (outFile )) {
572+ byte [] buffer = new byte [8192 ];
573+ int count ;
574+ while ((count = tarInput .read (buffer )) != -1 ) {
575+ os .write (buffer , 0 , count );
576+ }
577+ }
578+ }
516579 }
517- } else {
518- File parent = newFile .getParentFile ();
519- if (!parent .isDirectory () && !parent .mkdirs ()) {
520- throw new IOException ("Failed to create directory " + parent );
580+ }
581+ } else {
582+ String name = archive .getName ();
583+ if (name .toLowerCase ().endsWith (".gz" )) {
584+ name = name .substring (0 , name .length () - 3 );
585+ }
586+ File singleOutFile = new File (targetDir , name );
587+ if (!tempFile .renameTo (singleOutFile )) {
588+ try (
589+ FileInputStream in = new FileInputStream (tempFile );
590+ FileOutputStream out = new FileOutputStream (singleOutFile )
591+ ) {
592+ byte [] buffer = new byte [8192 ];
593+ int len ;
594+ while ((len = in .read (buffer )) != -1 ) {
595+ out .write (buffer , 0 , len );
596+ }
521597 }
522- InputStream is = jarFile .getInputStream (entry );
523- FileOutputStream fos = new FileOutputStream (newFile );
524- int len ;
525- while ((len = is .read (buffer )) > 0 ) {
526- fos .write (buffer , 0 , len );
598+ }
599+ }
600+ if (!tempFile .delete ()) {
601+ tempFile .deleteOnExit ();
602+ }
603+ }
604+
605+ private static void decompressJar (File archive , String directory ) throws IOException {
606+ if (!archive .exists () || !archive .isFile ()) {
607+ throw new IOException ("Invalid archive file." );
608+ }
609+ File targetDir = new File (directory );
610+ if (!targetDir .exists ()) {
611+ if (!targetDir .mkdirs ()) {
612+ throw new IOException ("Failed to create target directory." );
613+ }
614+ }
615+ try (JarInputStream jarInputStream = new JarInputStream (Files .newInputStream (archive .toPath ()))) {
616+ JarEntry entry ;
617+ while ((entry = jarInputStream .getNextJarEntry ()) != null ) {
618+ File outputFile = new File (targetDir , entry .getName ());
619+ if (entry .isDirectory ()) {
620+ if (!outputFile .exists () && !outputFile .mkdirs ()) {
621+ throw new IOException ("Failed to create directory: " + outputFile .getAbsolutePath ());
622+ }
623+ } else {
624+ File parent = outputFile .getParentFile ();
625+ if (!parent .exists () && !parent .mkdirs ()) {
626+ throw new IOException ("Failed to create parent directory: " + parent .getAbsolutePath ());
627+ }
628+ try (FileOutputStream fos = new FileOutputStream (outputFile )) {
629+ byte [] buffer = new byte [1024 ];
630+ int bytesRead ;
631+ while ((bytesRead = jarInputStream .read (buffer )) != -1 ) {
632+ fos .write (buffer , 0 , bytesRead );
633+ }
634+ }
527635 }
528- fos .close ();
529- is .close ();
636+ jarInputStream .closeEntry ();
530637 }
531638 }
532- jarFile .close ();
533639 }
534640}
0 commit comments