From 594547c7b5da17fbd2ffc9bce2425c4733c3b0f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Thu, 2 May 2024 11:10:54 -0300
Subject: [PATCH 01/49] Compress EXO initial module outline
---
gxcompress/pom.xml | 15 ++++++++
.../main/java/com/genexus/Compression.java | 37 +++++++++++++++++++
.../java/com/genexus/CompressionFormat.java | 6 +++
.../java/com/genexus/CompressionMethod.java | 6 +++
.../main/java/com/genexus/DictionarySize.java | 5 +++
.../main/java/com/genexus/GXCompressor.java | 27 ++++++++++++++
.../main/java/com/genexus/IGXCompressor.java | 10 +++++
pom.xml | 1 +
8 files changed, 107 insertions(+)
create mode 100644 gxcompress/pom.xml
create mode 100644 gxcompress/src/main/java/com/genexus/Compression.java
create mode 100644 gxcompress/src/main/java/com/genexus/CompressionFormat.java
create mode 100644 gxcompress/src/main/java/com/genexus/CompressionMethod.java
create mode 100644 gxcompress/src/main/java/com/genexus/DictionarySize.java
create mode 100644 gxcompress/src/main/java/com/genexus/GXCompressor.java
create mode 100644 gxcompress/src/main/java/com/genexus/IGXCompressor.java
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
new file mode 100644
index 000000000..4b57efe76
--- /dev/null
+++ b/gxcompress/pom.xml
@@ -0,0 +1,15 @@
+
+
+ 4.0.0
+
+ com.genexus
+ parent
+ ${revision}${changelist}
+
+
+ gxcompress
+ GeneXus compression and decompression module
+
+
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/Compression.java b/gxcompress/src/main/java/com/genexus/Compression.java
new file mode 100644
index 000000000..7cfa76044
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/Compression.java
@@ -0,0 +1,37 @@
+package com.genexus;
+
+import java.io.File;
+
+public class Compression {
+ private String path;
+ private CompressionFormat format;
+ private String password;
+ private CompressionMethod method;
+ private DictionarySize dictionarySize;
+
+ public Compression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+ this.path = path;
+ this.format = format;
+ this.password = password;
+ this.method = method;
+ this.dictionarySize = dictionarySize;
+ }
+
+ public void addFile(File file) {
+ // Implementation goes here
+ }
+
+ public void addFolder(File folder) {
+ // Implementation goes here
+ }
+
+ public void save() {
+ // Implementation goes here
+ }
+
+ public void close() {
+ // Implementation goes here
+ }
+}
+
+
diff --git a/gxcompress/src/main/java/com/genexus/CompressionFormat.java b/gxcompress/src/main/java/com/genexus/CompressionFormat.java
new file mode 100644
index 000000000..625d4f049
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/CompressionFormat.java
@@ -0,0 +1,6 @@
+package com.genexus;
+
+public enum CompressionFormat {
+ BZIP2, GZIP, PACK200, LZMA, XZ, SNAPPY, UNIX_COMPRESS, DEFLATE, DEFLATE64,
+ LZ4, BROTLI, ZSTANDARD, AR, CPIO, JAR, TAR, ZIP, DUMP, SEVEN_Z, ARJ
+}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/CompressionMethod.java b/gxcompress/src/main/java/com/genexus/CompressionMethod.java
new file mode 100644
index 000000000..53e9bb314
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/CompressionMethod.java
@@ -0,0 +1,6 @@
+package com.genexus;
+
+public enum CompressionMethod {
+ STORE, FASTEST, FAST, NORMAL, GOOD, BEST
+}
+
diff --git a/gxcompress/src/main/java/com/genexus/DictionarySize.java b/gxcompress/src/main/java/com/genexus/DictionarySize.java
new file mode 100644
index 000000000..65be7e9a6
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/DictionarySize.java
@@ -0,0 +1,5 @@
+package com.genexus;
+
+public enum DictionarySize {
+ FOUR_MB, THIRTY_TWO_MB, ONE_TWENTY_EIGHT_MB, ONE_GB, TWO_GB, FOUR_GB, SIX_GB, EIGHT_GB, TWELVE_GB, SIXTEEN_GB
+}
diff --git a/gxcompress/src/main/java/com/genexus/GXCompressor.java b/gxcompress/src/main/java/com/genexus/GXCompressor.java
new file mode 100644
index 000000000..42c8aa83c
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/GXCompressor.java
@@ -0,0 +1,27 @@
+package com.genexus;
+
+import java.io.File;
+
+public class GXCompressor implements IGXCompressor {
+ @Override
+ public void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+ // Implementation goes here
+ }
+
+ @Override
+ public void compress(File folder, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+ // Implementation goes here
+ }
+
+ @Override
+ public Compression newCompression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+ // Implementation goes here
+ return new Compression(path, format, password, method, dictionarySize);
+ }
+
+ @Override
+ public void decompress(File file, String path, String password) {
+ // Implementation goes here
+ }
+}
+
diff --git a/gxcompress/src/main/java/com/genexus/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/IGXCompressor.java
new file mode 100644
index 000000000..3b6157326
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/IGXCompressor.java
@@ -0,0 +1,10 @@
+package com.genexus;
+
+import java.io.File;
+
+public interface IGXCompressor {
+ void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize);
+ void compress(File folder, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize);
+ Compression newCompression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize);
+ void decompress(File file, String path, String password);
+}
diff --git a/pom.xml b/pom.xml
index 642fbb979..67070d706 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,6 +114,7 @@
gxcloudstorage-tests
gxobservability
gxcloudstorage-awss3-v2
+ gxcompress
From ef671384ab7a3b0241f6958aa3f111b384c03e77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 7 May 2024 12:59:03 -0300
Subject: [PATCH 02/49] Initial implementation of the compress method
---
gxcompress/pom.xml | 8 +
.../java/com/genexus/CompressionFormat.java | 2 +-
.../main/java/com/genexus/GXCompressor.java | 184 +++++++++++++++++-
3 files changed, 191 insertions(+), 3 deletions(-)
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index 4b57efe76..5de24ce9f 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -12,4 +12,12 @@
gxcompress
GeneXus compression and decompression module
+
+
+ org.apache.commons
+ commons-compress
+ 1.26.1
+
+
+
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/CompressionFormat.java b/gxcompress/src/main/java/com/genexus/CompressionFormat.java
index 625d4f049..4fe700cda 100644
--- a/gxcompress/src/main/java/com/genexus/CompressionFormat.java
+++ b/gxcompress/src/main/java/com/genexus/CompressionFormat.java
@@ -2,5 +2,5 @@
public enum CompressionFormat {
BZIP2, GZIP, PACK200, LZMA, XZ, SNAPPY, UNIX_COMPRESS, DEFLATE, DEFLATE64,
- LZ4, BROTLI, ZSTANDARD, AR, CPIO, JAR, TAR, ZIP, DUMP, SEVEN_Z, ARJ
+ LZ4, BROTLI, ZSTANDARD, AR, CPIO, JAR, TAR, ZIP, DUMP, SEVEN_Z, ARJ, SEVENZ
}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/GXCompressor.java b/gxcompress/src/main/java/com/genexus/GXCompressor.java
index 42c8aa83c..38bf4f769 100644
--- a/gxcompress/src/main/java/com/genexus/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/GXCompressor.java
@@ -1,11 +1,38 @@
package com.genexus;
-import java.io.File;
+import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
+import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.io.IOUtils;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.zip.Deflater;
public class GXCompressor implements IGXCompressor {
@Override
public void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
- // Implementation goes here
+ switch (format) {
+ case ZIP:
+ compressToZip(files, path, method, dictionarySize);
+ break;
+ case SEVENZ:
+ compressToSevenZ(files, path);
+ break;
+ case TAR:
+ compressToTar(files, path);
+ break;
+ case GZIP:
+ compressToGzip(files, path);
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported compression format: " + format);
+ }
}
@Override
@@ -23,5 +50,158 @@ public Compression newCompression(String path, CompressionFormat format, String
public void decompress(File file, String path, String password) {
// Implementation goes here
}
+
+ private int convertCompressionMethodToLevel(CompressionMethod method) {
+ switch (method) {
+ case FASTEST:
+ return Deflater.BEST_SPEED;
+ case BEST:
+ return Deflater.BEST_COMPRESSION;
+ default:
+ return Deflater.DEFAULT_COMPRESSION;
+ }
+ }
+
+ private void compressToZip(File[] files, String outputPath, CompressionMethod method, DictionarySize dictionarySize) {
+ // Set up the zip output stream to write to the specified output path
+ try (OutputStream fos = Files.newOutputStream(Paths.get(outputPath));
+ ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos)) {
+
+ // Setting the compression method and level
+ zos.setMethod(ZipArchiveOutputStream.DEFLATED);
+ zos.setLevel(convertCompressionMethodToLevel(method));
+
+ // Add each file as a new entry to the zip file
+ for (File file : files) {
+ if (file.exists()) {
+ addFileToZip(zos, file, "");
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to compress files", e);
+ }
+ }
+
+ private void addFileToZip(ZipArchiveOutputStream zos, File file, String base) throws IOException {
+ String entryName = base + file.getName();
+ if (file.isDirectory()) {
+ // If it's a directory, recursively add its contents
+ File[] children = file.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ addFileToZip(zos, child, entryName + "/");
+ }
+ }
+ } else {
+ // If it's a file, add it as an entry
+ ZipArchiveEntry zipEntry = new ZipArchiveEntry(file, entryName);
+ zos.putArchiveEntry(zipEntry);
+ try (FileInputStream fis = new FileInputStream(file)) {
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = fis.read(buffer)) >= 0) {
+ zos.write(buffer, 0, length);
+ }
+ }
+ zos.closeArchiveEntry();
+ }
+ }
+
+ private void compressToSevenZ(File[] files, String outputPath) {
+ File outputSevenZFile = new File(outputPath);
+ try (SevenZOutputFile sevenZOutput = new SevenZOutputFile(outputSevenZFile)) {
+ for (File file : files) {
+ addToSevenZArchive(sevenZOutput, file, "");
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Error creating 7z archive", e);
+ }
+ }
+
+ private void addToSevenZArchive(SevenZOutputFile sevenZOutput, File file, String base) throws IOException {
+ if (file.isFile()) {
+ SevenZArchiveEntry entry = sevenZOutput.createArchiveEntry(file, base + file.getName());
+ sevenZOutput.putArchiveEntry(entry);
+ try (FileInputStream fis = new FileInputStream(file)) {
+ byte[] buffer = new byte[8192];
+ int bytesRead;
+ while ((bytesRead = fis.read(buffer)) != -1) {
+ sevenZOutput.write(buffer, 0, bytesRead);
+ }
+ }
+ sevenZOutput.closeArchiveEntry();
+ } else if (file.isDirectory()) {
+ // Recursively add directory contents
+ File[] children = file.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ addToSevenZArchive(sevenZOutput, child, base + file.getName() + "/");
+ }
+ }
+ }
+ }
+
+ private void compressToTar(File[] files, String outputPath) {
+ File outputTarFile = new File(outputPath);
+ try (FileOutputStream fos = new FileOutputStream(outputTarFile);
+ TarArchiveOutputStream taos = new TarArchiveOutputStream(fos)) {
+
+ // Configure TAR options
+ taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
+ taos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
+ taos.setAddPaxHeadersForNonAsciiNames(true);
+
+ for (File file : files) {
+ addFileToTar(taos, file, "");
+ }
+ taos.finish();
+ } catch (IOException e) {
+ throw new RuntimeException("Error creating TAR archive", e);
+ }
+ }
+
+ private void addFileToTar(TarArchiveOutputStream taos, File file, String base) throws IOException {
+ if (file.isDirectory()) {
+ File[] children = file.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ addFileToTar(taos, child, base + file.getName() + "/");
+ }
+ }
+ } else if (file.isFile()) {
+ String entryName = base + file.getName();
+ TarArchiveEntry entry = new TarArchiveEntry(file, entryName);
+ entry.setSize(file.length());
+
+ taos.putArchiveEntry(entry);
+ try (FileInputStream fis = new FileInputStream(file)) {
+ IOUtils.copy(fis, taos);
+ }
+ taos.closeArchiveEntry();
+ }
+ }
+
+ private void compressToGzip(File[] files, String outputPath) {
+ if (files.length > 1) {
+ throw new IllegalArgumentException("GZIP does not support multiple files. Consider archiving the files first.");
+ }
+
+ File inputFile = files[0];
+ File outputFile = new File(outputPath);
+
+ try (InputStream in = Files.newInputStream(inputFile.toPath());
+ FileOutputStream fout = new FileOutputStream(outputFile);
+ BufferedOutputStream out = new BufferedOutputStream(fout);
+ GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(out)) {
+
+ byte[] buffer = new byte[4096];
+ int n;
+ while (-1 != (n = in.read(buffer))) {
+ gzOut.write(buffer, 0, n);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Error compressing file with GZIP", e);
+ }
+ }
}
From c041d267ad6452a23f7c7ba00969db28b8db33f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 7 May 2024 16:46:30 -0300
Subject: [PATCH 03/49] Initial decompress functionality implementation
---
.../main/java/com/genexus/GXCompressor.java | 143 +++++++++++++++++-
1 file changed, 141 insertions(+), 2 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/GXCompressor.java b/gxcompress/src/main/java/com/genexus/GXCompressor.java
index 38bf4f769..36db2cdfe 100644
--- a/gxcompress/src/main/java/com/genexus/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/GXCompressor.java
@@ -1,8 +1,10 @@
package com.genexus;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
+import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
@@ -11,8 +13,12 @@
import java.io.*;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.zip.Deflater;
+import java.util.zip.*;
+
+import static org.apache.commons.io.FilenameUtils.getExtension;
+import static org.apache.commons.io.FilenameUtils.removeExtension;
public class GXCompressor implements IGXCompressor {
@Override
@@ -48,7 +54,27 @@ public Compression newCompression(String path, CompressionFormat format, String
@Override
public void decompress(File file, String path, String password) {
- // Implementation goes here
+ // Determine the format from the file extension or other logic
+ String extension = getExtension(file.getName());
+ try {
+ switch (extension.toLowerCase()) {
+ case "zip":
+ decompressZip(file, path);
+ break;
+ case "7z":
+ decompress7z(file, path, password); // New case for 7z
+ break;
+ case "tar":
+ decompressTar(file, path);
+ case "gzip":
+ decompressGzip(file, path);
+ // Add cases for other formats as needed
+ default:
+ throw new IllegalArgumentException("Unsupported compression format for decompression: " + extension);
+ }
+ } catch (IOException ioe) {
+ System.out.println("Fail");
+ }
}
private int convertCompressionMethodToLevel(CompressionMethod method) {
@@ -203,5 +229,118 @@ private void compressToGzip(File[] files, String outputPath) {
throw new RuntimeException("Error compressing file with GZIP", e);
}
}
+
+ private void decompressZip(File zipFile, String directory) {
+ Path zipFilePath = Paths.get(zipFile.toURI());
+ Path targetDir = Paths.get(directory);
+ targetDir = targetDir.toAbsolutePath(); // Ensure the path is absolute to prevent directory traversal issues
+
+ try (InputStream fis = Files.newInputStream(zipFilePath.toFile().toPath());
+ ZipInputStream zipIn = new ZipInputStream(fis)) {
+
+ ZipEntry entry;
+ while ((entry = zipIn.getNextEntry()) != null) {
+ Path resolvedPath = targetDir.resolve(entry.getName()).normalize();
+
+ if (!resolvedPath.startsWith(targetDir)) {
+ throw new SecurityException("Zip entry is outside of the target dir: " + entry.getName());
+ }
+
+ if (entry.isDirectory()) {
+ Files.createDirectories(resolvedPath);
+ } else {
+ Path parentDir = resolvedPath.getParent();
+ if (!Files.exists(parentDir)) {
+ Files.createDirectories(parentDir);
+ }
+ try (OutputStream out = Files.newOutputStream(resolvedPath.toFile().toPath())) {
+ byte[] buffer = new byte[4096];
+ int length;
+ while ((length = zipIn.read(buffer)) > 0) {
+ out.write(buffer, 0, length);
+ }
+ }
+ }
+ zipIn.closeEntry();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to decompress ZIP file: " + zipFilePath, e);
+ }
+ }
+
+ private void decompress7z(File file, String outputPath, String password) throws IOException {
+ Path targetDir = Paths.get(outputPath).toAbsolutePath(); // Ensure the path is absolute
+
+ try (SevenZFile sevenZFile = new SevenZFile(file, password.toCharArray())) {
+ SevenZArchiveEntry entry = sevenZFile.getNextEntry();
+ while (entry != null) {
+ Path resolvedPath = targetDir.resolve(entry.getName()).normalize();
+
+ if (!resolvedPath.startsWith(targetDir)) {
+ throw new IOException("Entry is outside of the target dir: " + entry.getName());
+ }
+
+ if (entry.isDirectory()) {
+ Files.createDirectories(resolvedPath);
+ } else {
+ File outputFile = resolvedPath.toFile();
+ File parentDir = outputFile.getParentFile();
+ if (!parentDir.exists() && !parentDir.mkdirs()) {
+ throw new IOException("Failed to create directory: " + parentDir);
+ }
+
+ try (FileOutputStream out = new FileOutputStream(outputFile)) {
+ byte[] content = new byte[(int) entry.getSize()];
+ sevenZFile.read(content, 0, content.length);
+ out.write(content);
+ }
+ }
+ entry = sevenZFile.getNextEntry();
+ }
+ }
+ }
+
+ private void decompressTar(File file, String outputPath) throws IOException {
+ Path targetDir = Paths.get(outputPath).toAbsolutePath();
+ try (InputStream fi = Files.newInputStream(file.toPath());
+ TarArchiveInputStream ti = new TarArchiveInputStream(fi)) {
+ TarArchiveEntry entry;
+ while ((entry = ti.getNextTarEntry()) != null) {
+ File outputFile = targetDir.resolve(entry.getName()).normalize().toFile();
+ if (!outputFile.toPath().startsWith(targetDir)) {
+ throw new IOException("Entry is outside of the target directory: " + entry.getName());
+ }
+ if (entry.isDirectory()) {
+ if (!outputFile.exists()) {
+ if (!outputFile.mkdirs()) {
+ throw new IOException("Failed to create directory: " + outputFile);
+ }
+ }
+ } else {
+ File parent = outputFile.getParentFile();
+ if (!parent.exists() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory: " + parent);
+ }
+ try (OutputStream out = new FileOutputStream(outputFile)) {
+ IOUtils.copy(ti, out);
+ }
+ }
+ }
+ }
+ }
+
+ private void decompressGzip(File inputFile, String outputPath) throws IOException {
+ Path outputFilePath = Paths.get(outputPath, removeExtension(inputFile.getName()));
+ try (FileInputStream fis = new FileInputStream(inputFile);
+ GZIPInputStream gzis = new GZIPInputStream(fis);
+ FileOutputStream fos = new FileOutputStream(outputFilePath.toFile())) {
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+ while ((bytesRead = gzis.read(buffer)) != -1) {
+ fos.write(buffer, 0, bytesRead);
+ }
+ }
+ }
+
}
From 30f4618e3c06d0e4adb3146c3a56ea79321c07a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 28 May 2024 11:14:11 -0300
Subject: [PATCH 04/49] Add Compression data type
---
gxcompress/pom.xml | 6 ++
.../main/java/com/genexus/Compression.java | 66 ++++++++++++++--
.../java/com/genexus/CompressionFormat.java | 3 +-
.../java/com/genexus/CompressionMethod.java | 2 +-
.../main/java/com/genexus/GXCompressor.java | 68 ++++++++---------
.../main/java/com/genexus/IGXCompressor.java | 8 +-
gxcompress/src/test/java/CompressionTest.java | 75 +++++++++++++++++++
7 files changed, 177 insertions(+), 51 deletions(-)
create mode 100644 gxcompress/src/test/java/CompressionTest.java
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index 5de24ce9f..41992d0cf 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -18,6 +18,12 @@
commons-compress
1.26.1
+
+ org.junit.jupiter
+ junit-jupiter
+ RELEASE
+ test
+
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/Compression.java b/gxcompress/src/main/java/com/genexus/Compression.java
index 7cfa76044..83d083a57 100644
--- a/gxcompress/src/main/java/com/genexus/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/Compression.java
@@ -1,6 +1,8 @@
package com.genexus;
import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
public class Compression {
private String path;
@@ -9,29 +11,79 @@ public class Compression {
private CompressionMethod method;
private DictionarySize dictionarySize;
+ private List filesToCompress;
+
+ public Compression() {}
+
public Compression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
this.path = path;
this.format = format;
this.password = password;
this.method = method;
this.dictionarySize = dictionarySize;
+ this.filesToCompress = new ArrayList<>();
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public void setFormat(CompressionFormat format) {
+ this.format = format;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setMethod(CompressionMethod method) {
+ this.method = method;
+ }
+
+ public void setDictionarySize(DictionarySize dictionarySize) {
+ this.dictionarySize = dictionarySize;
}
public void addFile(File file) {
- // Implementation goes here
+ if (file.exists()) {
+ filesToCompress.add(file);
+ } else {
+ System.out.println("File does not exist: " + file.getAbsolutePath());
+ }
}
public void addFolder(File folder) {
- // Implementation goes here
+ if (folder.exists() && folder.isDirectory()) {
+ File[] files = folder.listFiles();
+ if (files != null) {
+ for (File file : files) {
+ if (file.isDirectory()) {
+ addFolder(file);
+ } else {
+ addFile(file);
+ }
+ }
+ }
+ } else {
+ System.out.println("Folder does not exist or is not a directory: " + folder.getAbsolutePath());
+ }
}
public void save() {
- // Implementation goes here
+ if (filesToCompress.isEmpty()) {
+ System.out.println("No files have been added for compression.");
+ return;
+ }
+ File[] filesArray = filesToCompress.toArray(new File[0]);
+ try {
+ GXCompressor.compress(filesArray, path, format, password, method, dictionarySize);
+ System.out.println("Compression successful to: " + path);
+ } catch (IllegalArgumentException e) {
+ System.err.println("Compression failed: " + e.getMessage());
+ }
}
public void close() {
- // Implementation goes here
+ filesToCompress.clear();
}
-}
-
-
+}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/CompressionFormat.java b/gxcompress/src/main/java/com/genexus/CompressionFormat.java
index 4fe700cda..259235482 100644
--- a/gxcompress/src/main/java/com/genexus/CompressionFormat.java
+++ b/gxcompress/src/main/java/com/genexus/CompressionFormat.java
@@ -1,6 +1,5 @@
package com.genexus;
public enum CompressionFormat {
- BZIP2, GZIP, PACK200, LZMA, XZ, SNAPPY, UNIX_COMPRESS, DEFLATE, DEFLATE64,
- LZ4, BROTLI, ZSTANDARD, AR, CPIO, JAR, TAR, ZIP, DUMP, SEVEN_Z, ARJ, SEVENZ
+ GZIP,TAR, ZIP, SEVENZ
}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/CompressionMethod.java b/gxcompress/src/main/java/com/genexus/CompressionMethod.java
index 53e9bb314..add8cb6ae 100644
--- a/gxcompress/src/main/java/com/genexus/CompressionMethod.java
+++ b/gxcompress/src/main/java/com/genexus/CompressionMethod.java
@@ -1,6 +1,6 @@
package com.genexus;
public enum CompressionMethod {
- STORE, FASTEST, FAST, NORMAL, GOOD, BEST
+ FASTEST, BEST
}
diff --git a/gxcompress/src/main/java/com/genexus/GXCompressor.java b/gxcompress/src/main/java/com/genexus/GXCompressor.java
index 36db2cdfe..05a58b40f 100644
--- a/gxcompress/src/main/java/com/genexus/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/GXCompressor.java
@@ -21,8 +21,8 @@
import static org.apache.commons.io.FilenameUtils.removeExtension;
public class GXCompressor implements IGXCompressor {
- @Override
- public void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+
+ public static void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
switch (format) {
case ZIP:
compressToZip(files, path, method, dictionarySize);
@@ -41,20 +41,25 @@ public void compress(File[] files, String path, CompressionFormat format, String
}
}
- @Override
- public void compress(File folder, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
- // Implementation goes here
+
+ public static void compress(File folder, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+ if (!folder.exists()) {
+ throw new IllegalArgumentException("The specified folder does not exist: " + folder.getAbsolutePath());
+ }
+ if (!folder.isDirectory()) {
+ throw new IllegalArgumentException("The specified file is not a directory: " + folder.getAbsolutePath());
+ }
+ File[] files = new File[] { folder };
+ compress(files, path, format, password, method, dictionarySize);
}
- @Override
- public Compression newCompression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
- // Implementation goes here
+
+ public static Compression newCompression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
return new Compression(path, format, password, method, dictionarySize);
}
- @Override
- public void decompress(File file, String path, String password) {
- // Determine the format from the file extension or other logic
+
+ public static void decompress(File file, String path, String password) {
String extension = getExtension(file.getName());
try {
switch (extension.toLowerCase()) {
@@ -62,13 +67,12 @@ public void decompress(File file, String path, String password) {
decompressZip(file, path);
break;
case "7z":
- decompress7z(file, path, password); // New case for 7z
+ decompress7z(file, path, password);
break;
case "tar":
decompressTar(file, path);
case "gzip":
decompressGzip(file, path);
- // Add cases for other formats as needed
default:
throw new IllegalArgumentException("Unsupported compression format for decompression: " + extension);
}
@@ -77,7 +81,7 @@ public void decompress(File file, String path, String password) {
}
}
- private int convertCompressionMethodToLevel(CompressionMethod method) {
+ private static int convertCompressionMethodToLevel(CompressionMethod method) {
switch (method) {
case FASTEST:
return Deflater.BEST_SPEED;
@@ -88,16 +92,11 @@ private int convertCompressionMethodToLevel(CompressionMethod method) {
}
}
- private void compressToZip(File[] files, String outputPath, CompressionMethod method, DictionarySize dictionarySize) {
- // Set up the zip output stream to write to the specified output path
+ private static void compressToZip(File[] files, String outputPath, CompressionMethod method, DictionarySize dictionarySize) {
try (OutputStream fos = Files.newOutputStream(Paths.get(outputPath));
ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos)) {
-
- // Setting the compression method and level
zos.setMethod(ZipArchiveOutputStream.DEFLATED);
zos.setLevel(convertCompressionMethodToLevel(method));
-
- // Add each file as a new entry to the zip file
for (File file : files) {
if (file.exists()) {
addFileToZip(zos, file, "");
@@ -108,10 +107,9 @@ private void compressToZip(File[] files, String outputPath, CompressionMethod me
}
}
- private void addFileToZip(ZipArchiveOutputStream zos, File file, String base) throws IOException {
+ private static void addFileToZip(ZipArchiveOutputStream zos, File file, String base) throws IOException {
String entryName = base + file.getName();
if (file.isDirectory()) {
- // If it's a directory, recursively add its contents
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
@@ -119,7 +117,6 @@ private void addFileToZip(ZipArchiveOutputStream zos, File file, String base) th
}
}
} else {
- // If it's a file, add it as an entry
ZipArchiveEntry zipEntry = new ZipArchiveEntry(file, entryName);
zos.putArchiveEntry(zipEntry);
try (FileInputStream fis = new FileInputStream(file)) {
@@ -133,7 +130,7 @@ private void addFileToZip(ZipArchiveOutputStream zos, File file, String base) th
}
}
- private void compressToSevenZ(File[] files, String outputPath) {
+ private static void compressToSevenZ(File[] files, String outputPath) {
File outputSevenZFile = new File(outputPath);
try (SevenZOutputFile sevenZOutput = new SevenZOutputFile(outputSevenZFile)) {
for (File file : files) {
@@ -144,7 +141,7 @@ private void compressToSevenZ(File[] files, String outputPath) {
}
}
- private void addToSevenZArchive(SevenZOutputFile sevenZOutput, File file, String base) throws IOException {
+ private static void addToSevenZArchive(SevenZOutputFile sevenZOutput, File file, String base) throws IOException {
if (file.isFile()) {
SevenZArchiveEntry entry = sevenZOutput.createArchiveEntry(file, base + file.getName());
sevenZOutput.putArchiveEntry(entry);
@@ -157,7 +154,6 @@ private void addToSevenZArchive(SevenZOutputFile sevenZOutput, File file, String
}
sevenZOutput.closeArchiveEntry();
} else if (file.isDirectory()) {
- // Recursively add directory contents
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
@@ -167,12 +163,10 @@ private void addToSevenZArchive(SevenZOutputFile sevenZOutput, File file, String
}
}
- private void compressToTar(File[] files, String outputPath) {
+ private static void compressToTar(File[] files, String outputPath) {
File outputTarFile = new File(outputPath);
try (FileOutputStream fos = new FileOutputStream(outputTarFile);
TarArchiveOutputStream taos = new TarArchiveOutputStream(fos)) {
-
- // Configure TAR options
taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
taos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
taos.setAddPaxHeadersForNonAsciiNames(true);
@@ -186,7 +180,7 @@ private void compressToTar(File[] files, String outputPath) {
}
}
- private void addFileToTar(TarArchiveOutputStream taos, File file, String base) throws IOException {
+ private static void addFileToTar(TarArchiveOutputStream taos, File file, String base) throws IOException {
if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null) {
@@ -207,7 +201,7 @@ private void addFileToTar(TarArchiveOutputStream taos, File file, String base) t
}
}
- private void compressToGzip(File[] files, String outputPath) {
+ private static void compressToGzip(File[] files, String outputPath) {
if (files.length > 1) {
throw new IllegalArgumentException("GZIP does not support multiple files. Consider archiving the files first.");
}
@@ -230,10 +224,10 @@ private void compressToGzip(File[] files, String outputPath) {
}
}
- private void decompressZip(File zipFile, String directory) {
+ private static void decompressZip(File zipFile, String directory) {
Path zipFilePath = Paths.get(zipFile.toURI());
Path targetDir = Paths.get(directory);
- targetDir = targetDir.toAbsolutePath(); // Ensure the path is absolute to prevent directory traversal issues
+ targetDir = targetDir.toAbsolutePath();
try (InputStream fis = Files.newInputStream(zipFilePath.toFile().toPath());
ZipInputStream zipIn = new ZipInputStream(fis)) {
@@ -268,8 +262,8 @@ private void decompressZip(File zipFile, String directory) {
}
}
- private void decompress7z(File file, String outputPath, String password) throws IOException {
- Path targetDir = Paths.get(outputPath).toAbsolutePath(); // Ensure the path is absolute
+ private static void decompress7z(File file, String outputPath, String password) throws IOException {
+ Path targetDir = Paths.get(outputPath).toAbsolutePath();
try (SevenZFile sevenZFile = new SevenZFile(file, password.toCharArray())) {
SevenZArchiveEntry entry = sevenZFile.getNextEntry();
@@ -300,7 +294,7 @@ private void decompress7z(File file, String outputPath, String password) throws
}
}
- private void decompressTar(File file, String outputPath) throws IOException {
+ private static void decompressTar(File file, String outputPath) throws IOException {
Path targetDir = Paths.get(outputPath).toAbsolutePath();
try (InputStream fi = Files.newInputStream(file.toPath());
TarArchiveInputStream ti = new TarArchiveInputStream(fi)) {
@@ -329,7 +323,7 @@ private void decompressTar(File file, String outputPath) throws IOException {
}
}
- private void decompressGzip(File inputFile, String outputPath) throws IOException {
+ private static void decompressGzip(File inputFile, String outputPath) throws IOException {
Path outputFilePath = Paths.get(outputPath, removeExtension(inputFile.getName()));
try (FileInputStream fis = new FileInputStream(inputFile);
GZIPInputStream gzis = new GZIPInputStream(fis);
diff --git a/gxcompress/src/main/java/com/genexus/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/IGXCompressor.java
index 3b6157326..b9e839cf1 100644
--- a/gxcompress/src/main/java/com/genexus/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/IGXCompressor.java
@@ -3,8 +3,8 @@
import java.io.File;
public interface IGXCompressor {
- void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize);
- void compress(File folder, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize);
- Compression newCompression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize);
- void decompress(File file, String path, String password);
+ static void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {}
+ static void compress(File folder, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {}
+ static Compression newCompression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) { return new Compression();}
+ static void decompress(File file, String path, String password) {}
}
diff --git a/gxcompress/src/test/java/CompressionTest.java b/gxcompress/src/test/java/CompressionTest.java
new file mode 100644
index 000000000..a09adc7b1
--- /dev/null
+++ b/gxcompress/src/test/java/CompressionTest.java
@@ -0,0 +1,75 @@
+import com.genexus.CompressionFormat;
+import com.genexus.CompressionMethod;
+import com.genexus.GXCompressor;
+import com.genexus.DictionarySize;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class CompressionTest {
+ private List tempFiles = new ArrayList<>();
+ private File tempDir;
+
+ @BeforeEach
+ void setUp() throws IOException {
+ tempDir = Files.createTempDirectory("compressionTest").toFile();
+ for (int i = 0; i < 3; i++) {
+ File tempFile = new File(tempDir, "testFile" + i + ".txt");
+ try (FileWriter writer = new FileWriter(tempFile)) {
+ writer.write("This is a test file number " + i);
+ }
+ tempFiles.add(tempFile);
+ }
+ }
+
+ @AfterEach
+ void tearDown() {
+ for (File file : tempFiles) {
+ file.delete();
+ }
+ tempDir.delete();
+ }
+
+ @Test
+ void testCompressionAndDecompression() throws IOException {
+ // Define paths
+ String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.zip";
+ String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
+
+ // Compress files
+ File[] filesArray = tempFiles.toArray(new File[0]);
+ GXCompressor.compress(filesArray, compressedPath, CompressionFormat.ZIP, "", CompressionMethod.BEST, DictionarySize.FOUR_MB);
+
+ // Decompress files
+ File compressedFile = new File(compressedPath);
+ GXCompressor.decompress(compressedFile, decompressedPath, "");
+
+ // Check files
+ File decompressedDir = new File(decompressedPath);
+ File[] decompressedFiles = decompressedDir.listFiles();
+
+ assertNotNull(decompressedFiles);
+ assertEquals(tempFiles.size(), decompressedFiles.length);
+
+ for (File original : tempFiles) {
+ File decompressedFile = new File(decompressedDir, original.getName());
+ assertTrue(decompressedFile.exists());
+ assertArrayEquals(Files.readAllBytes(original.toPath()), Files.readAllBytes(decompressedFile.toPath()));
+ }
+
+ compressedFile.delete();
+ for (File file : decompressedFiles) {
+ file.delete();
+ }
+ decompressedDir.delete();
+ }
+}
\ No newline at end of file
From db32861a26d1eeafccc22ade86ea5e80d261caa7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 29 May 2024 11:53:54 -0300
Subject: [PATCH 05/49] All 4 compression and decompression methods working
---
gxcompress/pom.xml | 7 +-
.../main/java/com/genexus/Compression.java | 20 +----
.../java/com/genexus/CompressionMethod.java | 6 --
.../main/java/com/genexus/DictionarySize.java | 5 --
.../main/java/com/genexus/GXCompressor.java | 65 +++++++-------
.../main/java/com/genexus/IGXCompressor.java | 8 +-
gxcompress/src/test/java/CompressionTest.java | 84 ++++++++++++++++---
7 files changed, 121 insertions(+), 74 deletions(-)
delete mode 100644 gxcompress/src/main/java/com/genexus/CompressionMethod.java
delete mode 100644 gxcompress/src/main/java/com/genexus/DictionarySize.java
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index 41992d0cf..58b541116 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -16,7 +16,12 @@
org.apache.commons
commons-compress
- 1.26.1
+ 1.26.2
+
+
+ org.tukaani
+ xz
+ 1.9
org.junit.jupiter
diff --git a/gxcompress/src/main/java/com/genexus/Compression.java b/gxcompress/src/main/java/com/genexus/Compression.java
index 83d083a57..f93bb7536 100644
--- a/gxcompress/src/main/java/com/genexus/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/Compression.java
@@ -7,19 +7,15 @@
public class Compression {
private String path;
private CompressionFormat format;
- private String password;
- private CompressionMethod method;
- private DictionarySize dictionarySize;
+ private int dictionarySize;
private List filesToCompress;
public Compression() {}
- public Compression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+ public Compression(String path, CompressionFormat format, int dictionarySize) {
this.path = path;
this.format = format;
- this.password = password;
- this.method = method;
this.dictionarySize = dictionarySize;
this.filesToCompress = new ArrayList<>();
}
@@ -32,15 +28,7 @@ public void setFormat(CompressionFormat format) {
this.format = format;
}
- public void setPassword(String password) {
- this.password = password;
- }
-
- public void setMethod(CompressionMethod method) {
- this.method = method;
- }
-
- public void setDictionarySize(DictionarySize dictionarySize) {
+ public void setDictionarySize(int dictionarySize) {
this.dictionarySize = dictionarySize;
}
@@ -76,7 +64,7 @@ public void save() {
}
File[] filesArray = filesToCompress.toArray(new File[0]);
try {
- GXCompressor.compress(filesArray, path, format, password, method, dictionarySize);
+ GXCompressor.compress(filesArray, path, format, dictionarySize);
System.out.println("Compression successful to: " + path);
} catch (IllegalArgumentException e) {
System.err.println("Compression failed: " + e.getMessage());
diff --git a/gxcompress/src/main/java/com/genexus/CompressionMethod.java b/gxcompress/src/main/java/com/genexus/CompressionMethod.java
deleted file mode 100644
index add8cb6ae..000000000
--- a/gxcompress/src/main/java/com/genexus/CompressionMethod.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.genexus;
-
-public enum CompressionMethod {
- FASTEST, BEST
-}
-
diff --git a/gxcompress/src/main/java/com/genexus/DictionarySize.java b/gxcompress/src/main/java/com/genexus/DictionarySize.java
deleted file mode 100644
index 65be7e9a6..000000000
--- a/gxcompress/src/main/java/com/genexus/DictionarySize.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.genexus;
-
-public enum DictionarySize {
- FOUR_MB, THIRTY_TWO_MB, ONE_TWENTY_EIGHT_MB, ONE_GB, TWO_GB, FOUR_GB, SIX_GB, EIGHT_GB, TWELVE_GB, SIXTEEN_GB
-}
diff --git a/gxcompress/src/main/java/com/genexus/GXCompressor.java b/gxcompress/src/main/java/com/genexus/GXCompressor.java
index 05a58b40f..c534906f1 100644
--- a/gxcompress/src/main/java/com/genexus/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/GXCompressor.java
@@ -18,14 +18,13 @@
import java.util.zip.*;
import static org.apache.commons.io.FilenameUtils.getExtension;
-import static org.apache.commons.io.FilenameUtils.removeExtension;
public class GXCompressor implements IGXCompressor {
- public static void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+ public static void compress(File[] files, String path, CompressionFormat format, int dictionarySize) {
switch (format) {
case ZIP:
- compressToZip(files, path, method, dictionarySize);
+ compressToZip(files, path, dictionarySize);
break;
case SEVENZ:
compressToSevenZ(files, path);
@@ -42,7 +41,7 @@ public static void compress(File[] files, String path, CompressionFormat format,
}
- public static void compress(File folder, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
+ public static void compress(File folder, String path, CompressionFormat format, int dictionarySize) {
if (!folder.exists()) {
throw new IllegalArgumentException("The specified folder does not exist: " + folder.getAbsolutePath());
}
@@ -50,16 +49,16 @@ public static void compress(File folder, String path, CompressionFormat format,
throw new IllegalArgumentException("The specified file is not a directory: " + folder.getAbsolutePath());
}
File[] files = new File[] { folder };
- compress(files, path, format, password, method, dictionarySize);
+ compress(files, path, format, dictionarySize);
}
- public static Compression newCompression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {
- return new Compression(path, format, password, method, dictionarySize);
+ public static Compression newCompression(String path, CompressionFormat format, int dictionarySize) {
+ return new Compression(path, format, dictionarySize);
}
-
- public static void decompress(File file, String path, String password) {
+
+ public static void decompress(File file, String path) {
String extension = getExtension(file.getName());
try {
switch (extension.toLowerCase()) {
@@ -67,36 +66,26 @@ public static void decompress(File file, String path, String password) {
decompressZip(file, path);
break;
case "7z":
- decompress7z(file, path, password);
+ decompress7z(file, path);
break;
case "tar":
decompressTar(file, path);
- case "gzip":
+ break;
+ case "gz":
decompressGzip(file, path);
+ break;
default:
throw new IllegalArgumentException("Unsupported compression format for decompression: " + extension);
}
} catch (IOException ioe) {
- System.out.println("Fail");
- }
- }
-
- private static int convertCompressionMethodToLevel(CompressionMethod method) {
- switch (method) {
- case FASTEST:
- return Deflater.BEST_SPEED;
- case BEST:
- return Deflater.BEST_COMPRESSION;
- default:
- return Deflater.DEFAULT_COMPRESSION;
+ System.out.println("Decompression failed: " + ioe.getMessage());
}
}
- private static void compressToZip(File[] files, String outputPath, CompressionMethod method, DictionarySize dictionarySize) {
+ private static void compressToZip(File[] files, String outputPath, int dictionarySize) {
try (OutputStream fos = Files.newOutputStream(Paths.get(outputPath));
ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos)) {
zos.setMethod(ZipArchiveOutputStream.DEFLATED);
- zos.setLevel(convertCompressionMethodToLevel(method));
for (File file : files) {
if (file.exists()) {
addFileToZip(zos, file, "");
@@ -262,10 +251,10 @@ private static void decompressZip(File zipFile, String directory) {
}
}
- private static void decompress7z(File file, String outputPath, String password) throws IOException {
+ private static void decompress7z(File file, String outputPath) throws IOException {
Path targetDir = Paths.get(outputPath).toAbsolutePath();
- try (SevenZFile sevenZFile = new SevenZFile(file, password.toCharArray())) {
+ try (SevenZFile sevenZFile = new SevenZFile(file)) {
SevenZArchiveEntry entry = sevenZFile.getNextEntry();
while (entry != null) {
Path resolvedPath = targetDir.resolve(entry.getName()).normalize();
@@ -324,10 +313,27 @@ private static void decompressTar(File file, String outputPath) throws IOExcepti
}
private static void decompressGzip(File inputFile, String outputPath) throws IOException {
- Path outputFilePath = Paths.get(outputPath, removeExtension(inputFile.getName()));
+ // Create the output directory if it doesn't exist
+ File outputDir = new File(outputPath);
+ if (!outputDir.exists() && !outputDir.mkdirs()) {
+ throw new IOException("Failed to create the output directory: " + outputDir.getAbsolutePath());
+ }
+
+ // Generate the output file's name by removing the .gz extension
+ String outputFileName = inputFile.getName();
+ if (outputFileName.endsWith(".gz")) {
+ outputFileName = outputFileName.substring(0, outputFileName.length() - 3);
+ } else {
+ // Handle cases where the extension is not .gz (just a safeguard)
+ throw new IllegalArgumentException("The input file does not have a .gz extension.");
+ }
+
+ File outputFile = new File(outputDir, outputFileName);
+
+ // Decompress the GZIP file
try (FileInputStream fis = new FileInputStream(inputFile);
GZIPInputStream gzis = new GZIPInputStream(fis);
- FileOutputStream fos = new FileOutputStream(outputFilePath.toFile())) {
+ FileOutputStream fos = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = gzis.read(buffer)) != -1) {
@@ -336,5 +342,6 @@ private static void decompressGzip(File inputFile, String outputPath) throws IOE
}
}
+
}
diff --git a/gxcompress/src/main/java/com/genexus/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/IGXCompressor.java
index b9e839cf1..709e64834 100644
--- a/gxcompress/src/main/java/com/genexus/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/IGXCompressor.java
@@ -3,8 +3,8 @@
import java.io.File;
public interface IGXCompressor {
- static void compress(File[] files, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {}
- static void compress(File folder, String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) {}
- static Compression newCompression(String path, CompressionFormat format, String password, CompressionMethod method, DictionarySize dictionarySize) { return new Compression();}
- static void decompress(File file, String path, String password) {}
+ static void compress(File[] files, String path, CompressionFormat format, int dictionarySize) {}
+ static void compress(File folder, String path, CompressionFormat format, int dictionarySize) {}
+ static Compression newCompression(String path, CompressionFormat format, int dictionarySize) { return new Compression();}
+ static void decompress(File file, String path) {}
}
diff --git a/gxcompress/src/test/java/CompressionTest.java b/gxcompress/src/test/java/CompressionTest.java
index a09adc7b1..9bfa1e372 100644
--- a/gxcompress/src/test/java/CompressionTest.java
+++ b/gxcompress/src/test/java/CompressionTest.java
@@ -1,7 +1,5 @@
import com.genexus.CompressionFormat;
-import com.genexus.CompressionMethod;
import com.genexus.GXCompressor;
-import com.genexus.DictionarySize;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -17,6 +15,7 @@
class CompressionTest {
private List tempFiles = new ArrayList<>();
+ private File singleTestFile;
private File tempDir;
@BeforeEach
@@ -36,40 +35,99 @@ void tearDown() {
for (File file : tempFiles) {
file.delete();
}
+ if (singleTestFile != null) singleTestFile.delete();
tempDir.delete();
}
@Test
- void testCompressionAndDecompression() throws IOException {
- // Define paths
+ void testCompressionAndDecompressionZIP() throws IOException {
String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.zip";
String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
-
- // Compress files
File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(filesArray, compressedPath, CompressionFormat.ZIP, "", CompressionMethod.BEST, DictionarySize.FOUR_MB);
-
- // Decompress files
+ GXCompressor.compress(filesArray, compressedPath, CompressionFormat.ZIP, 4);
File compressedFile = new File(compressedPath);
- GXCompressor.decompress(compressedFile, decompressedPath, "");
-
- // Check files
+ GXCompressor.decompress(compressedFile, decompressedPath);
File decompressedDir = new File(decompressedPath);
File[] decompressedFiles = decompressedDir.listFiles();
-
assertNotNull(decompressedFiles);
assertEquals(tempFiles.size(), decompressedFiles.length);
+ for (File original : tempFiles) {
+ File decompressedFile = new File(decompressedDir, original.getName());
+ assertTrue(decompressedFile.exists());
+ assertArrayEquals(Files.readAllBytes(original.toPath()), Files.readAllBytes(decompressedFile.toPath()));
+ }
+ compressedFile.delete();
+ for (File file : decompressedFiles) {
+ file.delete();
+ }
+ decompressedDir.delete();
+ }
+ @Test
+ void testCompressionAndDecompressionTAR() throws IOException {
+ String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.tar";
+ String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
+ File[] filesArray = tempFiles.toArray(new File[0]);
+ GXCompressor.compress(filesArray, compressedPath, CompressionFormat.TAR, 128);
+ File compressedFile = new File(compressedPath);
+ GXCompressor.decompress(compressedFile, decompressedPath);
+ File decompressedDir = new File(decompressedPath);
+ File[] decompressedFiles = decompressedDir.listFiles();
+ assertNotNull(decompressedFiles);
+ assertEquals(tempFiles.size(), decompressedFiles.length);
for (File original : tempFiles) {
File decompressedFile = new File(decompressedDir, original.getName());
assertTrue(decompressedFile.exists());
assertArrayEquals(Files.readAllBytes(original.toPath()), Files.readAllBytes(decompressedFile.toPath()));
}
+ compressedFile.delete();
+ for (File file : decompressedFiles) {
+ file.delete();
+ }
+ decompressedDir.delete();
+ }
+ @Test
+ void testCompressionAndDecompressionSEVENZ() throws IOException {
+ String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.7z";
+ String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
+ File[] filesArray = tempFiles.toArray(new File[0]);
+ GXCompressor.compress(filesArray, compressedPath, CompressionFormat.SEVENZ, 32);
+ File compressedFile = new File(compressedPath);
+ GXCompressor.decompress(compressedFile, decompressedPath);
+ File decompressedDir = new File(decompressedPath);
+ File[] decompressedFiles = decompressedDir.listFiles();
+ assertNotNull(decompressedFiles);
+ assertEquals(tempFiles.size(), decompressedFiles.length);
+ for (File original : tempFiles) {
+ File decompressedFile = new File(decompressedDir, original.getName());
+ assertTrue(decompressedFile.exists());
+ assertArrayEquals(Files.readAllBytes(original.toPath()), Files.readAllBytes(decompressedFile.toPath()));
+ }
compressedFile.delete();
for (File file : decompressedFiles) {
file.delete();
}
decompressedDir.delete();
}
+
+ @Test
+ void testCompressionAndDecompressionGZIP() throws IOException {
+ String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.gz";
+ String decompressedDirPath = tempDir.getAbsolutePath();
+ File singleTestFile = new File(tempDir, "testFile.txt");
+ try (FileWriter writer = new FileWriter(singleTestFile)) {
+ writer.write("This is a test file");
+ }
+ GXCompressor.compress(new File[]{singleTestFile}, compressedPath, CompressionFormat.GZIP, 4);
+ File compressedFile = new File(compressedPath);
+ assertTrue(compressedFile.exists());
+ GXCompressor.decompress(compressedFile, decompressedDirPath);
+ File decompressedFile = new File(decompressedDirPath, singleTestFile.getName());
+ assertTrue(decompressedFile.exists());
+ assertArrayEquals(Files.readAllBytes(singleTestFile.toPath()), Files.readAllBytes(decompressedFile.toPath()));
+ compressedFile.delete();
+ decompressedFile.delete();
+ }
+
}
\ No newline at end of file
From 8307368d96336510ecee65d10c1a685919add206 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 29 May 2024 12:00:08 -0300
Subject: [PATCH 06/49] Refactor into compression package
---
.../java/com/genexus/{ => compression}/Compression.java | 2 +-
.../com/genexus/{ => compression}/CompressionFormat.java | 2 +-
.../java/com/genexus/{ => compression}/GXCompressor.java | 2 +-
.../java/com/genexus/{ => compression}/IGXCompressor.java | 2 +-
.../java/{ => com/genexus/compression}/CompressionTest.java | 6 ++----
5 files changed, 6 insertions(+), 8 deletions(-)
rename gxcompress/src/main/java/com/genexus/{ => compression}/Compression.java (98%)
rename gxcompress/src/main/java/com/genexus/{ => compression}/CompressionFormat.java (63%)
rename gxcompress/src/main/java/com/genexus/{ => compression}/GXCompressor.java (99%)
rename gxcompress/src/main/java/com/genexus/{ => compression}/IGXCompressor.java (92%)
rename gxcompress/src/test/java/{ => com/genexus/compression}/CompressionTest.java (97%)
diff --git a/gxcompress/src/main/java/com/genexus/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
similarity index 98%
rename from gxcompress/src/main/java/com/genexus/Compression.java
rename to gxcompress/src/main/java/com/genexus/compression/Compression.java
index f93bb7536..10852fec7 100644
--- a/gxcompress/src/main/java/com/genexus/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -1,4 +1,4 @@
-package com.genexus;
+package com.genexus.compression;
import java.io.File;
import java.util.ArrayList;
diff --git a/gxcompress/src/main/java/com/genexus/CompressionFormat.java b/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
similarity index 63%
rename from gxcompress/src/main/java/com/genexus/CompressionFormat.java
rename to gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
index 259235482..4192b3c65 100644
--- a/gxcompress/src/main/java/com/genexus/CompressionFormat.java
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
@@ -1,4 +1,4 @@
-package com.genexus;
+package com.genexus.compression;
public enum CompressionFormat {
GZIP,TAR, ZIP, SEVENZ
diff --git a/gxcompress/src/main/java/com/genexus/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
similarity index 99%
rename from gxcompress/src/main/java/com/genexus/GXCompressor.java
rename to gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index c534906f1..31d772e37 100644
--- a/gxcompress/src/main/java/com/genexus/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -1,4 +1,4 @@
-package com.genexus;
+package com.genexus.compression;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
diff --git a/gxcompress/src/main/java/com/genexus/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
similarity index 92%
rename from gxcompress/src/main/java/com/genexus/IGXCompressor.java
rename to gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index 709e64834..0098dea45 100644
--- a/gxcompress/src/main/java/com/genexus/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -1,4 +1,4 @@
-package com.genexus;
+package com.genexus.compression;
import java.io.File;
diff --git a/gxcompress/src/test/java/CompressionTest.java b/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
similarity index 97%
rename from gxcompress/src/test/java/CompressionTest.java
rename to gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
index 9bfa1e372..eb7d6233a 100644
--- a/gxcompress/src/test/java/CompressionTest.java
+++ b/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
@@ -1,5 +1,5 @@
-import com.genexus.CompressionFormat;
-import com.genexus.GXCompressor;
+package com.genexus.compression;
+
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -15,7 +15,6 @@
class CompressionTest {
private List tempFiles = new ArrayList<>();
- private File singleTestFile;
private File tempDir;
@BeforeEach
@@ -35,7 +34,6 @@ void tearDown() {
for (File file : tempFiles) {
file.delete();
}
- if (singleTestFile != null) singleTestFile.delete();
tempDir.delete();
}
From 8bf8104b3ee89ffc75c43fddac50ee4d15b25fd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 29 May 2024 14:50:56 -0300
Subject: [PATCH 07/49] Logging and return values for better flow control
---
gxcompress/pom.xml | 11 +++
.../com/genexus/compression/Compression.java | 28 +++---
.../com/genexus/compression/GXCompressor.java | 87 ++++++++++---------
.../genexus/compression/IGXCompressor.java | 6 +-
4 files changed, 78 insertions(+), 54 deletions(-)
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index 58b541116..7e19dd4fe 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -29,6 +29,17 @@
RELEASE
test
+
+ org.apache.logging.log4j
+ log4j-core
+ ${log4j.version}
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.21.1
+ compile
+
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 10852fec7..4bf7f81a6 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -1,14 +1,17 @@
package com.genexus.compression;
+import org.apache.logging.log4j.Logger;
+
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class Compression {
+ private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Compression.class);
+
private String path;
private CompressionFormat format;
private int dictionarySize;
-
private List filesToCompress;
public Compression() {}
@@ -36,7 +39,7 @@ public void addFile(File file) {
if (file.exists()) {
filesToCompress.add(file);
} else {
- System.out.println("File does not exist: " + file.getAbsolutePath());
+ log.error("File does not exist: {}", file.getAbsolutePath());
}
}
@@ -53,25 +56,30 @@ public void addFolder(File folder) {
}
}
} else {
- System.out.println("Folder does not exist or is not a directory: " + folder.getAbsolutePath());
+ log.error("Folder does not exist or is not a directory: {}", folder.getAbsolutePath());
}
}
- public void save() {
+ public int save() {
if (filesToCompress.isEmpty()) {
- System.out.println("No files have been added for compression.");
- return;
+ log.error("No files have been added for compression.");
+ return -3;
}
File[] filesArray = filesToCompress.toArray(new File[0]);
+ int compressionResult;
try {
- GXCompressor.compress(filesArray, path, format, dictionarySize);
- System.out.println("Compression successful to: " + path);
+ compressionResult = GXCompressor.compress(filesArray, path, format, dictionarySize);
} catch (IllegalArgumentException e) {
- System.err.println("Compression failed: " + e.getMessage());
+ compressionResult = -1;
+ log.error("Compression failed: {}", e.getMessage());
}
+ return compressionResult;
}
public void close() {
- filesToCompress.clear();
+ this.path = "";
+ this.format = null;
+ this.dictionarySize = 0;
+ this.filesToCompress = new ArrayList<>();
}
}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 31d772e37..7a8852599 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -1,5 +1,7 @@
package com.genexus.compression;
+import org.apache.logging.log4j.Logger;
+
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
@@ -20,36 +22,45 @@
import static org.apache.commons.io.FilenameUtils.getExtension;
public class GXCompressor implements IGXCompressor {
+
+ private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
- public static void compress(File[] files, String path, CompressionFormat format, int dictionarySize) {
- switch (format) {
- case ZIP:
- compressToZip(files, path, dictionarySize);
- break;
- case SEVENZ:
- compressToSevenZ(files, path);
- break;
- case TAR:
- compressToTar(files, path);
- break;
- case GZIP:
- compressToGzip(files, path);
- break;
- default:
- throw new IllegalArgumentException("Unsupported compression format: " + format);
+ public static int compress(File[] files, String path, CompressionFormat format, int dictionarySize) {
+ try {
+ switch (format) {
+ case ZIP:
+ compressToZip(files, path, dictionarySize);
+ break;
+ case SEVENZ:
+ compressToSevenZ(files, path);
+ break;
+ case TAR:
+ compressToTar(files, path);
+ break;
+ case GZIP:
+ compressToGzip(files, path);
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported compression format: " + format);
+ }
+ return 0;
+ } catch (Exception e) {
+ return -1;
}
}
- public static void compress(File folder, String path, CompressionFormat format, int dictionarySize) {
+ public static int compress(File folder, String path, CompressionFormat format, int dictionarySize) {
if (!folder.exists()) {
- throw new IllegalArgumentException("The specified folder does not exist: " + folder.getAbsolutePath());
+ log.error("The specified folder does not exist: {}", folder.getAbsolutePath());
+ return -2;
}
if (!folder.isDirectory()) {
- throw new IllegalArgumentException("The specified file is not a directory: " + folder.getAbsolutePath());
+ log.error("The specified file is not a directory: {}", folder.getAbsolutePath());
+ return -2;
}
File[] files = new File[] { folder };
- compress(files, path, format, dictionarySize);
+ return compress(files, path, format, dictionarySize);
}
@@ -58,27 +69,29 @@ public static Compression newCompression(String path, CompressionFormat format,
}
- public static void decompress(File file, String path) {
+ public static int decompress(File file, String path) {
String extension = getExtension(file.getName());
try {
switch (extension.toLowerCase()) {
case "zip":
decompressZip(file, path);
- break;
+ return 0;
case "7z":
decompress7z(file, path);
- break;
+ return 0;
case "tar":
decompressTar(file, path);
- break;
+ return 0;
case "gz":
decompressGzip(file, path);
- break;
+ return 0;
default:
- throw new IllegalArgumentException("Unsupported compression format for decompression: " + extension);
+ log.error("Unsupported compression format for decompression: {}", extension);
+ return -3;
}
} catch (IOException ioe) {
- System.out.println("Decompression failed: " + ioe.getMessage());
+ log.error("Decompression failed: {}", ioe.getMessage());
+ return -1;
}
}
@@ -119,7 +132,7 @@ private static void addFileToZip(ZipArchiveOutputStream zos, File file, String b
}
}
- private static void compressToSevenZ(File[] files, String outputPath) {
+ private static void compressToSevenZ(File[] files, String outputPath) throws RuntimeException {
File outputSevenZFile = new File(outputPath);
try (SevenZOutputFile sevenZOutput = new SevenZOutputFile(outputSevenZFile)) {
for (File file : files) {
@@ -152,7 +165,7 @@ private static void addToSevenZArchive(SevenZOutputFile sevenZOutput, File file,
}
}
- private static void compressToTar(File[] files, String outputPath) {
+ private static void compressToTar(File[] files, String outputPath) throws RuntimeException {
File outputTarFile = new File(outputPath);
try (FileOutputStream fos = new FileOutputStream(outputTarFile);
TarArchiveOutputStream taos = new TarArchiveOutputStream(fos)) {
@@ -190,7 +203,7 @@ private static void addFileToTar(TarArchiveOutputStream taos, File file, String
}
}
- private static void compressToGzip(File[] files, String outputPath) {
+ private static void compressToGzip(File[] files, String outputPath) throws RuntimeException {
if (files.length > 1) {
throw new IllegalArgumentException("GZIP does not support multiple files. Consider archiving the files first.");
}
@@ -213,7 +226,7 @@ private static void compressToGzip(File[] files, String outputPath) {
}
}
- private static void decompressZip(File zipFile, String directory) {
+ private static void decompressZip(File zipFile, String directory) throws RuntimeException{
Path zipFilePath = Paths.get(zipFile.toURI());
Path targetDir = Paths.get(directory);
targetDir = targetDir.toAbsolutePath();
@@ -313,24 +326,16 @@ private static void decompressTar(File file, String outputPath) throws IOExcepti
}
private static void decompressGzip(File inputFile, String outputPath) throws IOException {
- // Create the output directory if it doesn't exist
File outputDir = new File(outputPath);
if (!outputDir.exists() && !outputDir.mkdirs()) {
throw new IOException("Failed to create the output directory: " + outputDir.getAbsolutePath());
}
-
- // Generate the output file's name by removing the .gz extension
String outputFileName = inputFile.getName();
- if (outputFileName.endsWith(".gz")) {
+ if (outputFileName.endsWith(".gz"))
outputFileName = outputFileName.substring(0, outputFileName.length() - 3);
- } else {
- // Handle cases where the extension is not .gz (just a safeguard)
+ else
throw new IllegalArgumentException("The input file does not have a .gz extension.");
- }
-
File outputFile = new File(outputDir, outputFileName);
-
- // Decompress the GZIP file
try (FileInputStream fis = new FileInputStream(inputFile);
GZIPInputStream gzis = new GZIPInputStream(fis);
FileOutputStream fos = new FileOutputStream(outputFile)) {
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index 0098dea45..0cb848bca 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -3,8 +3,8 @@
import java.io.File;
public interface IGXCompressor {
- static void compress(File[] files, String path, CompressionFormat format, int dictionarySize) {}
- static void compress(File folder, String path, CompressionFormat format, int dictionarySize) {}
+ static int compress(File[] files, String path, CompressionFormat format, int dictionarySize) {return 0;}
+ static int compress(File folder, String path, CompressionFormat format, int dictionarySize) {return 0;}
static Compression newCompression(String path, CompressionFormat format, int dictionarySize) { return new Compression();}
- static void decompress(File file, String path) {}
+ static int decompress(File file, String path) {return 0;}
}
From 1554769a328cb0a32b8944de6e411498cfeecddf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 29 May 2024 16:04:04 -0300
Subject: [PATCH 08/49] Switch compression format type form enum to string
---
.../com/genexus/compression/Compression.java | 8 ++++----
.../com/genexus/compression/GXCompressor.java | 16 ++++++++++++----
.../com/genexus/compression/IGXCompressor.java | 6 +++---
.../com/genexus/compression/CompressionTest.java | 8 ++++----
4 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 4bf7f81a6..7fc5a8c3a 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -10,13 +10,13 @@ public class Compression {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Compression.class);
private String path;
- private CompressionFormat format;
+ private String format;
private int dictionarySize;
private List filesToCompress;
public Compression() {}
- public Compression(String path, CompressionFormat format, int dictionarySize) {
+ public Compression(String path, String format, int dictionarySize) {
this.path = path;
this.format = format;
this.dictionarySize = dictionarySize;
@@ -27,7 +27,7 @@ public void setPath(String path) {
this.path = path;
}
- public void setFormat(CompressionFormat format) {
+ public void setFormat(String format) {
this.format = format;
}
@@ -78,7 +78,7 @@ public int save() {
public void close() {
this.path = "";
- this.format = null;
+ this.format = "";
this.dictionarySize = 0;
this.filesToCompress = new ArrayList<>();
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 7a8852599..802dffe96 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -25,9 +25,10 @@ public class GXCompressor implements IGXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
- public static int compress(File[] files, String path, CompressionFormat format, int dictionarySize) {
+ public static int compress(File[] files, String path, String format, int dictionarySize) {
try {
- switch (format) {
+ CompressionFormat compressionFormat = getCompressionFormat(format);
+ switch (compressionFormat) {
case ZIP:
compressToZip(files, path, dictionarySize);
break;
@@ -50,7 +51,7 @@ public static int compress(File[] files, String path, CompressionFormat format,
}
- public static int compress(File folder, String path, CompressionFormat format, int dictionarySize) {
+ public static int compress(File folder, String path, String format, int dictionarySize) {
if (!folder.exists()) {
log.error("The specified folder does not exist: {}", folder.getAbsolutePath());
return -2;
@@ -64,7 +65,7 @@ public static int compress(File folder, String path, CompressionFormat format, i
}
- public static Compression newCompression(String path, CompressionFormat format, int dictionarySize) {
+ public static Compression newCompression(String path, String format, int dictionarySize) {
return new Compression(path, format, dictionarySize);
}
@@ -347,6 +348,13 @@ private static void decompressGzip(File inputFile, String outputPath) throws IOE
}
}
+ public static CompressionFormat getCompressionFormat(String format) {
+ try {
+ return CompressionFormat.valueOf(format.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid compression format: " + format);
+ }
+ }
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index 0cb848bca..fcbf6bdfd 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -3,8 +3,8 @@
import java.io.File;
public interface IGXCompressor {
- static int compress(File[] files, String path, CompressionFormat format, int dictionarySize) {return 0;}
- static int compress(File folder, String path, CompressionFormat format, int dictionarySize) {return 0;}
- static Compression newCompression(String path, CompressionFormat format, int dictionarySize) { return new Compression();}
+ static int compress(File[] files, String path, String format, int dictionarySize) {return 0;}
+ static int compress(File folder, String path, String format, int dictionarySize) {return 0;}
+ static Compression newCompression(String path, String format, int dictionarySize) { return new Compression();}
static int decompress(File file, String path) {return 0;}
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java b/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
index eb7d6233a..842ebe9de 100644
--- a/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
+++ b/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
@@ -42,7 +42,7 @@ void testCompressionAndDecompressionZIP() throws IOException {
String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.zip";
String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(filesArray, compressedPath, CompressionFormat.ZIP, 4);
+ GXCompressor.compress(filesArray, compressedPath, "zip", 4);
File compressedFile = new File(compressedPath);
GXCompressor.decompress(compressedFile, decompressedPath);
File decompressedDir = new File(decompressedPath);
@@ -66,7 +66,7 @@ void testCompressionAndDecompressionTAR() throws IOException {
String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.tar";
String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(filesArray, compressedPath, CompressionFormat.TAR, 128);
+ GXCompressor.compress(filesArray, compressedPath, "tar", 128);
File compressedFile = new File(compressedPath);
GXCompressor.decompress(compressedFile, decompressedPath);
File decompressedDir = new File(decompressedPath);
@@ -90,7 +90,7 @@ void testCompressionAndDecompressionSEVENZ() throws IOException {
String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.7z";
String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(filesArray, compressedPath, CompressionFormat.SEVENZ, 32);
+ GXCompressor.compress(filesArray, compressedPath, "sevenz", 32);
File compressedFile = new File(compressedPath);
GXCompressor.decompress(compressedFile, decompressedPath);
File decompressedDir = new File(decompressedPath);
@@ -117,7 +117,7 @@ void testCompressionAndDecompressionGZIP() throws IOException {
try (FileWriter writer = new FileWriter(singleTestFile)) {
writer.write("This is a test file");
}
- GXCompressor.compress(new File[]{singleTestFile}, compressedPath, CompressionFormat.GZIP, 4);
+ GXCompressor.compress(new File[]{singleTestFile}, compressedPath, "gzip", 4);
File compressedFile = new File(compressedPath);
assertTrue(compressedFile.exists());
GXCompressor.decompress(compressedFile, decompressedDirPath);
From da6c523cfd6b40e1943c5561ae552b2aa4280140 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 29 May 2024 16:34:29 -0300
Subject: [PATCH 09/49] Change parameter types to basic ones
---
.../com/genexus/compression/Compression.java | 6 ++-
.../com/genexus/compression/GXCompressor.java | 42 +++++++++++--------
.../genexus/compression/IGXCompressor.java | 8 ++--
.../genexus/compression/CompressionTest.java | 39 +++++++----------
4 files changed, 46 insertions(+), 49 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 7fc5a8c3a..e0b4e567e 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -66,9 +66,13 @@ public int save() {
return -3;
}
File[] filesArray = filesToCompress.toArray(new File[0]);
+ String[] paths = new String[filesArray.length];
+ for (int i = 0; i < filesArray.length; i++) {
+ paths[i] = filesArray[i].getPath();
+ }
int compressionResult;
try {
- compressionResult = GXCompressor.compress(filesArray, path, format, dictionarySize);
+ compressionResult = GXCompressor.compress(paths, path, format, dictionarySize);
} catch (IllegalArgumentException e) {
compressionResult = -1;
log.error("Compression failed: {}", e.getMessage());
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 802dffe96..c7ad95f5a 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -25,21 +25,25 @@ public class GXCompressor implements IGXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
- public static int compress(File[] files, String path, String format, int dictionarySize) {
+ public static int compress(String[] files, String path, String format, int dictionarySize) {
+ File[] toCompress = new File[files.length];
+ for (int i = 0; i < files.length; i++) {
+ toCompress[i] = new File(files[i]);
+ }
try {
CompressionFormat compressionFormat = getCompressionFormat(format);
switch (compressionFormat) {
case ZIP:
- compressToZip(files, path, dictionarySize);
+ compressToZip(toCompress, path, dictionarySize);
break;
case SEVENZ:
- compressToSevenZ(files, path);
+ compressToSevenZ(toCompress, path);
break;
case TAR:
- compressToTar(files, path);
+ compressToTar(toCompress, path);
break;
case GZIP:
- compressToGzip(files, path);
+ compressToGzip(toCompress, path);
break;
default:
throw new IllegalArgumentException("Unsupported compression format: " + format);
@@ -51,17 +55,18 @@ public static int compress(File[] files, String path, String format, int diction
}
- public static int compress(File folder, String path, String format, int dictionarySize) {
- if (!folder.exists()) {
- log.error("The specified folder does not exist: {}", folder.getAbsolutePath());
+ public static int compress(String folder, String path, String format, int dictionarySize) {
+ File toCompress = new File(folder);
+ if (!toCompress.exists()) {
+ log.error("The specified folder does not exist: {}", toCompress.getAbsolutePath());
return -2;
}
- if (!folder.isDirectory()) {
- log.error("The specified file is not a directory: {}", folder.getAbsolutePath());
+ if (!toCompress.isDirectory()) {
+ log.error("The specified file is not a directory: {}", toCompress.getAbsolutePath());
return -2;
}
- File[] files = new File[] { folder };
- return compress(files, path, format, dictionarySize);
+ File[] files = new File[] { toCompress };
+ return compress(folder, path, format, dictionarySize);
}
@@ -70,21 +75,22 @@ public static Compression newCompression(String path, String format, int dictio
}
- public static int decompress(File file, String path) {
- String extension = getExtension(file.getName());
+ public static int decompress(String file, String path) {
+ File toCompress = new File(file);
+ String extension = getExtension(toCompress.getName());
try {
switch (extension.toLowerCase()) {
case "zip":
- decompressZip(file, path);
+ decompressZip(toCompress, path);
return 0;
case "7z":
- decompress7z(file, path);
+ decompress7z(toCompress, path);
return 0;
case "tar":
- decompressTar(file, path);
+ decompressTar(toCompress, path);
return 0;
case "gz":
- decompressGzip(file, path);
+ decompressGzip(toCompress, path);
return 0;
default:
log.error("Unsupported compression format for decompression: {}", extension);
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index fcbf6bdfd..f922a0c0b 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -1,10 +1,8 @@
package com.genexus.compression;
-import java.io.File;
-
public interface IGXCompressor {
- static int compress(File[] files, String path, String format, int dictionarySize) {return 0;}
- static int compress(File folder, String path, String format, int dictionarySize) {return 0;}
+ static int compress(String[] files, String path, String format, int dictionarySize) {return 0;}
+ static int compress(String folder, String path, String format, int dictionarySize) {return 0;}
static Compression newCompression(String path, String format, int dictionarySize) { return new Compression();}
- static int decompress(File file, String path) {return 0;}
+ static int decompress(String file, String path) {return 0;}
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java b/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
index 842ebe9de..64d9a01a8 100644
--- a/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
+++ b/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
@@ -17,6 +17,14 @@ class CompressionTest {
private List tempFiles = new ArrayList<>();
private File tempDir;
+ public static String[] convertToPaths(File[] files) {
+ String[] paths = new String[files.length];
+ for (int i = 0; i < files.length; i++) {
+ paths[i] = files[i].getPath();
+ }
+ return paths;
+ }
+
@BeforeEach
void setUp() throws IOException {
tempDir = Files.createTempDirectory("compressionTest").toFile();
@@ -42,9 +50,9 @@ void testCompressionAndDecompressionZIP() throws IOException {
String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.zip";
String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(filesArray, compressedPath, "zip", 4);
+ GXCompressor.compress(convertToPaths(filesArray), compressedPath, "zip", 4);
File compressedFile = new File(compressedPath);
- GXCompressor.decompress(compressedFile, decompressedPath);
+ GXCompressor.decompress(compressedPath, decompressedPath);
File decompressedDir = new File(decompressedPath);
File[] decompressedFiles = decompressedDir.listFiles();
assertNotNull(decompressedFiles);
@@ -66,9 +74,9 @@ void testCompressionAndDecompressionTAR() throws IOException {
String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.tar";
String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(filesArray, compressedPath, "tar", 128);
+ GXCompressor.compress(convertToPaths(filesArray), compressedPath, "tar", 128);
File compressedFile = new File(compressedPath);
- GXCompressor.decompress(compressedFile, decompressedPath);
+ GXCompressor.decompress(compressedPath, decompressedPath);
File decompressedDir = new File(decompressedPath);
File[] decompressedFiles = decompressedDir.listFiles();
assertNotNull(decompressedFiles);
@@ -90,9 +98,9 @@ void testCompressionAndDecompressionSEVENZ() throws IOException {
String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.7z";
String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(filesArray, compressedPath, "sevenz", 32);
+ GXCompressor.compress(convertToPaths(filesArray), compressedPath, "sevenz", 32);
File compressedFile = new File(compressedPath);
- GXCompressor.decompress(compressedFile, decompressedPath);
+ GXCompressor.decompress(compressedPath, decompressedPath);
File decompressedDir = new File(decompressedPath);
File[] decompressedFiles = decompressedDir.listFiles();
assertNotNull(decompressedFiles);
@@ -109,23 +117,4 @@ void testCompressionAndDecompressionSEVENZ() throws IOException {
decompressedDir.delete();
}
- @Test
- void testCompressionAndDecompressionGZIP() throws IOException {
- String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.gz";
- String decompressedDirPath = tempDir.getAbsolutePath();
- File singleTestFile = new File(tempDir, "testFile.txt");
- try (FileWriter writer = new FileWriter(singleTestFile)) {
- writer.write("This is a test file");
- }
- GXCompressor.compress(new File[]{singleTestFile}, compressedPath, "gzip", 4);
- File compressedFile = new File(compressedPath);
- assertTrue(compressedFile.exists());
- GXCompressor.decompress(compressedFile, decompressedDirPath);
- File decompressedFile = new File(decompressedDirPath, singleTestFile.getName());
- assertTrue(decompressedFile.exists());
- assertArrayEquals(Files.readAllBytes(singleTestFile.toPath()), Files.readAllBytes(decompressedFile.toPath()));
- compressedFile.delete();
- decompressedFile.delete();
- }
-
}
\ No newline at end of file
From 259af104a2b2c468c86ee03bacdc8a202f21726d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 3 Jun 2024 16:04:18 -0300
Subject: [PATCH 10/49] Various fixes
---
gxcompress/pom.xml | 10 +-
.../com/genexus/compression/Compression.java | 22 +--
.../com/genexus/compression/GXCompressor.java | 29 ++--
.../genexus/compression/IGXCompressor.java | 6 +-
.../genexus/compression/CompressionTest.java | 157 +++++++-----------
5 files changed, 96 insertions(+), 128 deletions(-)
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index 7e19dd4fe..ba0b225ca 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -26,7 +26,7 @@
org.junit.jupiter
junit-jupiter
- RELEASE
+ 5.11.0-M2
test
@@ -37,8 +37,12 @@
org.apache.logging.log4j
log4j-api
- 2.21.1
- compile
+ ${log4j.version}
+
+
+ ${project.groupId}
+ gxcommon
+ ${project.version}
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index e0b4e567e..39fafd45e 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -1,5 +1,6 @@
package com.genexus.compression;
+import com.genexus.GXSimpleCollection;
import org.apache.logging.log4j.Logger;
import java.io.File;
@@ -11,15 +12,13 @@ public class Compression {
private String path;
private String format;
- private int dictionarySize;
private List filesToCompress;
public Compression() {}
- public Compression(String path, String format, int dictionarySize) {
+ public Compression(String path, String format) {
this.path = path;
this.format = format;
- this.dictionarySize = dictionarySize;
this.filesToCompress = new ArrayList<>();
}
@@ -31,10 +30,6 @@ public void setFormat(String format) {
this.format = format;
}
- public void setDictionarySize(int dictionarySize) {
- this.dictionarySize = dictionarySize;
- }
-
public void addFile(File file) {
if (file.exists()) {
filesToCompress.add(file);
@@ -65,14 +60,13 @@ public int save() {
log.error("No files have been added for compression.");
return -3;
}
- File[] filesArray = filesToCompress.toArray(new File[0]);
- String[] paths = new String[filesArray.length];
- for (int i = 0; i < filesArray.length; i++) {
- paths[i] = filesArray[i].getPath();
+ GXSimpleCollection paths = new GXSimpleCollection<>();
+ for (File file : filesToCompress) {
+ paths.add(file.getPath());
}
int compressionResult;
try {
- compressionResult = GXCompressor.compress(paths, path, format, dictionarySize);
+ compressionResult = GXCompressor.compressFiles(paths, path, format);
} catch (IllegalArgumentException e) {
compressionResult = -1;
log.error("Compression failed: {}", e.getMessage());
@@ -80,10 +74,10 @@ public int save() {
return compressionResult;
}
- public void close() {
+
+ public void clear() {
this.path = "";
this.format = "";
- this.dictionarySize = 0;
this.filesToCompress = new ArrayList<>();
}
}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index c7ad95f5a..a244c120f 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -17,6 +17,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Vector;
import java.util.zip.*;
import static org.apache.commons.io.FilenameUtils.getExtension;
@@ -25,16 +26,17 @@ public class GXCompressor implements IGXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
- public static int compress(String[] files, String path, String format, int dictionarySize) {
- File[] toCompress = new File[files.length];
- for (int i = 0; i < files.length; i++) {
- toCompress[i] = new File(files[i]);
+ public static int compressFiles(Vector files, String path, String format) {
+ File[] toCompress = new File[files.size()];
+ int index = 0;
+ for (String filePath : files) {
+ toCompress[index++] = new File(filePath);
}
try {
CompressionFormat compressionFormat = getCompressionFormat(format);
switch (compressionFormat) {
case ZIP:
- compressToZip(toCompress, path, dictionarySize);
+ compressToZip(toCompress, path);
break;
case SEVENZ:
compressToSevenZ(toCompress, path);
@@ -55,23 +57,20 @@ public static int compress(String[] files, String path, String format, int dicti
}
- public static int compress(String folder, String path, String format, int dictionarySize) {
+ public static int compressFolder(String folder, String path, String format) {
File toCompress = new File(folder);
if (!toCompress.exists()) {
log.error("The specified folder does not exist: {}", toCompress.getAbsolutePath());
return -2;
}
- if (!toCompress.isDirectory()) {
- log.error("The specified file is not a directory: {}", toCompress.getAbsolutePath());
- return -2;
- }
- File[] files = new File[] { toCompress };
- return compress(folder, path, format, dictionarySize);
+ Vector vector = new Vector();
+ vector.add(folder);
+ return compressFiles(vector, path, format);
}
- public static Compression newCompression(String path, String format, int dictionarySize) {
- return new Compression(path, format, dictionarySize);
+ public static Compression newCompression(String path, String format) {
+ return new Compression(path, format);
}
@@ -102,7 +101,7 @@ public static int decompress(String file, String path) {
}
}
- private static void compressToZip(File[] files, String outputPath, int dictionarySize) {
+ private static void compressToZip(File[] files, String outputPath) {
try (OutputStream fos = Files.newOutputStream(Paths.get(outputPath));
ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos)) {
zos.setMethod(ZipArchiveOutputStream.DEFLATED);
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index f922a0c0b..21183ae4d 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -1,8 +1,10 @@
package com.genexus.compression;
+import java.util.Vector;
+
public interface IGXCompressor {
- static int compress(String[] files, String path, String format, int dictionarySize) {return 0;}
- static int compress(String folder, String path, String format, int dictionarySize) {return 0;}
+ static int compressFiles(Vector files, String path, String format) {return 0;}
+ static int compressFolder(String folder, String path, String format) {return 0;}
static Compression newCompression(String path, String format, int dictionarySize) { return new Compression();}
static int decompress(String file, String path) {return 0;}
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java b/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
index 64d9a01a8..677447f45 100644
--- a/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
+++ b/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
@@ -1,120 +1,89 @@
package com.genexus.compression;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
import java.io.File;
-import java.io.FileWriter;
import java.io.IOException;
+import java.io.PrintWriter;
import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Vector;
-import static org.junit.jupiter.api.Assertions.*;
+public class CompressionTest {
-class CompressionTest {
- private List tempFiles = new ArrayList<>();
- private File tempDir;
+ private Vector files;
+ private File testDirectory;
- public static String[] convertToPaths(File[] files) {
- String[] paths = new String[files.length];
- for (int i = 0; i < files.length; i++) {
- paths[i] = files[i].getPath();
- }
- return paths;
- }
-
- @BeforeEach
- void setUp() throws IOException {
- tempDir = Files.createTempDirectory("compressionTest").toFile();
+ @Before
+ public void setUp() throws IOException {
+ testDirectory = Files.createTempDirectory("testCompressor").toFile();
+ files = new Vector<>();
+ String content = "This is a sample text to test the compression functionality.";
for (int i = 0; i < 3; i++) {
- File tempFile = new File(tempDir, "testFile" + i + ".txt");
- try (FileWriter writer = new FileWriter(tempFile)) {
- writer.write("This is a test file number " + i);
+ File file = new File(testDirectory, "testFile" + i + ".txt");
+ try (PrintWriter out = new PrintWriter(file)) {
+ out.println(content);
}
- tempFiles.add(tempFile);
+ files.add(file.getAbsolutePath());
}
}
- @AfterEach
- void tearDown() {
- for (File file : tempFiles) {
- file.delete();
+
+ @After
+ public void tearDown() {
+ for (String filePath : files) {
+ new File(filePath).delete();
}
- tempDir.delete();
+ testDirectory.delete();
}
@Test
- void testCompressionAndDecompressionZIP() throws IOException {
- String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.zip";
- String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
- File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(convertToPaths(filesArray), compressedPath, "zip", 4);
- File compressedFile = new File(compressedPath);
- GXCompressor.decompress(compressedPath, decompressedPath);
- File decompressedDir = new File(decompressedPath);
- File[] decompressedFiles = decompressedDir.listFiles();
- assertNotNull(decompressedFiles);
- assertEquals(tempFiles.size(), decompressedFiles.length);
- for (File original : tempFiles) {
- File decompressedFile = new File(decompressedDir, original.getName());
- assertTrue(decompressedFile.exists());
- assertArrayEquals(Files.readAllBytes(original.toPath()), Files.readAllBytes(decompressedFile.toPath()));
- }
- compressedFile.delete();
- for (File file : decompressedFiles) {
- file.delete();
- }
- decompressedDir.delete();
+ public void testCompressToZip() {
+ String outputPath = new File(testDirectory, "output.zip").getAbsolutePath();
+ int result = GXCompressor.compressFiles(files, outputPath, "ZIP");
+ assertEquals(0, result);
+ assertTrue(new File(outputPath).exists());
}
@Test
- void testCompressionAndDecompressionTAR() throws IOException {
- String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.tar";
- String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
- File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(convertToPaths(filesArray), compressedPath, "tar", 128);
- File compressedFile = new File(compressedPath);
- GXCompressor.decompress(compressedPath, decompressedPath);
- File decompressedDir = new File(decompressedPath);
- File[] decompressedFiles = decompressedDir.listFiles();
- assertNotNull(decompressedFiles);
- assertEquals(tempFiles.size(), decompressedFiles.length);
- for (File original : tempFiles) {
- File decompressedFile = new File(decompressedDir, original.getName());
- assertTrue(decompressedFile.exists());
- assertArrayEquals(Files.readAllBytes(original.toPath()), Files.readAllBytes(decompressedFile.toPath()));
- }
- compressedFile.delete();
- for (File file : decompressedFiles) {
- file.delete();
- }
- decompressedDir.delete();
+ public void testCompressToSevenZ() {
+ String outputPath = new File(testDirectory, "output.7z").getAbsolutePath();
+ int result = GXCompressor.compressFiles(files, outputPath, "SEVENZ");
+ assertEquals(0, result);
+ assertTrue(new File(outputPath).exists());
}
@Test
- void testCompressionAndDecompressionSEVENZ() throws IOException {
- String compressedPath = tempDir.getAbsolutePath() + File.separator + "archive.7z";
- String decompressedPath = tempDir.getAbsolutePath() + File.separator + "decompressed";
- File[] filesArray = tempFiles.toArray(new File[0]);
- GXCompressor.compress(convertToPaths(filesArray), compressedPath, "sevenz", 32);
- File compressedFile = new File(compressedPath);
- GXCompressor.decompress(compressedPath, decompressedPath);
- File decompressedDir = new File(decompressedPath);
- File[] decompressedFiles = decompressedDir.listFiles();
- assertNotNull(decompressedFiles);
- assertEquals(tempFiles.size(), decompressedFiles.length);
- for (File original : tempFiles) {
- File decompressedFile = new File(decompressedDir, original.getName());
- assertTrue(decompressedFile.exists());
- assertArrayEquals(Files.readAllBytes(original.toPath()), Files.readAllBytes(decompressedFile.toPath()));
- }
- compressedFile.delete();
- for (File file : decompressedFiles) {
- file.delete();
- }
- decompressedDir.delete();
+ public void testCompressToTar() {
+ String outputPath = new File(testDirectory, "output.tar").getAbsolutePath();
+ int result = GXCompressor.compressFiles(files, outputPath, "TAR");
+ assertEquals(0, result);
+ assertTrue(new File(outputPath).exists());
+ }
+
+ @Test
+ public void testCompressToGzip() {
+ String outputPath = new File(testDirectory, "output.gz").getAbsolutePath();
+ Vector singleFileCollection = new Vector<>();
+ singleFileCollection.add(files.get(0));
+ int result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP");
+ assertEquals(0, result);
+ assertTrue(new File(outputPath).exists());
}
-}
\ No newline at end of file
+ @Test
+ public void testUnsupportedFormat() {
+ String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
+ int result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN");
+ assertEquals(-1, result);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testThrowExceptionForUnsupportedFormat() {
+ String outputPath = new File(testDirectory, "output.unsupported").getAbsolutePath();
+ GXCompressor.compressFiles(files, outputPath, "UNSUPPORTED");
+ }
+}
From f01cb0c5595848e86cadd5edf05a17a459e9f552 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 4 Jun 2024 13:56:52 -0300
Subject: [PATCH 11/49] Change junit version
---
gxcompress/pom.xml | 6 ------
.../java/com/genexus/compression/Compression.java | 13 +++----------
.../java/com/genexus/compression/GXCompressor.java | 6 ++++--
.../{CompressionTest.java => TestCompression.java} | 8 +-------
4 files changed, 8 insertions(+), 25 deletions(-)
rename gxcompress/src/test/java/com/genexus/compression/{CompressionTest.java => TestCompression.java} (89%)
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index ba0b225ca..113e2fe88 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -23,12 +23,6 @@
xz
1.9
-
- org.junit.jupiter
- junit-jupiter
- 5.11.0-M2
- test
-
org.apache.logging.log4j
log4j-core
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 39fafd45e..dc6612088 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -1,11 +1,11 @@
package com.genexus.compression;
-import com.genexus.GXSimpleCollection;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import java.util.Vector;
public class Compression {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Compression.class);
@@ -60,18 +60,11 @@ public int save() {
log.error("No files have been added for compression.");
return -3;
}
- GXSimpleCollection paths = new GXSimpleCollection<>();
+ Vector paths = new Vector<>();
for (File file : filesToCompress) {
paths.add(file.getPath());
}
- int compressionResult;
- try {
- compressionResult = GXCompressor.compressFiles(paths, path, format);
- } catch (IllegalArgumentException e) {
- compressionResult = -1;
- log.error("Compression failed: {}", e.getMessage());
- }
- return compressionResult;
+ return GXCompressor.compressFiles(paths, path, format);
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index a244c120f..bc75846fd 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -48,10 +48,12 @@ public static int compressFiles(Vector files, String path, String format
compressToGzip(toCompress, path);
break;
default:
- throw new IllegalArgumentException("Unsupported compression format: " + format);
+ log.error("Unsupported compression format for compression: {}", format);
+ return -3;
}
return 0;
} catch (Exception e) {
+ log.error("An error occurred during the compression process: ", e);
return -1;
}
}
@@ -63,7 +65,7 @@ public static int compressFolder(String folder, String path, String format) {
log.error("The specified folder does not exist: {}", toCompress.getAbsolutePath());
return -2;
}
- Vector vector = new Vector();
+ Vector vector = new Vector<>();
vector.add(folder);
return compressFiles(vector, path, format);
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
similarity index 89%
rename from gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
rename to gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 677447f45..1d3111357 100644
--- a/gxcompress/src/test/java/com/genexus/compression/CompressionTest.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -12,7 +12,7 @@
import java.nio.file.Files;
import java.util.Vector;
-public class CompressionTest {
+public class TestCompression {
private Vector files;
private File testDirectory;
@@ -80,10 +80,4 @@ public void testUnsupportedFormat() {
int result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN");
assertEquals(-1, result);
}
-
- @Test(expected = IllegalArgumentException.class)
- public void testThrowExceptionForUnsupportedFormat() {
- String outputPath = new File(testDirectory, "output.unsupported").getAbsolutePath();
- GXCompressor.compressFiles(files, outputPath, "UNSUPPORTED");
- }
}
From 88372039ebcdb148b4adea443e0dc635c043b9c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 5 Jun 2024 12:13:24 -0300
Subject: [PATCH 12/49] Fix error codes
---
.../com/genexus/compression/Compression.java | 2 +-
.../com/genexus/compression/GXCompressor.java | 24 +++++++++----------
.../genexus/compression/TestCompression.java | 2 +-
3 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index dc6612088..18e4bc1d4 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -58,7 +58,7 @@ public void addFolder(File folder) {
public int save() {
if (filesToCompress.isEmpty()) {
log.error("No files have been added for compression.");
- return -3;
+ return -4;
}
Vector paths = new Vector<>();
for (File file : filesToCompress) {
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index bc75846fd..87ae74331 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -37,25 +37,25 @@ public static int compressFiles(Vector files, String path, String format
switch (compressionFormat) {
case ZIP:
compressToZip(toCompress, path);
- break;
+ return 0;
case SEVENZ:
compressToSevenZ(toCompress, path);
- break;
+ return 0;
case TAR:
compressToTar(toCompress, path);
- break;
+ return 0;
case GZIP:
compressToGzip(toCompress, path);
- break;
- default:
- log.error("Unsupported compression format for compression: {}", format);
- return -3;
+ return 0;
}
- return 0;
+ } catch (IllegalArgumentException iae) {
+ log.error("Unsupported compression format for compression: {}", format);
+ return -3;
} catch (Exception e) {
log.error("An error occurred during the compression process: ", e);
return -1;
}
+ return -1;
}
@@ -69,13 +69,11 @@ public static int compressFolder(String folder, String path, String format) {
vector.add(folder);
return compressFiles(vector, path, format);
}
-
public static Compression newCompression(String path, String format) {
return new Compression(path, format);
}
-
public static int decompress(String file, String path) {
File toCompress = new File(file);
String extension = getExtension(toCompress.getName());
@@ -97,8 +95,8 @@ public static int decompress(String file, String path) {
log.error("Unsupported compression format for decompression: {}", extension);
return -3;
}
- } catch (IOException ioe) {
- log.error("Decompression failed: {}", ioe.getMessage());
+ } catch (Exception e) {
+ log.error("Decompression failed: {}", e.getMessage());
return -1;
}
}
@@ -355,7 +353,7 @@ private static void decompressGzip(File inputFile, String outputPath) throws IOE
}
}
- public static CompressionFormat getCompressionFormat(String format) {
+ private static CompressionFormat getCompressionFormat(String format) {
try {
return CompressionFormat.valueOf(format.toUpperCase());
} catch (IllegalArgumentException e) {
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 1d3111357..91cc5fc77 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -78,6 +78,6 @@ public void testCompressToGzip() {
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
int result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN");
- assertEquals(-1, result);
+ assertEquals(-3, result);
}
}
From c8c789095c502642f6870d2980aafb5c32a08e3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 5 Jun 2024 12:17:51 -0300
Subject: [PATCH 13/49] Correct parameters data types
---
.../main/java/com/genexus/compression/Compression.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 18e4bc1d4..b8f4ea7d6 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -30,7 +30,8 @@ public void setFormat(String format) {
this.format = format;
}
- public void addFile(File file) {
+ public void addFile(String filePath) {
+ File file = new File(filePath);
if (file.exists()) {
filesToCompress.add(file);
} else {
@@ -38,15 +39,16 @@ public void addFile(File file) {
}
}
- public void addFolder(File folder) {
+ public void addFolder(String folderPath) {
+ File folder = new File(folderPath);
if (folder.exists() && folder.isDirectory()) {
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
- addFolder(file);
+ addFolder(file.getAbsolutePath());
} else {
- addFile(file);
+ addFile(file.getAbsolutePath());
}
}
}
From defaeea9620ca11b9755d22f899fa83e8a69a434 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 5 Jun 2024 14:22:40 -0300
Subject: [PATCH 14/49] Expand error codes
---
.../java/com/genexus/compression/GXCompressor.java | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 87ae74331..bf3890562 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -27,6 +27,10 @@ public class GXCompressor implements IGXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
public static int compressFiles(Vector files, String path, String format) {
+ if (files.isEmpty()){
+ log.error("No files have been added for compression.");
+ return -4;
+ }
File[] toCompress = new File[files.size()];
int index = 0;
for (String filePath : files) {
@@ -76,6 +80,14 @@ public static Compression newCompression(String path, String format) {
public static int decompress(String file, String path) {
File toCompress = new File(file);
+ if (!toCompress.exists()) {
+ log.error("The specified archive does not exist: {}", toCompress.getAbsolutePath());
+ return -2;
+ }
+ if (toCompress.length() == 0L){
+ log.error("The archive located at {} is empty", path);
+ return -4;
+ }
String extension = getExtension(toCompress.getName());
try {
switch (extension.toLowerCase()) {
From 009afc372bcd26ae4e603e337605a7a309caf260 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 5 Jun 2024 14:46:22 -0300
Subject: [PATCH 15/49] Better logging
---
.../src/main/java/com/genexus/compression/GXCompressor.java | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index bf3890562..f6850e78b 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -123,6 +123,7 @@ private static void compressToZip(File[] files, String outputPath) {
}
}
} catch (IOException e) {
+ log.error("Error while compressing to zip", e);
throw new RuntimeException("Failed to compress files", e);
}
}
@@ -157,6 +158,7 @@ private static void compressToSevenZ(File[] files, String outputPath) throws Run
addToSevenZArchive(sevenZOutput, file, "");
}
} catch (IOException e) {
+ log.error("Error while compressing to 7z", e);
throw new RuntimeException("Error creating 7z archive", e);
}
}
@@ -196,6 +198,7 @@ private static void compressToTar(File[] files, String outputPath) throws Runtim
}
taos.finish();
} catch (IOException e) {
+ log.error("Error while compressing to tar", e);
throw new RuntimeException("Error creating TAR archive", e);
}
}
@@ -240,6 +243,7 @@ private static void compressToGzip(File[] files, String outputPath) throws Runti
gzOut.write(buffer, 0, n);
}
} catch (IOException e) {
+ log.error("Error while compressing to gzip", e);
throw new RuntimeException("Error compressing file with GZIP", e);
}
}
@@ -278,6 +282,7 @@ private static void decompressZip(File zipFile, String directory) throws Runtime
zipIn.closeEntry();
}
} catch (IOException e) {
+ log.error("Error while decompressing to zip", e);
throw new RuntimeException("Failed to decompress ZIP file: " + zipFilePath, e);
}
}
From 2d1783e79ace06d87cba25692367ed408a67be42 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 10 Jun 2024 15:13:00 -0300
Subject: [PATCH 16/49] Remove unnecesary usage of List
---
.../com/genexus/compression/Compression.java | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index b8f4ea7d6..4285d31a4 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -12,14 +12,14 @@ public class Compression {
private String path;
private String format;
- private List filesToCompress;
+ private Vector filesToCompress;
public Compression() {}
public Compression(String path, String format) {
this.path = path;
this.format = format;
- this.filesToCompress = new ArrayList<>();
+ this.filesToCompress = new Vector<>();
}
public void setPath(String path) {
@@ -31,11 +31,10 @@ public void setFormat(String format) {
}
public void addFile(String filePath) {
- File file = new File(filePath);
- if (file.exists()) {
- filesToCompress.add(file);
+ if (new File(filePath).exists()) {
+ filesToCompress.add(filePath);
} else {
- log.error("File does not exist: {}", file.getAbsolutePath());
+ log.error("File does not exist: {}", filePath);
}
}
@@ -62,17 +61,13 @@ public int save() {
log.error("No files have been added for compression.");
return -4;
}
- Vector paths = new Vector<>();
- for (File file : filesToCompress) {
- paths.add(file.getPath());
- }
- return GXCompressor.compressFiles(paths, path, format);
+ return GXCompressor.compressFiles(filesToCompress, path, format);
}
public void clear() {
this.path = "";
this.format = "";
- this.filesToCompress = new ArrayList<>();
+ this.filesToCompress = new Vector<>();
}
}
\ No newline at end of file
From bab7cce95f677822e97dcd27a572bdee50acec0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 10 Jun 2024 16:41:38 -0300
Subject: [PATCH 17/49] Add jar support
---
.../compression/CompressionFormat.java | 2 +-
.../com/genexus/compression/GXCompressor.java | 63 +++++++++++++++++--
.../genexus/compression/TestCompression.java | 8 +++
3 files changed, 66 insertions(+), 7 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java b/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
index 4192b3c65..dce8ce7b2 100644
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
@@ -1,5 +1,5 @@
package com.genexus.compression;
public enum CompressionFormat {
- GZIP,TAR, ZIP, SEVENZ
+ GZIP,TAR, ZIP, SEVENZ, JAR
}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index f6850e78b..07a924b69 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -18,6 +18,9 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
import java.util.zip.*;
import static org.apache.commons.io.FilenameUtils.getExtension;
@@ -51,6 +54,9 @@ public static int compressFiles(Vector files, String path, String format
case GZIP:
compressToGzip(toCompress, path);
return 0;
+ case JAR:
+ compressToJar(toCompress, path);
+ return 0;
}
} catch (IllegalArgumentException iae) {
log.error("Unsupported compression format for compression: {}", format);
@@ -103,6 +109,9 @@ public static int decompress(String file, String path) {
case "gz":
decompressGzip(toCompress, path);
return 0;
+ case "jar":
+ decompressJar(toCompress, path);
+ return 0;
default:
log.error("Unsupported compression format for decompression: {}", extension);
return -3;
@@ -329,12 +338,8 @@ private static void decompressTar(File file, String outputPath) throws IOExcepti
if (!outputFile.toPath().startsWith(targetDir)) {
throw new IOException("Entry is outside of the target directory: " + entry.getName());
}
- if (entry.isDirectory()) {
- if (!outputFile.exists()) {
- if (!outputFile.mkdirs()) {
- throw new IOException("Failed to create directory: " + outputFile);
- }
- }
+ if (entry.isDirectory() && !outputFile.exists() && !outputFile.mkdirs()) {
+ throw new IOException("Failed to create directory: " + outputFile);
} else {
File parent = outputFile.getParentFile();
if (!parent.exists() && !parent.mkdirs()) {
@@ -370,6 +375,52 @@ private static void decompressGzip(File inputFile, String outputPath) throws IOE
}
}
+ private static void compressToJar(File[] files, String outputPath) throws IOException {
+ JarOutputStream jos = new JarOutputStream(Files.newOutputStream(Paths.get(outputPath)));
+ byte[] buffer = new byte[1024];
+ for (File file : files) {
+ FileInputStream fis = new FileInputStream(file);
+ jos.putNextEntry(new JarEntry(file.getName()));
+ int length;
+ while ((length = fis.read(buffer)) > 0) {
+ jos.write(buffer, 0, length);
+ }
+ fis.close();
+ jos.closeEntry();
+ }
+ jos.close();
+ }
+
+ public static void decompressJar(File jarFile, String outputPath) throws IOException {
+ if (!jarFile.exists()) {
+ throw new IOException("The jar file does not exist.");
+ }
+ File outputDir = new File(outputPath);
+ if (!outputDir.exists() && !outputDir.mkdirs()) {
+ throw new IOException("Failed to create output directory.");
+ }
+ try (JarInputStream jis = new JarInputStream(Files.newInputStream(jarFile.toPath()))) {
+ JarEntry entry;
+ byte[] buffer = new byte[1024];
+ while ((entry = jis.getNextJarEntry()) != null) {
+ File outputFile = new File(outputDir, entry.getName());
+ if (entry.isDirectory()) {
+ if (!outputFile.exists() && !outputFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + outputFile.getAbsolutePath());
+ }
+ } else {
+ try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+ int len;
+ while ((len = jis.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ }
+ }
+ }
+ jis.closeEntry();
+ }
+ }
+ }
+
private static CompressionFormat getCompressionFormat(String format) {
try {
return CompressionFormat.valueOf(format.toUpperCase());
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 91cc5fc77..9cd2a61e7 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -74,6 +74,14 @@ public void testCompressToGzip() {
assertTrue(new File(outputPath).exists());
}
+ @Test
+ public void testCompressToJar() {
+ String outputPath = new File(testDirectory, "output.jar").getAbsolutePath();
+ int result = GXCompressor.compressFiles(files, outputPath, "JAR");
+ assertEquals(0, result);
+ assertTrue(new File(outputPath).exists());
+ }
+
@Test
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
From b6eb9f5ee9f803d2aed1b9b432b2b95b249f18ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 10 Jun 2024 17:02:52 -0300
Subject: [PATCH 18/49] Add support for decompressing rar files
---
gxcompress/pom.xml | 5 +++++
.../main/java/com/genexus/compression/GXCompressor.java | 9 +++++++++
2 files changed, 14 insertions(+)
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index 113e2fe88..c162122d4 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -23,6 +23,11 @@
xz
1.9
+
+ com.github.junrar
+ junrar
+ 7.5.5
+
org.apache.logging.log4j
log4j-core
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 07a924b69..0831c9280 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -12,6 +12,8 @@
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.commons.io.IOUtils;
+import com.github.junrar.Junrar;
+import com.github.junrar.exception.RarException;
import java.io.*;
import java.nio.file.Files;
@@ -112,6 +114,9 @@ public static int decompress(String file, String path) {
case "jar":
decompressJar(toCompress, path);
return 0;
+ case "rar":
+ decompressRar(toCompress, path);
+ return 0;
default:
log.error("Unsupported compression format for decompression: {}", extension);
return -3;
@@ -421,6 +426,10 @@ public static void decompressJar(File jarFile, String outputPath) throws IOExcep
}
}
+ public static void decompressRar(File rarFile, String destinationPath) throws RarException, IOException{
+ Junrar.extract(rarFile, new File(destinationPath));
+ }
+
private static CompressionFormat getCompressionFormat(String format) {
try {
return CompressionFormat.valueOf(format.toUpperCase());
From 39180c2d337b79240fa03c3008184ec3c95955eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 10 Jun 2024 17:41:25 -0300
Subject: [PATCH 19/49] Remove unused imports
---
.../src/main/java/com/genexus/compression/Compression.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 4285d31a4..750d25d7c 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -3,8 +3,6 @@
import org.apache.logging.log4j.Logger;
import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Vector;
public class Compression {
@@ -70,4 +68,4 @@ public void clear() {
this.format = "";
this.filesToCompress = new Vector<>();
}
-}
\ No newline at end of file
+}
From 5f5233e330c368adcc763984796c6a143f51cfcc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 10 Jun 2024 17:43:54 -0300
Subject: [PATCH 20/49] Merge nested ifs
---
.../src/main/java/com/genexus/compression/GXCompressor.java | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 0831c9280..0458d8abc 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -409,10 +409,8 @@ public static void decompressJar(File jarFile, String outputPath) throws IOExcep
byte[] buffer = new byte[1024];
while ((entry = jis.getNextJarEntry()) != null) {
File outputFile = new File(outputDir, entry.getName());
- if (entry.isDirectory()) {
- if (!outputFile.exists() && !outputFile.mkdirs()) {
- throw new IOException("Failed to create directory " + outputFile.getAbsolutePath());
- }
+ if (entry.isDirectory() && !outputFile.exists() && !outputFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + outputFile.getAbsolutePath());
} else {
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
int len;
From 825fdc181c90e347772c880340aa68140c24d0f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 15 Jul 2024 12:07:24 -0300
Subject: [PATCH 21/49] Change operations return type
---
.../com/genexus/compression/Compression.java | 4 +-
.../compression/CompressionMessage.java | 27 ++++++++++
.../com/genexus/compression/GXCompressor.java | 53 ++++++++++---------
.../genexus/compression/IGXCompressor.java | 6 +--
.../genexus/compression/TestCompression.java | 29 +++++-----
5 files changed, 74 insertions(+), 45 deletions(-)
create mode 100644 gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 750d25d7c..0c29fec0f 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -54,10 +54,10 @@ public void addFolder(String folderPath) {
}
}
- public int save() {
+ public CompressionMessage save() {
if (filesToCompress.isEmpty()) {
log.error("No files have been added for compression.");
- return -4;
+ return new CompressionMessage(false, "No files have been added for compression.");
}
return GXCompressor.compressFiles(filesToCompress, path, format);
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java b/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
new file mode 100644
index 000000000..6ce153774
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
@@ -0,0 +1,27 @@
+package com.genexus.compression;
+
+public class CompressionMessage {
+ private boolean successfulCompression;
+ private String message;
+
+ public CompressionMessage(boolean successfulCompression, String message) {
+ this.successfulCompression = successfulCompression;
+ this.message = message;
+ }
+
+ public boolean isSuccessfulCompression() {
+ return successfulCompression;
+ }
+
+ public void setSuccessfulCompression(boolean successfulCompression) {
+ this.successfulCompression = successfulCompression;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 0458d8abc..d0fe9a55a 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -31,10 +31,10 @@ public class GXCompressor implements IGXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
- public static int compressFiles(Vector files, String path, String format) {
+ public static CompressionMessage compressFiles(Vector files, String path, String format) {
if (files.isEmpty()){
log.error("No files have been added for compression.");
- return -4;
+ return new CompressionMessage(false, "No files have been added for compression.");
}
File[] toCompress = new File[files.size()];
int index = 0;
@@ -46,36 +46,35 @@ public static int compressFiles(Vector files, String path, String format
switch (compressionFormat) {
case ZIP:
compressToZip(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case SEVENZ:
compressToSevenZ(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case TAR:
compressToTar(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case GZIP:
compressToGzip(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case JAR:
compressToJar(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
}
} catch (IllegalArgumentException iae) {
log.error("Unsupported compression format for compression: {}", format);
- return -3;
+ return new CompressionMessage(false, "Unsupported compression format for compression: " + format);
} catch (Exception e) {
log.error("An error occurred during the compression process: ", e);
- return -1;
+ return new CompressionMessage(false, "An error occurred during the compression process");
}
- return -1;
+ return new CompressionMessage(false, "An error occurred during the compression process");
}
-
- public static int compressFolder(String folder, String path, String format) {
+ public static CompressionMessage compressFolder(String folder, String path, String format) {
File toCompress = new File(folder);
if (!toCompress.exists()) {
log.error("The specified folder does not exist: {}", toCompress.getAbsolutePath());
- return -2;
+ return new CompressionMessage(false, "The specified folder does not exist: " + folder);
}
Vector vector = new Vector<>();
vector.add(folder);
@@ -86,47 +85,51 @@ public static Compression newCompression(String path, String format) {
return new Compression(path, format);
}
- public static int decompress(String file, String path) {
+ public static CompressionMessage decompress(String file, String path) {
File toCompress = new File(file);
if (!toCompress.exists()) {
log.error("The specified archive does not exist: {}", toCompress.getAbsolutePath());
- return -2;
+ return new CompressionMessage(false, "The specified archive does not exist: " + file);
}
if (toCompress.length() == 0L){
- log.error("The archive located at {} is empty", path);
- return -4;
+ log.error("The archive located at {} is empty", file);
+ return new CompressionMessage(false, "The archive located at " + file + " is empty");
}
String extension = getExtension(toCompress.getName());
try {
switch (extension.toLowerCase()) {
case "zip":
decompressZip(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case "7z":
decompress7z(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case "tar":
decompressTar(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case "gz":
decompressGzip(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case "jar":
decompressJar(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
case "rar":
decompressRar(toCompress, path);
- return 0;
+ return getSuccessfulCompressionMessage();
default:
log.error("Unsupported compression format for decompression: {}", extension);
- return -3;
+ return new CompressionMessage(false, "Unsupported compression format for decompression");
}
} catch (Exception e) {
log.error("Decompression failed: {}", e.getMessage());
- return -1;
+ return new CompressionMessage(false, "Decompression failed");
}
}
+ private static CompressionMessage getSuccessfulCompressionMessage(){
+ return new CompressionMessage(true, "The operation was successful");
+ }
+
private static void compressToZip(File[] files, String outputPath) {
try (OutputStream fos = Files.newOutputStream(Paths.get(outputPath));
ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos)) {
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index 21183ae4d..ea0bf4432 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -3,8 +3,8 @@
import java.util.Vector;
public interface IGXCompressor {
- static int compressFiles(Vector files, String path, String format) {return 0;}
- static int compressFolder(String folder, String path, String format) {return 0;}
+ static CompressionMessage compressFiles(Vector files, String path, String format) {return null;}
+ static CompressionMessage compressFolder(String folder, String path, String format) {return null;}
static Compression newCompression(String path, String format, int dictionarySize) { return new Compression();}
- static int decompress(String file, String path) {return 0;}
+ static CompressionMessage decompress(String file, String path) {return null;}
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 9cd2a61e7..b1b622081 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -1,8 +1,5 @@
package com.genexus.compression;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -12,6 +9,8 @@
import java.nio.file.Files;
import java.util.Vector;
+import static org.junit.Assert.*;
+
public class TestCompression {
private Vector files;
@@ -43,24 +42,24 @@ public void tearDown() {
@Test
public void testCompressToZip() {
String outputPath = new File(testDirectory, "output.zip").getAbsolutePath();
- int result = GXCompressor.compressFiles(files, outputPath, "ZIP");
- assertEquals(0, result);
+ CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "ZIP");
+ assertTrue(result.isSuccessfulCompression());
assertTrue(new File(outputPath).exists());
}
@Test
public void testCompressToSevenZ() {
String outputPath = new File(testDirectory, "output.7z").getAbsolutePath();
- int result = GXCompressor.compressFiles(files, outputPath, "SEVENZ");
- assertEquals(0, result);
+ CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "SEVENZ");
+ assertTrue(result.isSuccessfulCompression());
assertTrue(new File(outputPath).exists());
}
@Test
public void testCompressToTar() {
String outputPath = new File(testDirectory, "output.tar").getAbsolutePath();
- int result = GXCompressor.compressFiles(files, outputPath, "TAR");
- assertEquals(0, result);
+ CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "TAR");
+ assertTrue(result.isSuccessfulCompression());
assertTrue(new File(outputPath).exists());
}
@@ -69,23 +68,23 @@ public void testCompressToGzip() {
String outputPath = new File(testDirectory, "output.gz").getAbsolutePath();
Vector singleFileCollection = new Vector<>();
singleFileCollection.add(files.get(0));
- int result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP");
- assertEquals(0, result);
+ CompressionMessage result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP");
+ assertTrue(result.isSuccessfulCompression());
assertTrue(new File(outputPath).exists());
}
@Test
public void testCompressToJar() {
String outputPath = new File(testDirectory, "output.jar").getAbsolutePath();
- int result = GXCompressor.compressFiles(files, outputPath, "JAR");
- assertEquals(0, result);
+ CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "JAR");
+ assertTrue(result.isSuccessfulCompression());
assertTrue(new File(outputPath).exists());
}
@Test
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
- int result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN");
- assertEquals(-3, result);
+ CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN");
+ assertFalse(result.isSuccessfulCompression());
}
}
From 1bdab8598780be8afecd18d55bc5abd879ff12b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 15 Jul 2024 14:52:28 -0300
Subject: [PATCH 22/49] Fix method naming and logging
---
.../genexus/compression/CompressionMessage.java | 14 +++++++-------
.../java/com/genexus/compression/GXCompressor.java | 4 ++--
.../com/genexus/compression/TestCompression.java | 13 ++++++-------
3 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java b/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
index 6ce153774..d7ed6a1f2 100644
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
@@ -1,20 +1,20 @@
package com.genexus.compression;
public class CompressionMessage {
- private boolean successfulCompression;
+ private boolean successfulOperation;
private String message;
- public CompressionMessage(boolean successfulCompression, String message) {
- this.successfulCompression = successfulCompression;
+ public CompressionMessage(boolean successfulOperation, String message) {
+ this.successfulOperation = successfulOperation;
this.message = message;
}
- public boolean isSuccessfulCompression() {
- return successfulCompression;
+ public boolean isSuccessfulOperation() {
+ return successfulOperation;
}
- public void setSuccessfulCompression(boolean successfulCompression) {
- this.successfulCompression = successfulCompression;
+ public void setSuccessfulCompression(boolean successfulOperation) {
+ this.successfulOperation = successfulOperation;
}
public String getMessage() {
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index d0fe9a55a..84e2d0321 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -61,7 +61,7 @@ public static CompressionMessage compressFiles(Vector files, String path
return getSuccessfulCompressionMessage();
}
} catch (IllegalArgumentException iae) {
- log.error("Unsupported compression format for compression: {}", format);
+ log.error("Unsupported compression format for compression: {}", format, iae);
return new CompressionMessage(false, "Unsupported compression format for compression: " + format);
} catch (Exception e) {
log.error("An error occurred during the compression process: ", e);
@@ -121,7 +121,7 @@ public static CompressionMessage decompress(String file, String path) {
return new CompressionMessage(false, "Unsupported compression format for decompression");
}
} catch (Exception e) {
- log.error("Decompression failed: {}", e.getMessage());
+ log.error("Decompression failed: ", e);
return new CompressionMessage(false, "Decompression failed");
}
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index b1b622081..5e444a27c 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -30,7 +30,6 @@ public void setUp() throws IOException {
}
}
-
@After
public void tearDown() {
for (String filePath : files) {
@@ -43,7 +42,7 @@ public void tearDown() {
public void testCompressToZip() {
String outputPath = new File(testDirectory, "output.zip").getAbsolutePath();
CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "ZIP");
- assertTrue(result.isSuccessfulCompression());
+ assertTrue(result.isSuccessfulOperation());
assertTrue(new File(outputPath).exists());
}
@@ -51,7 +50,7 @@ public void testCompressToZip() {
public void testCompressToSevenZ() {
String outputPath = new File(testDirectory, "output.7z").getAbsolutePath();
CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "SEVENZ");
- assertTrue(result.isSuccessfulCompression());
+ assertTrue(result.isSuccessfulOperation());
assertTrue(new File(outputPath).exists());
}
@@ -59,7 +58,7 @@ public void testCompressToSevenZ() {
public void testCompressToTar() {
String outputPath = new File(testDirectory, "output.tar").getAbsolutePath();
CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "TAR");
- assertTrue(result.isSuccessfulCompression());
+ assertTrue(result.isSuccessfulOperation());
assertTrue(new File(outputPath).exists());
}
@@ -69,7 +68,7 @@ public void testCompressToGzip() {
Vector singleFileCollection = new Vector<>();
singleFileCollection.add(files.get(0));
CompressionMessage result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP");
- assertTrue(result.isSuccessfulCompression());
+ assertTrue(result.isSuccessfulOperation());
assertTrue(new File(outputPath).exists());
}
@@ -77,7 +76,7 @@ public void testCompressToGzip() {
public void testCompressToJar() {
String outputPath = new File(testDirectory, "output.jar").getAbsolutePath();
CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "JAR");
- assertTrue(result.isSuccessfulCompression());
+ assertTrue(result.isSuccessfulOperation());
assertTrue(new File(outputPath).exists());
}
@@ -85,6 +84,6 @@ public void testCompressToJar() {
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN");
- assertFalse(result.isSuccessfulCompression());
+ assertFalse(result.isSuccessfulOperation());
}
}
From 6de7f6d995f6e20d080b49e9e8b079a1002284e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 15 Jul 2024 15:06:08 -0300
Subject: [PATCH 23/49] Make attributes readonly
---
.../com/genexus/compression/CompressionMessage.java | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java b/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
index d7ed6a1f2..4ed12aa9a 100644
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
@@ -1,8 +1,8 @@
package com.genexus.compression;
public class CompressionMessage {
- private boolean successfulOperation;
- private String message;
+ private final boolean successfulOperation;
+ private final String message;
public CompressionMessage(boolean successfulOperation, String message) {
this.successfulOperation = successfulOperation;
@@ -13,15 +13,7 @@ public boolean isSuccessfulOperation() {
return successfulOperation;
}
- public void setSuccessfulCompression(boolean successfulOperation) {
- this.successfulOperation = successfulOperation;
- }
-
public String getMessage() {
return message;
}
-
- public void setMessage(String message) {
- this.message = message;
- }
}
\ No newline at end of file
From f458aaa2a8e1639f06a8c16dd03e743117f68398 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 16 Jul 2024 10:52:10 -0300
Subject: [PATCH 24/49] Refactor compression classes to support error messages
---
.../com/genexus/compression/Compression.java | 26 +++++--
.../compression/CompressionMessage.java | 19 -----
.../com/genexus/compression/GXCompressor.java | 77 +++++++++++--------
.../genexus/compression/IGXCompressor.java | 10 ++-
.../genexus/compression/TestCompression.java | 24 +++---
5 files changed, 83 insertions(+), 73 deletions(-)
delete mode 100644 gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 0c29fec0f..73f430045 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -1,5 +1,8 @@
package com.genexus.compression;
+import com.genexus.GXBaseCollection;
+import com.genexus.SdtMessages_Message;
+import com.genexus.StructSdtMessages_Message;
import org.apache.logging.log4j.Logger;
import java.io.File;
@@ -10,13 +13,15 @@ public class Compression {
private String path;
private String format;
+ private GXBaseCollection[] messages;
private Vector filesToCompress;
public Compression() {}
- public Compression(String path, String format) {
+ public Compression(String path, String format, GXBaseCollection[] messages) {
this.path = path;
this.format = format;
+ this.messages = messages;
this.filesToCompress = new Vector<>();
}
@@ -33,6 +38,7 @@ public void addFile(String filePath) {
filesToCompress.add(filePath);
} else {
log.error("File does not exist: {}", filePath);
+ if (messages != null) storageMessages("File does not exist: " + filePath, messages[0]);
}
}
@@ -51,21 +57,25 @@ public void addFolder(String folderPath) {
}
} else {
log.error("Folder does not exist or is not a directory: {}", folder.getAbsolutePath());
+ if (messages != null) storageMessages("Folder does not exist or is not a directory: " + folder.getAbsolutePath(), messages[0]);
}
}
- public CompressionMessage save() {
- if (filesToCompress.isEmpty()) {
- log.error("No files have been added for compression.");
- return new CompressionMessage(false, "No files have been added for compression.");
- }
- return GXCompressor.compressFiles(filesToCompress, path, format);
+ public Boolean save() {
+ return GXCompressor.compressFiles(filesToCompress, path, format, this.messages);
}
-
public void clear() {
this.path = "";
this.format = "";
this.filesToCompress = new Vector<>();
}
+
+ private static void storageMessages(String error, GXBaseCollection messages) {
+ StructSdtMessages_Message struct = new StructSdtMessages_Message();
+ struct.setDescription(error);
+ struct.setType((byte) 1);
+ SdtMessages_Message msg = new SdtMessages_Message(struct);
+ messages.add(msg);
+ }
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java b/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
deleted file mode 100644
index 4ed12aa9a..000000000
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionMessage.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.genexus.compression;
-
-public class CompressionMessage {
- private final boolean successfulOperation;
- private final String message;
-
- public CompressionMessage(boolean successfulOperation, String message) {
- this.successfulOperation = successfulOperation;
- this.message = message;
- }
-
- public boolean isSuccessfulOperation() {
- return successfulOperation;
- }
-
- public String getMessage() {
- return message;
- }
-}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 84e2d0321..e6c4cee62 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -1,5 +1,8 @@
package com.genexus.compression;
+import com.genexus.GXBaseCollection;
+import com.genexus.SdtMessages_Message;
+import com.genexus.StructSdtMessages_Message;
import org.apache.logging.log4j.Logger;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
@@ -30,11 +33,23 @@
public class GXCompressor implements IGXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
+
+ private static void storageMessages(Exception ex, String error, GXBaseCollection messages) {
+ StructSdtMessages_Message struct = new StructSdtMessages_Message();
+ if (ex != null)
+ struct.setDescription(ex.getMessage());
+ else
+ struct.setDescription(error);
+ struct.setType((byte) 1);
+ SdtMessages_Message msg = new SdtMessages_Message(struct);
+ messages.add(msg);
+ }
- public static CompressionMessage compressFiles(Vector files, String path, String format) {
+ public static Boolean compressFiles(Vector files, String path, String format, GXBaseCollection[] messages) {
if (files.isEmpty()){
log.error("No files have been added for compression.");
- return new CompressionMessage(false, "No files have been added for compression.");
+ if (messages != null) storageMessages(null, "No files have been added for compression.", messages[0]);
+ return false;
}
File[] toCompress = new File[files.size()];
int index = 0;
@@ -46,90 +61,92 @@ public static CompressionMessage compressFiles(Vector files, String path
switch (compressionFormat) {
case ZIP:
compressToZip(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case SEVENZ:
compressToSevenZ(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case TAR:
compressToTar(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case GZIP:
compressToGzip(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case JAR:
compressToJar(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
}
} catch (IllegalArgumentException iae) {
log.error("Unsupported compression format for compression: {}", format, iae);
- return new CompressionMessage(false, "Unsupported compression format for compression: " + format);
+ if (messages != null) storageMessages(null, "Unsupported compression format for compression: " + format, messages[0]);
+ return false;
} catch (Exception e) {
log.error("An error occurred during the compression process: ", e);
- return new CompressionMessage(false, "An error occurred during the compression process");
+ return false;
}
- return new CompressionMessage(false, "An error occurred during the compression process");
+ return false;
}
- public static CompressionMessage compressFolder(String folder, String path, String format) {
+ public static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {
File toCompress = new File(folder);
if (!toCompress.exists()) {
log.error("The specified folder does not exist: {}", toCompress.getAbsolutePath());
- return new CompressionMessage(false, "The specified folder does not exist: " + folder);
+ if (messages != null) storageMessages(null, "The specified folder does not exist: " + toCompress.getAbsolutePath(), messages[0]);
+ return false;
}
Vector vector = new Vector<>();
vector.add(folder);
- return compressFiles(vector, path, format);
+ return compressFiles(vector, path, format, messages);
}
- public static Compression newCompression(String path, String format) {
- return new Compression(path, format);
+ public static Compression newCompression(String path, String format, GXBaseCollection[] messages) {
+ return new Compression(path, format, messages);
}
- public static CompressionMessage decompress(String file, String path) {
+ public static Boolean decompress(String file, String path, GXBaseCollection[] messages) {
File toCompress = new File(file);
if (!toCompress.exists()) {
log.error("The specified archive does not exist: {}", toCompress.getAbsolutePath());
- return new CompressionMessage(false, "The specified archive does not exist: " + file);
+ if (messages != null) storageMessages(null, "The specified archive does not exist: " + toCompress.getAbsolutePath(), messages[0]);
+ return false;
}
if (toCompress.length() == 0L){
log.error("The archive located at {} is empty", file);
- return new CompressionMessage(false, "The archive located at " + file + " is empty");
+ if (messages != null) storageMessages(null, "The archive located at " + toCompress.getAbsolutePath() + " is empty", messages[0]);
+ return false;
}
String extension = getExtension(toCompress.getName());
try {
switch (extension.toLowerCase()) {
case "zip":
decompressZip(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case "7z":
decompress7z(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case "tar":
decompressTar(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case "gz":
decompressGzip(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case "jar":
decompressJar(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
case "rar":
decompressRar(toCompress, path);
- return getSuccessfulCompressionMessage();
+ return true;
default:
log.error("Unsupported compression format for decompression: {}", extension);
- return new CompressionMessage(false, "Unsupported compression format for decompression");
+ if (messages != null) storageMessages(null, "Unsupported compression format for decompression: " + extension, messages[0]);
+ return false;
}
} catch (Exception e) {
log.error("Decompression failed: ", e);
- return new CompressionMessage(false, "Decompression failed");
+ if (messages != null) storageMessages(e, null, messages[0]);
+ return false;
}
}
- private static CompressionMessage getSuccessfulCompressionMessage(){
- return new CompressionMessage(true, "The operation was successful");
- }
-
private static void compressToZip(File[] files, String outputPath) {
try (OutputStream fos = Files.newOutputStream(Paths.get(outputPath));
ZipArchiveOutputStream zos = new ZipArchiveOutputStream(fos)) {
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index ea0bf4432..f9e47fb86 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -1,10 +1,12 @@
package com.genexus.compression;
+import com.genexus.GXBaseCollection;
+import com.genexus.SdtMessages_Message;
import java.util.Vector;
public interface IGXCompressor {
- static CompressionMessage compressFiles(Vector files, String path, String format) {return null;}
- static CompressionMessage compressFolder(String folder, String path, String format) {return null;}
- static Compression newCompression(String path, String format, int dictionarySize) { return new Compression();}
- static CompressionMessage decompress(String file, String path) {return null;}
+ static Boolean compressFiles(Vector files, String path, String format, GXBaseCollection[] messages) {return null;}
+ static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {return null;}
+ static Compression newCompression(String path, String format, int dictionarySize, GXBaseCollection[] messages) { return new Compression();}
+ static Boolean decompress(String file, String path, GXBaseCollection[] messages) {return null;}
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 5e444a27c..ab224c40e 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -41,24 +41,24 @@ public void tearDown() {
@Test
public void testCompressToZip() {
String outputPath = new File(testDirectory, "output.zip").getAbsolutePath();
- CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "ZIP");
- assertTrue(result.isSuccessfulOperation());
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "ZIP", null);
+ assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@Test
public void testCompressToSevenZ() {
String outputPath = new File(testDirectory, "output.7z").getAbsolutePath();
- CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "SEVENZ");
- assertTrue(result.isSuccessfulOperation());
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "SEVENZ", null);
+ assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@Test
public void testCompressToTar() {
String outputPath = new File(testDirectory, "output.tar").getAbsolutePath();
- CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "TAR");
- assertTrue(result.isSuccessfulOperation());
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "TAR", null);
+ assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -67,23 +67,23 @@ public void testCompressToGzip() {
String outputPath = new File(testDirectory, "output.gz").getAbsolutePath();
Vector singleFileCollection = new Vector<>();
singleFileCollection.add(files.get(0));
- CompressionMessage result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP");
- assertTrue(result.isSuccessfulOperation());
+ Boolean result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP", null);
+ assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@Test
public void testCompressToJar() {
String outputPath = new File(testDirectory, "output.jar").getAbsolutePath();
- CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "JAR");
- assertTrue(result.isSuccessfulOperation());
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "JAR", null);
+ assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@Test
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
- CompressionMessage result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN");
- assertFalse(result.isSuccessfulOperation());
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN", null);
+ assertFalse(result);
}
}
From 7df792c26e1e4ffa2e6c54f648afa6dc9d1cd178 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 16 Jul 2024 11:51:36 -0300
Subject: [PATCH 25/49] Add missing message and fix interface return type
---
.../src/main/java/com/genexus/compression/GXCompressor.java | 1 +
.../main/java/com/genexus/compression/IGXCompressor.java | 6 +++---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index e6c4cee62..637c0ff27 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -81,6 +81,7 @@ public static Boolean compressFiles(Vector files, String path, String fo
return false;
} catch (Exception e) {
log.error("An error occurred during the compression process: ", e);
+ if (messages != null) storageMessages(e, null, messages[0]);
return false;
}
return false;
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index f9e47fb86..0e392c714 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -5,8 +5,8 @@
import java.util.Vector;
public interface IGXCompressor {
- static Boolean compressFiles(Vector files, String path, String format, GXBaseCollection[] messages) {return null;}
- static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {return null;}
+ static Boolean compressFiles(Vector files, String path, String format, GXBaseCollection[] messages) {return false;}
+ static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {return false;}
static Compression newCompression(String path, String format, int dictionarySize, GXBaseCollection[] messages) { return new Compression();}
- static Boolean decompress(String file, String path, GXBaseCollection[] messages) {return null;}
+ static Boolean decompress(String file, String path, GXBaseCollection[] messages) {return false;}
}
From 3949964cb6b018f64585fb533a8b8b82757922e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Fri, 19 Jul 2024 19:19:55 -0300
Subject: [PATCH 26/49] Refactor for better code quality
---
.../com/genexus/compression/Compression.java | 53 ++++------
.../com/genexus/compression/GXCompressor.java | 97 ++++++++++++-------
.../genexus/compression/TestCompression.java | 2 +
3 files changed, 79 insertions(+), 73 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 73f430045..9e3f4aae2 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -2,11 +2,14 @@
import com.genexus.GXBaseCollection;
import com.genexus.SdtMessages_Message;
-import com.genexus.StructSdtMessages_Message;
import org.apache.logging.log4j.Logger;
-import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Vector;
+import java.util.stream.Stream;
public class Compression {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Compression.class);
@@ -22,7 +25,7 @@ public Compression(String path, String format, GXBaseCollection();
+ filesToCompress = new Vector<>();
}
public void setPath(String path) {
@@ -34,48 +37,26 @@ public void setFormat(String format) {
}
public void addFile(String filePath) {
- if (new File(filePath).exists()) {
- filesToCompress.add(filePath);
- } else {
- log.error("File does not exist: {}", filePath);
- if (messages != null) storageMessages("File does not exist: " + filePath, messages[0]);
- }
+ filesToCompress.add(filePath);
}
public void addFolder(String folderPath) {
- File folder = new File(folderPath);
- if (folder.exists() && folder.isDirectory()) {
- File[] files = folder.listFiles();
- if (files != null) {
- for (File file : files) {
- if (file.isDirectory()) {
- addFolder(file.getAbsolutePath());
- } else {
- addFile(file.getAbsolutePath());
- }
- }
- }
- } else {
- log.error("Folder does not exist or is not a directory: {}", folder.getAbsolutePath());
- if (messages != null) storageMessages("Folder does not exist or is not a directory: " + folder.getAbsolutePath(), messages[0]);
+ Path path = Paths.get(folderPath);
+ try (Stream stream = Files.walk(path)) {
+ stream.filter(Files::isRegularFile)
+ .forEach(p -> addFile(p.toAbsolutePath().toString()));
+ } catch (IOException e) {
+ log.error("Failed to process directory: {}", folderPath, e);
}
}
public Boolean save() {
- return GXCompressor.compressFiles(filesToCompress, path, format, this.messages);
+ return GXCompressor.compressFiles(filesToCompress, path, format, messages);
}
public void clear() {
- this.path = "";
- this.format = "";
- this.filesToCompress = new Vector<>();
- }
-
- private static void storageMessages(String error, GXBaseCollection messages) {
- StructSdtMessages_Message struct = new StructSdtMessages_Message();
- struct.setDescription(error);
- struct.setType((byte) 1);
- SdtMessages_Message msg = new SdtMessages_Message(struct);
- messages.add(msg);
+ path = "";
+ format = "";
+ filesToCompress = new Vector<>();
}
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 637c0ff27..341f7949e 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -22,6 +22,8 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
@@ -34,64 +36,84 @@ public class GXCompressor implements IGXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
- private static void storageMessages(Exception ex, String error, GXBaseCollection messages) {
- StructSdtMessages_Message struct = new StructSdtMessages_Message();
- if (ex != null)
- struct.setDescription(ex.getMessage());
- else
+ private static final Map errorMessages = new HashMap<>();
+ static {
+ errorMessages.put("GENERIC_ERROR","An error occurred during the compression/decompression process: ");
+ errorMessages.put("NO_FILES_ADDED", "No files have been added for compression.");
+ errorMessages.put("FILE_NOT_EXISTS", "File does not exist: ");
+ errorMessages.put("FOLDER_NOT_EXISTS", "The specified folder does not exist: ");
+ errorMessages.put("UNSUPPORTED_FORMAT", "Unsupported compression/decompression format: ");
+ errorMessages.put("EMPTY_FILE", "The selected file is empty: ");
+ }
+
+ private static void storageMessages(String error, GXBaseCollection messages) {
+ try {
+ StructSdtMessages_Message struct = new StructSdtMessages_Message();
struct.setDescription(error);
- struct.setType((byte) 1);
- SdtMessages_Message msg = new SdtMessages_Message(struct);
- messages.add(msg);
+ struct.setType((byte) 1);
+ SdtMessages_Message msg = new SdtMessages_Message(struct);
+ messages.add(msg);
+ } catch (Exception e) {
+ log.error("Failed to store the following error message: {}", error, e);
+ }
+
}
public static Boolean compressFiles(Vector files, String path, String format, GXBaseCollection[] messages) {
if (files.isEmpty()){
- log.error("No files have been added for compression.");
- if (messages != null) storageMessages(null, "No files have been added for compression.", messages[0]);
+ log.error(errorMessages.get("NO_FILES_ADDED"));
+ if (messages != null) storageMessages(errorMessages.get("NO_FILES_ADDED"), messages[0]);
return false;
}
File[] toCompress = new File[files.size()];
int index = 0;
for (String filePath : files) {
- toCompress[index++] = new File(filePath);
+ File file = new File(filePath);
+ if (!file.exists()) {
+ log.error("{}{}", errorMessages.get("FILE_NOT_EXISTS"), filePath);
+ if (messages != null) storageMessages(errorMessages.get("FILE_NOT_EXISTS") + filePath, messages[0]);
+ continue;
+ }
+ toCompress[index++] = file;
}
try {
CompressionFormat compressionFormat = getCompressionFormat(format);
switch (compressionFormat) {
case ZIP:
compressToZip(toCompress, path);
- return true;
+ break;
case SEVENZ:
compressToSevenZ(toCompress, path);
- return true;
+ break;
case TAR:
compressToTar(toCompress, path);
- return true;
+ break;
case GZIP:
compressToGzip(toCompress, path);
- return true;
+ break;
case JAR:
compressToJar(toCompress, path);
- return true;
+ break;
+ default:
+ return false;
}
+ return true;
} catch (IllegalArgumentException iae) {
- log.error("Unsupported compression format for compression: {}", format, iae);
- if (messages != null) storageMessages(null, "Unsupported compression format for compression: " + format, messages[0]);
+ log.error("{}{}", errorMessages.get("UNSUPPORTED_FORMAT"), format, iae);
+ if (messages != null) storageMessages(errorMessages.get("UNSUPPORTED_FORMAT") + format, messages[0]);
return false;
} catch (Exception e) {
- log.error("An error occurred during the compression process: ", e);
- if (messages != null) storageMessages(e, null, messages[0]);
+ log.error(errorMessages.get("GENERIC_ERROR"), e);
+ if (messages != null) storageMessages(e.getMessage(), messages[0]);
return false;
}
- return false;
}
public static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {
File toCompress = new File(folder);
if (!toCompress.exists()) {
- log.error("The specified folder does not exist: {}", toCompress.getAbsolutePath());
- if (messages != null) storageMessages(null, "The specified folder does not exist: " + toCompress.getAbsolutePath(), messages[0]);
+ log.error("{}{}", errorMessages.get("FOLDER_NOT_EXISTS"), toCompress.getAbsolutePath());
+ if (messages != null) storageMessages(errorMessages.get("FOLDER_NOT_EXISTS") + toCompress.getAbsolutePath(), messages[0]);
return false;
}
Vector vector = new Vector<>();
@@ -106,13 +128,13 @@ public static Compression newCompression(String path, String format, GXBaseColle
public static Boolean decompress(String file, String path, GXBaseCollection[] messages) {
File toCompress = new File(file);
if (!toCompress.exists()) {
- log.error("The specified archive does not exist: {}", toCompress.getAbsolutePath());
- if (messages != null) storageMessages(null, "The specified archive does not exist: " + toCompress.getAbsolutePath(), messages[0]);
+ log.error("{}{}", errorMessages.get("FILE_NOT_EXISTS"), toCompress.getAbsolutePath());
+ if (messages != null) storageMessages(errorMessages.get("FILE_NOT_EXISTS") + toCompress.getAbsolutePath(), messages[0]);
return false;
}
if (toCompress.length() == 0L){
- log.error("The archive located at {} is empty", file);
- if (messages != null) storageMessages(null, "The archive located at " + toCompress.getAbsolutePath() + " is empty", messages[0]);
+ log.error("{}{}", errorMessages.get("EMPTY_FILE"), file);
+ if (messages != null) storageMessages(errorMessages.get("EMPTY_FILE") + file, messages[0]);
return false;
}
String extension = getExtension(toCompress.getName());
@@ -120,30 +142,31 @@ public static Boolean decompress(String file, String path, GXBaseCollection
Date: Fri, 19 Jul 2024 19:24:24 -0300
Subject: [PATCH 27/49] Remove unused imports
---
.../src/test/java/com/genexus/compression/TestCompression.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index caebd92bb..ab224c40e 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -1,7 +1,5 @@
package com.genexus.compression;
-import com.genexus.GXBaseCollection;
-import com.genexus.SdtMessages_Message;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
From a8cd11e3b12a749a134de5e2e7bfd90e70aecd0f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Fri, 19 Jul 2024 19:35:02 -0300
Subject: [PATCH 28/49] Improve error message for invalid compression format
---
.../src/main/java/com/genexus/compression/GXCompressor.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 341f7949e..e9d763faf 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -476,9 +476,8 @@ private static CompressionFormat getCompressionFormat(String format) {
try {
return CompressionFormat.valueOf(format.toUpperCase());
} catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Invalid compression format: " + format);
+ throw new IllegalArgumentException("Invalid compression format: " + format + ". Valid formats are (upper or lower): GZIP,TAR, ZIP, SEVENZ and JAR");
}
}
-}
-
+}
\ No newline at end of file
From 33178d6cf3da68c056ba8f88719618c22b3deae5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 22 Jul 2024 13:38:21 -0300
Subject: [PATCH 29/49] Refactor compression classes to use ArrayList instead
of Vector
---
.../main/java/com/genexus/compression/Compression.java | 8 ++++----
.../java/com/genexus/compression/GXCompressor.java | 10 +++++-----
.../java/com/genexus/compression/TestCompression.java | 8 ++++----
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 9e3f4aae2..2e8979b39 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -8,7 +8,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.Vector;
+import java.util.ArrayList;
import java.util.stream.Stream;
public class Compression {
@@ -17,7 +17,7 @@ public class Compression {
private String path;
private String format;
private GXBaseCollection[] messages;
- private Vector filesToCompress;
+ private ArrayList filesToCompress;
public Compression() {}
@@ -25,7 +25,7 @@ public Compression(String path, String format, GXBaseCollection();
+ filesToCompress = new ArrayList<>();
}
public void setPath(String path) {
@@ -57,6 +57,6 @@ public Boolean save() {
public void clear() {
path = "";
format = "";
- filesToCompress = new Vector<>();
+ filesToCompress = new ArrayList<>();
}
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index e9d763faf..c1b2979d1 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -22,9 +22,9 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
-import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
@@ -59,7 +59,7 @@ private static void storageMessages(String error, GXBaseCollection files, String path, String format, GXBaseCollection[] messages) {
+ public static Boolean compressFiles(ArrayList files, String path, String format, GXBaseCollection[] messages) {
if (files.isEmpty()){
log.error(errorMessages.get("NO_FILES_ADDED"));
if (messages != null) storageMessages(errorMessages.get("NO_FILES_ADDED"), messages[0]);
@@ -116,9 +116,9 @@ public static Boolean compressFolder(String folder, String path, String format,
if (messages != null) storageMessages(errorMessages.get("FOLDER_NOT_EXISTS") + toCompress.getAbsolutePath(), messages[0]);
return false;
}
- Vector vector = new Vector<>();
- vector.add(folder);
- return compressFiles(vector, path, format, messages);
+ ArrayList list = new ArrayList<>();
+ list.add(folder);
+ return compressFiles(list, path, format, messages);
}
public static Compression newCompression(String path, String format, GXBaseCollection[] messages) {
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index ab224c40e..22d587ed9 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -7,19 +7,19 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
-import java.util.Vector;
+import java.util.ArrayList;
import static org.junit.Assert.*;
public class TestCompression {
- private Vector files;
+ private ArrayList files;
private File testDirectory;
@Before
public void setUp() throws IOException {
testDirectory = Files.createTempDirectory("testCompressor").toFile();
- files = new Vector<>();
+ files = new ArrayList<>();
String content = "This is a sample text to test the compression functionality.";
for (int i = 0; i < 3; i++) {
File file = new File(testDirectory, "testFile" + i + ".txt");
@@ -65,7 +65,7 @@ public void testCompressToTar() {
@Test
public void testCompressToGzip() {
String outputPath = new File(testDirectory, "output.gz").getAbsolutePath();
- Vector singleFileCollection = new Vector<>();
+ ArrayList singleFileCollection = new ArrayList<>();
singleFileCollection.add(files.get(0));
Boolean result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP", null);
assertTrue(result);
From 42abd43a615ba49bcec9695452be39240e0bfd26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 22 Jul 2024 13:49:00 -0300
Subject: [PATCH 30/49] Refactor compression interface to use ArrayList instead
of Vector
---
.../src/main/java/com/genexus/compression/IGXCompressor.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index 0e392c714..bb428b87b 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -2,10 +2,11 @@
import com.genexus.GXBaseCollection;
import com.genexus.SdtMessages_Message;
-import java.util.Vector;
+
+import java.util.ArrayList;
public interface IGXCompressor {
- static Boolean compressFiles(Vector files, String path, String format, GXBaseCollection[] messages) {return false;}
+ static Boolean compressFiles(ArrayList files, String path, String format, GXBaseCollection[] messages) {return false;}
static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {return false;}
static Compression newCompression(String path, String format, int dictionarySize, GXBaseCollection[] messages) { return new Compression();}
static Boolean decompress(String file, String path, GXBaseCollection[] messages) {return false;}
From 94a553ba87041b029b9eaca912241e6fdb65ba75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 23 Jul 2024 12:27:54 -0300
Subject: [PATCH 31/49] Switch from map to set of attributes
---
.../com/genexus/compression/GXCompressor.java | 49 +++++++++----------
1 file changed, 22 insertions(+), 27 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index c1b2979d1..269697091 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -23,8 +23,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
@@ -36,15 +34,12 @@ public class GXCompressor implements IGXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
- private static final Map errorMessages = new HashMap<>();
- static {
- errorMessages.put("GENERIC_ERROR","An error occurred during the compression/decompression process: ");
- errorMessages.put("NO_FILES_ADDED", "No files have been added for compression.");
- errorMessages.put("FILE_NOT_EXISTS", "File does not exist: ");
- errorMessages.put("FOLDER_NOT_EXISTS", "The specified folder does not exist: ");
- errorMessages.put("UNSUPPORTED_FORMAT", "Unsupported compression/decompression format: ");
- errorMessages.put("EMPTY_FILE", "The selected file is empty: ");
- }
+ private static final String GENERIC_ERROR = "An error occurred during the compression/decompression process: ";
+ private static final String NO_FILES_ADDED = "No files have been added for compression.";
+ private static final String FILE_NOT_EXISTS = "File does not exist: ";
+ private static final String FOLDER_NOT_EXISTS = "The specified folder does not exist: ";
+ private static final String UNSUPPORTED_FORMAT = "Unsupported compression/decompression format: ";
+ private static final String EMPTY_FILE = "The selected file is empty: ";
private static void storageMessages(String error, GXBaseCollection messages) {
try {
@@ -61,8 +56,8 @@ private static void storageMessages(String error, GXBaseCollection files, String path, String format, GXBaseCollection[] messages) {
if (files.isEmpty()){
- log.error(errorMessages.get("NO_FILES_ADDED"));
- if (messages != null) storageMessages(errorMessages.get("NO_FILES_ADDED"), messages[0]);
+ log.error(NO_FILES_ADDED);
+ if (messages != null) storageMessages(NO_FILES_ADDED, messages[0]);
return false;
}
File[] toCompress = new File[files.size()];
@@ -70,8 +65,8 @@ public static Boolean compressFiles(ArrayList files, String path, String
for (String filePath : files) {
File file = new File(filePath);
if (!file.exists()) {
- log.error("{}{}", errorMessages.get("FILE_NOT_EXISTS"), filePath);
- if (messages != null) storageMessages(errorMessages.get("FILE_NOT_EXISTS") + filePath, messages[0]);
+ log.error("{}{}", FILE_NOT_EXISTS, filePath);
+ if (messages != null) storageMessages(FILE_NOT_EXISTS + filePath, messages[0]);
continue;
}
toCompress[index++] = file;
@@ -99,11 +94,11 @@ public static Boolean compressFiles(ArrayList files, String path, String
}
return true;
} catch (IllegalArgumentException iae) {
- log.error("{}{}", errorMessages.get("UNSUPPORTED_FORMAT"), format, iae);
- if (messages != null) storageMessages(errorMessages.get("UNSUPPORTED_FORMAT") + format, messages[0]);
+ log.error("{}{}", UNSUPPORTED_FORMAT, format, iae);
+ if (messages != null) storageMessages(UNSUPPORTED_FORMAT + format, messages[0]);
return false;
} catch (Exception e) {
- log.error(errorMessages.get("GENERIC_ERROR"), e);
+ log.error(GENERIC_ERROR, e);
if (messages != null) storageMessages(e.getMessage(), messages[0]);
return false;
}
@@ -112,8 +107,8 @@ public static Boolean compressFiles(ArrayList files, String path, String
public static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {
File toCompress = new File(folder);
if (!toCompress.exists()) {
- log.error("{}{}", errorMessages.get("FOLDER_NOT_EXISTS"), toCompress.getAbsolutePath());
- if (messages != null) storageMessages(errorMessages.get("FOLDER_NOT_EXISTS") + toCompress.getAbsolutePath(), messages[0]);
+ log.error("{}{}", FOLDER_NOT_EXISTS, toCompress.getAbsolutePath());
+ if (messages != null) storageMessages(FOLDER_NOT_EXISTS + toCompress.getAbsolutePath(), messages[0]);
return false;
}
ArrayList list = new ArrayList<>();
@@ -128,13 +123,13 @@ public static Compression newCompression(String path, String format, GXBaseColle
public static Boolean decompress(String file, String path, GXBaseCollection[] messages) {
File toCompress = new File(file);
if (!toCompress.exists()) {
- log.error("{}{}", errorMessages.get("FILE_NOT_EXISTS"), toCompress.getAbsolutePath());
- if (messages != null) storageMessages(errorMessages.get("FILE_NOT_EXISTS") + toCompress.getAbsolutePath(), messages[0]);
+ log.error("{}{}", FILE_NOT_EXISTS, toCompress.getAbsolutePath());
+ if (messages != null) storageMessages(FILE_NOT_EXISTS + toCompress.getAbsolutePath(), messages[0]);
return false;
}
if (toCompress.length() == 0L){
- log.error("{}{}", errorMessages.get("EMPTY_FILE"), file);
- if (messages != null) storageMessages(errorMessages.get("EMPTY_FILE") + file, messages[0]);
+ log.error("{}{}", EMPTY_FILE, file);
+ if (messages != null) storageMessages(EMPTY_FILE + file, messages[0]);
return false;
}
String extension = getExtension(toCompress.getName());
@@ -159,13 +154,13 @@ public static Boolean decompress(String file, String path, GXBaseCollection
Date: Wed, 24 Jul 2024 12:04:28 -0300
Subject: [PATCH 32/49] Update gxcompress dependencies and refactor compression
classes
---
gxcompress/pom.xml | 6 ++++
.../com/genexus/compression/GXCompressor.java | 18 ++++++------
.../genexus/compression/TestCompression.java | 29 ++++++++++++++-----
3 files changed, 37 insertions(+), 16 deletions(-)
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index c162122d4..7d310cfb4 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -43,6 +43,12 @@
gxcommon
${project.version}
+
+ com.genexus
+ gxclassR
+ ${project.version}
+ test
+
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 269697091..ad3b36876 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -57,7 +57,7 @@ private static void storageMessages(String error, GXBaseCollection files, String path, String format, GXBaseCollection[] messages) {
if (files.isEmpty()){
log.error(NO_FILES_ADDED);
- if (messages != null) storageMessages(NO_FILES_ADDED, messages[0]);
+ storageMessages(NO_FILES_ADDED, messages[0]);
return false;
}
File[] toCompress = new File[files.size()];
@@ -66,7 +66,7 @@ public static Boolean compressFiles(ArrayList files, String path, String
File file = new File(filePath);
if (!file.exists()) {
log.error("{}{}", FILE_NOT_EXISTS, filePath);
- if (messages != null) storageMessages(FILE_NOT_EXISTS + filePath, messages[0]);
+ storageMessages(FILE_NOT_EXISTS + filePath, messages[0]);
continue;
}
toCompress[index++] = file;
@@ -95,11 +95,11 @@ public static Boolean compressFiles(ArrayList files, String path, String
return true;
} catch (IllegalArgumentException iae) {
log.error("{}{}", UNSUPPORTED_FORMAT, format, iae);
- if (messages != null) storageMessages(UNSUPPORTED_FORMAT + format, messages[0]);
+ storageMessages(UNSUPPORTED_FORMAT + format, messages[0]);
return false;
} catch (Exception e) {
log.error(GENERIC_ERROR, e);
- if (messages != null) storageMessages(e.getMessage(), messages[0]);
+ storageMessages(e.getMessage(), messages[0]);
return false;
}
}
@@ -108,7 +108,7 @@ public static Boolean compressFolder(String folder, String path, String format,
File toCompress = new File(folder);
if (!toCompress.exists()) {
log.error("{}{}", FOLDER_NOT_EXISTS, toCompress.getAbsolutePath());
- if (messages != null) storageMessages(FOLDER_NOT_EXISTS + toCompress.getAbsolutePath(), messages[0]);
+ storageMessages(FOLDER_NOT_EXISTS + toCompress.getAbsolutePath(), messages[0]);
return false;
}
ArrayList list = new ArrayList<>();
@@ -124,12 +124,12 @@ public static Boolean decompress(String file, String path, GXBaseCollection files;
private File testDirectory;
+ private static GXBaseCollection[] msgs;
+
+ @BeforeClass
+ public static void setUpTestSuite() {
+ Connect.init();
+ msgs = new GXBaseCollection[]{new GXBaseCollection<>()};
+ msgs[0] = new GXBaseCollection<>(SdtMessages_Message.class, "Messages.Message", "Genexus");
+ }
@Before
- public void setUp() throws IOException {
+ public void setUpTest() throws IOException {
testDirectory = Files.createTempDirectory("testCompressor").toFile();
files = new ArrayList<>();
String content = "This is a sample text to test the compression functionality.";
@@ -41,7 +56,7 @@ public void tearDown() {
@Test
public void testCompressToZip() {
String outputPath = new File(testDirectory, "output.zip").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "ZIP", null);
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "ZIP", msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -49,7 +64,7 @@ public void testCompressToZip() {
@Test
public void testCompressToSevenZ() {
String outputPath = new File(testDirectory, "output.7z").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "SEVENZ", null);
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "SEVENZ", msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -57,7 +72,7 @@ public void testCompressToSevenZ() {
@Test
public void testCompressToTar() {
String outputPath = new File(testDirectory, "output.tar").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "TAR", null);
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "TAR", msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -67,7 +82,7 @@ public void testCompressToGzip() {
String outputPath = new File(testDirectory, "output.gz").getAbsolutePath();
ArrayList singleFileCollection = new ArrayList<>();
singleFileCollection.add(files.get(0));
- Boolean result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP", null);
+ Boolean result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP", msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -75,7 +90,7 @@ public void testCompressToGzip() {
@Test
public void testCompressToJar() {
String outputPath = new File(testDirectory, "output.jar").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "JAR", null);
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "JAR", msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -83,7 +98,7 @@ public void testCompressToJar() {
@Test
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN", null);
+ Boolean result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN", msgs);
assertFalse(result);
}
}
From 289d6250d1ac9b66808ff87cd1d14ed288dd8c72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 24 Jul 2024 12:07:12 -0300
Subject: [PATCH 33/49] Remove unused imports
---
.../src/test/java/com/genexus/compression/TestCompression.java | 3 ---
1 file changed, 3 deletions(-)
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 47139e851..8831ff8f8 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -1,11 +1,8 @@
package com.genexus.compression;
-import com.genexus.Application;
import com.genexus.GXBaseCollection;
import com.genexus.SdtMessages_Message;
-import com.genexus.reports.GXcfg;
import com.genexus.specific.java.Connect;
-import com.genexus.specific.java.LogManager;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
From b64ca63cead33e818ac4f60d538597eaff664c68 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Thu, 22 Aug 2024 14:34:21 -0300
Subject: [PATCH 34/49] Consider folder within files to compress for jar and
zip formats
---
.../com/genexus/compression/GXCompressor.java | 168 ++++++++++++------
1 file changed, 114 insertions(+), 54 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index ad3b36876..4c9f7ce3c 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -11,9 +11,6 @@
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
-import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
-import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
-import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.commons.io.IOUtils;
import com.github.junrar.Junrar;
import com.github.junrar.exception.RarException;
@@ -23,6 +20,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
@@ -166,41 +164,48 @@ public static Boolean decompress(String file, String path, GXBaseCollection= 0) {
- zos.write(buffer, 0, length);
- }
+ FileInputStream fis = new FileInputStream(file);
+ ZipEntry entry = new ZipEntry(entryName);
+ entry.setTime(file.lastModified());
+ zos.putNextEntry(entry);
+ byte[] buffer = new byte[1024];
+ int count;
+ while ((count = fis.read(buffer)) != -1) {
+ zos.write(buffer, 0, count);
}
- zos.closeArchiveEntry();
+ zos.closeEntry();
+ fis.close();
}
}
@@ -277,27 +282,56 @@ private static void addFileToTar(TarArchiveOutputStream taos, File file, String
}
}
- private static void compressToGzip(File[] files, String outputPath) throws RuntimeException {
- if (files.length > 1) {
- throw new IllegalArgumentException("GZIP does not support multiple files. Consider archiving the files first.");
+ private static void compressToGzip(File[] files, String outputPath) throws IOException {
+ File tarFile = new File(outputPath.replace(".gz", ".tar"));
+ FileOutputStream fosTar = new FileOutputStream(tarFile);
+ BufferedOutputStream bosTar = new BufferedOutputStream(fosTar);
+ TarArchiveOutputStream taos = new TarArchiveOutputStream(bosTar);
+ for (File file : files) {
+ addFilesToTar(file, "", taos);
}
+ taos.finish();
+ taos.close();
+ bosTar.close();
+ fosTar.close();
+ FileInputStream fis = new FileInputStream(tarFile);
+ FileOutputStream fosGzip = new FileOutputStream(outputPath);
+ GZIPOutputStream gzos = new GZIPOutputStream(fosGzip);
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = fis.read(buffer)) > 0) {
+ gzos.write(buffer, 0, length);
+ }
+ gzos.finish();
+ gzos.close();
+ fosGzip.close();
+ fis.close();
+ tarFile.delete();
+ }
- File inputFile = files[0];
- File outputFile = new File(outputPath);
-
- try (InputStream in = Files.newInputStream(inputFile.toPath());
- FileOutputStream fout = new FileOutputStream(outputFile);
- BufferedOutputStream out = new BufferedOutputStream(fout);
- GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(out)) {
-
- byte[] buffer = new byte[4096];
- int n;
- while (-1 != (n = in.read(buffer))) {
- gzOut.write(buffer, 0, n);
+ private static void addFilesToTar(File file, String parent, TarArchiveOutputStream taos) throws IOException {
+ String entryName = parent + file.getName();
+ if (file.isDirectory()) {
+ File[] children = file.listFiles();
+ if (children != null) {
+ if (!entryName.endsWith("/")) {
+ entryName += "/";
+ }
+ for (File child : children) {
+ addFilesToTar(child, entryName, taos);
+ }
}
- } catch (IOException e) {
- log.error("Error while compressing to gzip", e);
- throw new RuntimeException("Error compressing file with GZIP", e);
+ } else {
+ TarArchiveEntry entry = new TarArchiveEntry(file, entryName);
+ taos.putArchiveEntry(entry);
+ BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(file.toPath()));
+ byte[] buffer = new byte[1024];
+ int count;
+ while ((count = bis.read(buffer)) != -1) {
+ taos.write(buffer, 0, count);
+ }
+ bis.close();
+ taos.closeArchiveEntry();
}
}
@@ -420,19 +454,45 @@ private static void decompressGzip(File inputFile, String outputPath) throws IOE
}
private static void compressToJar(File[] files, String outputPath) throws IOException {
- JarOutputStream jos = new JarOutputStream(Files.newOutputStream(Paths.get(outputPath)));
- byte[] buffer = new byte[1024];
+ FileOutputStream fos = new FileOutputStream(outputPath);
+ JarOutputStream jos = new JarOutputStream(fos);
for (File file : files) {
+ addFileToJar("", file, jos);
+ }
+ jos.close();
+ fos.close();
+ }
+
+ private static void addFileToJar(String parent, File file, JarOutputStream jos) throws IOException {
+ if (file.isHidden()) {
+ log.error("{} is a hidden file and cannot be compressed", file.getAbsolutePath());
+ return;
+ }
+ String entryName = parent + file.getName();
+ if (file.isDirectory()) {
+ if (!entryName.endsWith("/")) {
+ entryName += "/";
+ }
+ JarEntry entry = new JarEntry(entryName);
+ entry.setTime(file.lastModified());
+ jos.putNextEntry(entry);
+ jos.closeEntry();
+ for (File nestedFile : Objects.requireNonNull(file.listFiles())) {
+ addFileToJar(entryName, nestedFile, jos);
+ }
+ } else {
FileInputStream fis = new FileInputStream(file);
- jos.putNextEntry(new JarEntry(file.getName()));
- int length;
- while ((length = fis.read(buffer)) > 0) {
- jos.write(buffer, 0, length);
+ JarEntry entry = new JarEntry(entryName);
+ entry.setTime(file.lastModified());
+ jos.putNextEntry(entry);
+ byte[] buffer = new byte[1024];
+ int count;
+ while ((count = fis.read(buffer)) != -1) {
+ jos.write(buffer, 0, count);
}
- fis.close();
jos.closeEntry();
+ fis.close();
}
- jos.close();
}
public static void decompressJar(File jarFile, String outputPath) throws IOException {
From e4961fe091db2059f82c99e33053bcd3fa0b40b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Fri, 1 Nov 2024 18:08:51 +0900
Subject: [PATCH 35/49] Compression module simplification an improvements
---
gxcompress/pom.xml | 9 +-
.../com/genexus/compression/Compression.java | 33 +-
.../compression/CompressionFormat.java | 5 -
.../com/genexus/compression/GXCompressor.java | 612 +++++++++---------
.../genexus/compression/IGXCompressor.java | 5 +-
.../genexus/compression/TestCompression.java | 12 +-
6 files changed, 313 insertions(+), 363 deletions(-)
delete mode 100644 gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
diff --git a/gxcompress/pom.xml b/gxcompress/pom.xml
index 7d310cfb4..ebeb9b276 100644
--- a/gxcompress/pom.xml
+++ b/gxcompress/pom.xml
@@ -16,17 +16,12 @@
org.apache.commons
commons-compress
- 1.26.2
+ 1.27.1
org.tukaani
xz
- 1.9
-
-
- com.github.junrar
- junrar
- 7.5.5
+ 1.10
org.apache.logging.log4j
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 2e8979b39..8b656fea5 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -14,49 +14,32 @@
public class Compression {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Compression.class);
- private String path;
- private String format;
+ private String absolutePath;
private GXBaseCollection[] messages;
private ArrayList filesToCompress;
public Compression() {}
- public Compression(String path, String format, GXBaseCollection[] messages) {
- this.path = path;
- this.format = format;
+ public Compression(String absolutePath, GXBaseCollection[] messages) {
+ this.absolutePath = absolutePath;
this.messages = messages;
filesToCompress = new ArrayList<>();
}
- public void setPath(String path) {
- this.path = path;
+ public void setAbsolutePath(String path) {
+ this.absolutePath = path;
}
- public void setFormat(String format) {
- this.format = format;
- }
-
- public void addFile(String filePath) {
+ public void addElement(String filePath) {
filesToCompress.add(filePath);
}
- public void addFolder(String folderPath) {
- Path path = Paths.get(folderPath);
- try (Stream stream = Files.walk(path)) {
- stream.filter(Files::isRegularFile)
- .forEach(p -> addFile(p.toAbsolutePath().toString()));
- } catch (IOException e) {
- log.error("Failed to process directory: {}", folderPath, e);
- }
- }
-
public Boolean save() {
- return GXCompressor.compressFiles(filesToCompress, path, format, messages);
+ return GXCompressor.compress(filesToCompress, absolutePath, messages);
}
public void clear() {
- path = "";
- format = "";
+ absolutePath = "";
filesToCompress = new ArrayList<>();
}
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java b/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
deleted file mode 100644
index dce8ce7b2..000000000
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionFormat.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.genexus.compression;
-
-public enum CompressionFormat {
- GZIP,TAR, ZIP, SEVENZ, JAR
-}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 4c9f7ce3c..2aae9fe13 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -1,8 +1,11 @@
package com.genexus.compression;
+import com.genexus.CommonUtil;
import com.genexus.GXBaseCollection;
import com.genexus.SdtMessages_Message;
import com.genexus.StructSdtMessages_Message;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.logging.log4j.Logger;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
@@ -11,18 +14,14 @@
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
-import org.apache.commons.io.IOUtils;
-import com.github.junrar.Junrar;
-import com.github.junrar.exception.RarException;
import java.io.*;
import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
-import java.util.Objects;
+import java.util.Enumeration;
+import java.util.Stack;
import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
+import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.*;
@@ -52,7 +51,7 @@ private static void storageMessages(String error, GXBaseCollection files, String path, String format, GXBaseCollection[] messages) {
+ public static Boolean compress(ArrayList files, String path, GXBaseCollection[] messages) {
if (files.isEmpty()){
log.error(NO_FILES_ADDED);
storageMessages(NO_FILES_ADDED, messages[0]);
@@ -69,22 +68,22 @@ public static Boolean compressFiles(ArrayList files, String path, String
}
toCompress[index++] = file;
}
+ String format = CommonUtil.getFileType(path).toLowerCase();
try {
- CompressionFormat compressionFormat = getCompressionFormat(format);
- switch (compressionFormat) {
- case ZIP:
+ switch (format.toLowerCase()) {
+ case "zip":
compressToZip(toCompress, path);
break;
- case SEVENZ:
+ case "7z":
compressToSevenZ(toCompress, path);
break;
- case TAR:
+ case "tar":
compressToTar(toCompress, path);
break;
- case GZIP:
+ case "gz":
compressToGzip(toCompress, path);
break;
- case JAR:
+ case "jar":
compressToJar(toCompress, path);
break;
default:
@@ -92,7 +91,7 @@ public static Boolean compressFiles(ArrayList files, String path, String
}
return true;
} catch (IllegalArgumentException iae) {
- log.error("{}{}", UNSUPPORTED_FORMAT, format, iae);
+ log.error("{}{}. Supported compression formats are zip, 7z, tar, gz and jar", UNSUPPORTED_FORMAT, format, iae);
storageMessages(UNSUPPORTED_FORMAT + format, messages[0]);
return false;
} catch (Exception e) {
@@ -102,20 +101,8 @@ public static Boolean compressFiles(ArrayList files, String path, String
}
}
- public static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {
- File toCompress = new File(folder);
- if (!toCompress.exists()) {
- log.error("{}{}", FOLDER_NOT_EXISTS, toCompress.getAbsolutePath());
- storageMessages(FOLDER_NOT_EXISTS + toCompress.getAbsolutePath(), messages[0]);
- return false;
- }
- ArrayList list = new ArrayList<>();
- list.add(folder);
- return compressFiles(list, path, format, messages);
- }
-
- public static Compression newCompression(String path, String format, GXBaseCollection[] messages) {
- return new Compression(path, format, messages);
+ public static Compression newCompression(String path, GXBaseCollection[] messages) {
+ return new Compression(path, messages);
}
public static Boolean decompress(String file, String path, GXBaseCollection[] messages) {
@@ -148,11 +135,8 @@ public static Boolean decompress(String file, String path, GXBaseCollection= 0) {
+ zipOut.write(bytes, 0, length);
+ }
}
- zos.closeEntry();
- fis.close();
}
}
- private static void compressToSevenZ(File[] files, String outputPath) throws RuntimeException {
- File outputSevenZFile = new File(outputPath);
- try (SevenZOutputFile sevenZOutput = new SevenZOutputFile(outputSevenZFile)) {
+ private static void compressToSevenZ(File[] files, String outputPath) throws IOException {
+ if (files == null || outputPath == null) {
+ throw new IllegalArgumentException("Files and outputPath must not be null");
+ }
+ File outputFile = new File(outputPath);
+ if (outputFile.exists()) {
+ throw new IOException("Output file already exists");
+ }
+ try (SevenZOutputFile sevenZOutput = new SevenZOutputFile(outputFile)) {
for (File file : files) {
- addToSevenZArchive(sevenZOutput, file, "");
+ if (file == null || !file.exists()) {
+ continue;
+ }
+ addFileToSevenZ(sevenZOutput, file, file.getName());
}
- } catch (IOException e) {
- log.error("Error while compressing to 7z", e);
- throw new RuntimeException("Error creating 7z archive", e);
}
}
- private static void addToSevenZArchive(SevenZOutputFile sevenZOutput, File file, String base) throws IOException {
- if (file.isFile()) {
- SevenZArchiveEntry entry = sevenZOutput.createArchiveEntry(file, base + file.getName());
+ private static void addFileToSevenZ(SevenZOutputFile sevenZOutput, File file, String entryName) throws IOException {
+ if (file.isDirectory()) {
+ File[] children = file.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ addFileToSevenZ(sevenZOutput, child, entryName + "/" + child.getName());
+ }
+ }
+ } else {
+ SevenZArchiveEntry entry = sevenZOutput.createArchiveEntry(file, entryName);
sevenZOutput.putArchiveEntry(entry);
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[8192];
- int bytesRead;
- while ((bytesRead = fis.read(buffer)) != -1) {
- sevenZOutput.write(buffer, 0, bytesRead);
+ int len;
+ while ((len = fis.read(buffer)) > 0) {
+ sevenZOutput.write(buffer, 0, len);
}
}
sevenZOutput.closeArchiveEntry();
- } else if (file.isDirectory()) {
- File[] children = file.listFiles();
- if (children != null) {
- for (File child : children) {
- addToSevenZArchive(sevenZOutput, child, base + file.getName() + "/");
- }
- }
}
}
- private static void compressToTar(File[] files, String outputPath) throws RuntimeException {
- File outputTarFile = new File(outputPath);
- try (FileOutputStream fos = new FileOutputStream(outputTarFile);
- TarArchiveOutputStream taos = new TarArchiveOutputStream(fos)) {
- taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
- taos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
- taos.setAddPaxHeadersForNonAsciiNames(true);
-
+ private static void compressToTar(File[] files, String outputPath) throws IOException {
+ if (outputPath == null || outputPath.isEmpty()) {
+ throw new IllegalArgumentException("The output path must not be null or empty");
+ }
+ File outputFile = new File(outputPath);
+ if (outputFile.exists()) {
+ throw new IOException("Output file already exists");
+ }
+ try (FileOutputStream fos = new FileOutputStream(outputFile);
+ BufferedOutputStream bos = new BufferedOutputStream(fos);
+ TarArchiveOutputStream tarOut = new TarArchiveOutputStream(bos)) {
for (File file : files) {
- addFileToTar(taos, file, "");
+ if (file == null || !file.exists()) {
+ continue;
+ }
+ addFileToTar(tarOut, file, file.getName());
}
- taos.finish();
- } catch (IOException e) {
- log.error("Error while compressing to tar", e);
- throw new RuntimeException("Error creating TAR archive", e);
}
}
- private static void addFileToTar(TarArchiveOutputStream taos, File file, String base) throws IOException {
+ private static void addFileToTar(TarArchiveOutputStream tarOut, File file, String entryName) throws IOException {
if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
- addFileToTar(taos, child, base + file.getName() + "/");
+ addFileToTar(tarOut, child, entryName + "/" + child.getName());
}
}
- } else if (file.isFile()) {
- String entryName = base + file.getName();
+ } else {
TarArchiveEntry entry = new TarArchiveEntry(file, entryName);
entry.setSize(file.length());
-
- taos.putArchiveEntry(entry);
+ tarOut.putArchiveEntry(entry);
try (FileInputStream fis = new FileInputStream(file)) {
- IOUtils.copy(fis, taos);
+ byte[] buffer = new byte[8192];
+ int len;
+ while ((len = fis.read(buffer)) != -1) {
+ tarOut.write(buffer, 0, len);
+ }
}
- taos.closeArchiveEntry();
+ tarOut.closeArchiveEntry();
}
}
private static void compressToGzip(File[] files, String outputPath) throws IOException {
- File tarFile = new File(outputPath.replace(".gz", ".tar"));
- FileOutputStream fosTar = new FileOutputStream(tarFile);
- BufferedOutputStream bosTar = new BufferedOutputStream(fosTar);
- TarArchiveOutputStream taos = new TarArchiveOutputStream(bosTar);
- for (File file : files) {
- addFilesToTar(file, "", taos);
- }
- taos.finish();
- taos.close();
- bosTar.close();
- fosTar.close();
- FileInputStream fis = new FileInputStream(tarFile);
- FileOutputStream fosGzip = new FileOutputStream(outputPath);
- GZIPOutputStream gzos = new GZIPOutputStream(fosGzip);
- byte[] buffer = new byte[1024];
- int length;
- while ((length = fis.read(buffer)) > 0) {
- gzos.write(buffer, 0, length);
+ if (outputPath == null || outputPath.isEmpty()) {
+ throw new IllegalArgumentException("Output path is null or empty");
}
- gzos.finish();
- gzos.close();
- fosGzip.close();
- fis.close();
- tarFile.delete();
- }
-
- private static void addFilesToTar(File file, String parent, TarArchiveOutputStream taos) throws IOException {
- String entryName = parent + file.getName();
- if (file.isDirectory()) {
- File[] children = file.listFiles();
- if (children != null) {
- if (!entryName.endsWith("/")) {
- entryName += "/";
- }
- for (File child : children) {
- addFilesToTar(child, entryName, taos);
- }
- }
+ File outputFile = new File(outputPath);
+ if (outputFile.exists() && !outputFile.canWrite()) {
+ throw new IOException("Cannot write to output file");
} else {
- TarArchiveEntry entry = new TarArchiveEntry(file, entryName);
- taos.putArchiveEntry(entry);
- BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(file.toPath()));
- byte[] buffer = new byte[1024];
- int count;
- while ((count = bis.read(buffer)) != -1) {
- taos.write(buffer, 0, count);
+ File parentDir = outputFile.getParentFile();
+ if (parentDir != null && !parentDir.exists() && !parentDir.mkdirs()) {
+ throw new IOException("Failed to create output directory");
}
- bis.close();
- taos.closeArchiveEntry();
}
- }
-
- private static void decompressZip(File zipFile, String directory) throws RuntimeException{
- Path zipFilePath = Paths.get(zipFile.toURI());
- Path targetDir = Paths.get(directory);
- targetDir = targetDir.toAbsolutePath();
-
- try (InputStream fis = Files.newInputStream(zipFilePath.toFile().toPath());
- ZipInputStream zipIn = new ZipInputStream(fis)) {
-
- ZipEntry entry;
- while ((entry = zipIn.getNextEntry()) != null) {
- Path resolvedPath = targetDir.resolve(entry.getName()).normalize();
-
- if (!resolvedPath.startsWith(targetDir)) {
- throw new SecurityException("Zip entry is outside of the target dir: " + entry.getName());
- }
-
- if (entry.isDirectory()) {
- Files.createDirectories(resolvedPath);
- } else {
- Path parentDir = resolvedPath.getParent();
- if (!Files.exists(parentDir)) {
- Files.createDirectories(parentDir);
+ try (FileOutputStream fos = new FileOutputStream(outputFile);
+ BufferedOutputStream bos = new BufferedOutputStream(fos);
+ GzipCompressorOutputStream gcos = new GzipCompressorOutputStream(bos);
+ TarArchiveOutputStream taos = new TarArchiveOutputStream(gcos)) {
+ taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
+ Stack stack = new Stack<>();
+ Stack pathStack = new Stack<>();
+ for (File file : files) {
+ if (file == null) continue;
+ stack.push(file);
+ pathStack.push("");
+ }
+ while (!stack.isEmpty()) {
+ File currentFile = stack.pop();
+ String path = pathStack.pop();
+ String entryName = path + currentFile.getName();
+ if (currentFile.isDirectory()) {
+ File[] dirFiles = currentFile.listFiles();
+ if (dirFiles != null) {
+ if (dirFiles.length == 0) {
+ TarArchiveEntry entry = new TarArchiveEntry(entryName + "/");
+ taos.putArchiveEntry(entry);
+ taos.closeArchiveEntry();
+ } else {
+ for (File child : dirFiles) {
+ stack.push(child);
+ pathStack.push(entryName + "/");
+ }
+ }
}
- try (OutputStream out = Files.newOutputStream(resolvedPath.toFile().toPath())) {
- byte[] buffer = new byte[4096];
- int length;
- while ((length = zipIn.read(buffer)) > 0) {
- out.write(buffer, 0, length);
+ } else {
+ TarArchiveEntry entry = new TarArchiveEntry(currentFile, entryName);
+ taos.putArchiveEntry(entry);
+ try (FileInputStream fis = new FileInputStream(currentFile)) {
+ byte[] buffer = new byte[1024];
+ int len;
+ while ((len = fis.read(buffer)) != -1) {
+ taos.write(buffer, 0, len);
}
}
+ taos.closeArchiveEntry();
}
- zipIn.closeEntry();
}
- } catch (IOException e) {
- log.error("Error while decompressing to zip", e);
- throw new RuntimeException("Failed to decompress ZIP file: " + zipFilePath, e);
}
}
- private static void decompress7z(File file, String outputPath) throws IOException {
- Path targetDir = Paths.get(outputPath).toAbsolutePath();
-
- try (SevenZFile sevenZFile = new SevenZFile(file)) {
- SevenZArchiveEntry entry = sevenZFile.getNextEntry();
- while (entry != null) {
- Path resolvedPath = targetDir.resolve(entry.getName()).normalize();
-
- if (!resolvedPath.startsWith(targetDir)) {
- throw new IOException("Entry is outside of the target dir: " + entry.getName());
+ private static void compressToJar(File[] files, String outputPath) throws IOException {
+ if (outputPath == null || outputPath.isEmpty()) {
+ throw new IllegalArgumentException("Output path is null or empty");
+ }
+ File outputFile = new File(outputPath);
+ if (outputFile.exists()) {
+ throw new IOException("Output file already exists");
+ }
+ try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(outputFile.toPath()))) {
+ byte[] buffer = new byte[1024];
+ for (File file : files) {
+ if (file == null || !file.exists()) {
+ continue;
}
-
- if (entry.isDirectory()) {
- Files.createDirectories(resolvedPath);
- } else {
- File outputFile = resolvedPath.toFile();
- File parentDir = outputFile.getParentFile();
- if (!parentDir.exists() && !parentDir.mkdirs()) {
- throw new IOException("Failed to create directory: " + parentDir);
- }
-
- try (FileOutputStream out = new FileOutputStream(outputFile)) {
- byte[] content = new byte[(int) entry.getSize()];
- sevenZFile.read(content, 0, content.length);
- out.write(content);
+ String basePath = file.isDirectory() ? file.getCanonicalPath() : file.getParentFile().getCanonicalPath();
+ Stack stack = new Stack<>();
+ stack.push(file);
+ while (!stack.isEmpty()) {
+ File currentFile = stack.pop();
+ String entryName = currentFile.getCanonicalPath().substring(basePath.length() + 1).replace("\\", "/");
+ if (currentFile.isDirectory()) {
+ File[] subFiles = currentFile.listFiles();
+ if (subFiles != null) {
+ for (File subFile : subFiles) {
+ stack.push(subFile);
+ }
+ }
+ if (!entryName.isEmpty()) {
+ if (!entryName.endsWith("/")) {
+ entryName += "/";
+ }
+ jos.putNextEntry(new JarEntry(entryName));
+ jos.closeEntry();
+ }
+ } else {
+ FileInputStream fis = null;
+ try {
+ jos.putNextEntry(new JarEntry(entryName));
+ fis = new FileInputStream(currentFile);
+ int len;
+ while ((len = fis.read(buffer)) > 0) {
+ jos.write(buffer, 0, len);
+ }
+ jos.closeEntry();
+ } finally {
+ if (fis != null) {
+ fis.close();
+ }
+ }
}
}
- entry = sevenZFile.getNextEntry();
}
}
}
- private static void decompressTar(File file, String outputPath) throws IOException {
- Path targetDir = Paths.get(outputPath).toAbsolutePath();
- try (InputStream fi = Files.newInputStream(file.toPath());
- TarArchiveInputStream ti = new TarArchiveInputStream(fi)) {
- TarArchiveEntry entry;
- while ((entry = ti.getNextTarEntry()) != null) {
- File outputFile = targetDir.resolve(entry.getName()).normalize().toFile();
- if (!outputFile.toPath().startsWith(targetDir)) {
- throw new IOException("Entry is outside of the target directory: " + entry.getName());
+ private static void decompressZip(File archive, String directory) throws IOException {
+ byte[] buffer = new byte[1024];
+ ZipInputStream zis = new ZipInputStream(Files.newInputStream(archive.toPath()));
+ ZipEntry zipEntry = zis.getNextEntry();
+ while (zipEntry != null) {
+ File newFile = new File(directory, zipEntry.getName());
+ if (zipEntry.isDirectory()) {
+ if (!newFile.isDirectory() && !newFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + newFile);
}
- if (entry.isDirectory() && !outputFile.exists() && !outputFile.mkdirs()) {
- throw new IOException("Failed to create directory: " + outputFile);
- } else {
- File parent = outputFile.getParentFile();
- if (!parent.exists() && !parent.mkdirs()) {
- throw new IOException("Failed to create directory: " + parent);
- }
- try (OutputStream out = new FileOutputStream(outputFile)) {
- IOUtils.copy(ti, out);
- }
+ } else {
+ File parent = newFile.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory " + parent);
+ }
+ FileOutputStream fos = new FileOutputStream(newFile);
+ int len;
+ while ((len = zis.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
}
+ fos.close();
}
+ zipEntry = zis.getNextEntry();
}
+ zis.closeEntry();
+ zis.close();
}
- private static void decompressGzip(File inputFile, String outputPath) throws IOException {
- File outputDir = new File(outputPath);
- if (!outputDir.exists() && !outputDir.mkdirs()) {
- throw new IOException("Failed to create the output directory: " + outputDir.getAbsolutePath());
- }
- String outputFileName = inputFile.getName();
- if (outputFileName.endsWith(".gz"))
- outputFileName = outputFileName.substring(0, outputFileName.length() - 3);
- else
- throw new IllegalArgumentException("The input file does not have a .gz extension.");
- File outputFile = new File(outputDir, outputFileName);
- try (FileInputStream fis = new FileInputStream(inputFile);
- GZIPInputStream gzis = new GZIPInputStream(fis);
- FileOutputStream fos = new FileOutputStream(outputFile)) {
- byte[] buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = gzis.read(buffer)) != -1) {
- fos.write(buffer, 0, bytesRead);
+ private static void decompress7z(File archive, String directory) throws IOException {
+ SevenZFile sevenZFile = new SevenZFile(archive);
+ SevenZArchiveEntry entry;
+ byte[] buffer = new byte[8192];
+ while ((entry = sevenZFile.getNextEntry()) != null) {
+ File newFile = new File(directory, entry.getName());
+ if (entry.isDirectory()) {
+ if (!newFile.isDirectory() && !newFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + newFile);
+ }
+ } else {
+ File parent = newFile.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory " + parent);
+ }
+ OutputStream out = Files.newOutputStream(newFile.toPath());
+ int bytesRead;
+ while ((bytesRead = sevenZFile.read(buffer)) != -1) {
+ out.write(buffer, 0, bytesRead);
+ }
+ out.close();
}
}
+ sevenZFile.close();
}
- private static void compressToJar(File[] files, String outputPath) throws IOException {
- FileOutputStream fos = new FileOutputStream(outputPath);
- JarOutputStream jos = new JarOutputStream(fos);
- for (File file : files) {
- addFileToJar("", file, jos);
- }
- jos.close();
- fos.close();
- }
-
- private static void addFileToJar(String parent, File file, JarOutputStream jos) throws IOException {
- if (file.isHidden()) {
- log.error("{} is a hidden file and cannot be compressed", file.getAbsolutePath());
- return;
- }
- String entryName = parent + file.getName();
- if (file.isDirectory()) {
- if (!entryName.endsWith("/")) {
- entryName += "/";
- }
- JarEntry entry = new JarEntry(entryName);
- entry.setTime(file.lastModified());
- jos.putNextEntry(entry);
- jos.closeEntry();
- for (File nestedFile : Objects.requireNonNull(file.listFiles())) {
- addFileToJar(entryName, nestedFile, jos);
- }
- } else {
- FileInputStream fis = new FileInputStream(file);
- JarEntry entry = new JarEntry(entryName);
- entry.setTime(file.lastModified());
- jos.putNextEntry(entry);
- byte[] buffer = new byte[1024];
- int count;
- while ((count = fis.read(buffer)) != -1) {
- jos.write(buffer, 0, count);
+ private static void decompressTar(File archive, String directory) throws IOException {
+ TarArchiveInputStream tis = new TarArchiveInputStream(Files.newInputStream(archive.toPath()));
+ TarArchiveEntry entry;
+ byte[] buffer = new byte[8192];
+ while ((entry = tis.getNextTarEntry()) != null) {
+ File newFile = new File(directory, entry.getName());
+ if (entry.isDirectory()) {
+ if (!newFile.isDirectory() && !newFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + newFile);
+ }
+ } else {
+ File parent = newFile.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory " + parent);
+ }
+ OutputStream out = Files.newOutputStream(newFile.toPath());
+ int len;
+ while ((len = tis.read(buffer)) != -1) {
+ out.write(buffer, 0, len);
+ }
+ out.close();
}
- jos.closeEntry();
- fis.close();
}
+ tis.close();
}
- public static void decompressJar(File jarFile, String outputPath) throws IOException {
- if (!jarFile.exists()) {
- throw new IOException("The jar file does not exist.");
+ private static void decompressGzip(File archive, String directory) throws IOException {
+ byte[] buffer = new byte[8192];
+ InputStream fi = Files.newInputStream(archive.toPath());
+ InputStream bi = new BufferedInputStream(fi);
+ InputStream gzi = new GzipCompressorInputStream(bi);
+ String fileName = archive.getName();
+ if (fileName.endsWith(".gz")) {
+ fileName = fileName.substring(0, fileName.length() - 3);
}
- File outputDir = new File(outputPath);
- if (!outputDir.exists() && !outputDir.mkdirs()) {
- throw new IOException("Failed to create output directory.");
+ File outputFile = new File(directory, fileName);
+ File parent = outputFile.getParentFile();
+ if (!parent.exists()) {
+ parent.mkdirs();
}
- try (JarInputStream jis = new JarInputStream(Files.newInputStream(jarFile.toPath()))) {
- JarEntry entry;
- byte[] buffer = new byte[1024];
- while ((entry = jis.getNextJarEntry()) != null) {
- File outputFile = new File(outputDir, entry.getName());
- if (entry.isDirectory() && !outputFile.exists() && !outputFile.mkdirs()) {
- throw new IOException("Failed to create directory " + outputFile.getAbsolutePath());
- } else {
- try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- int len;
- while ((len = jis.read(buffer)) > 0) {
- fos.write(buffer, 0, len);
- }
- }
- }
- jis.closeEntry();
- }
+ OutputStream fo = Files.newOutputStream(outputFile.toPath());
+ int len;
+ while ((len = gzi.read(buffer)) != -1) {
+ fo.write(buffer, 0, len);
}
+ fo.close();
+ gzi.close();
}
- public static void decompressRar(File rarFile, String destinationPath) throws RarException, IOException{
- Junrar.extract(rarFile, new File(destinationPath));
- }
-
- private static CompressionFormat getCompressionFormat(String format) {
- try {
- return CompressionFormat.valueOf(format.toUpperCase());
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Invalid compression format: " + format + ". Valid formats are (upper or lower): GZIP,TAR, ZIP, SEVENZ and JAR");
+ private static void decompressJar(File archive, String directory) throws IOException {
+ byte[] buffer = new byte[1024];
+ JarFile jarFile = new JarFile(archive);
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ File newFile = new File(directory, entry.getName());
+ if (entry.isDirectory()) {
+ if (!newFile.isDirectory() && !newFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + newFile);
+ }
+ } else {
+ File parent = newFile.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory " + parent);
+ }
+ InputStream is = jarFile.getInputStream(entry);
+ FileOutputStream fos = new FileOutputStream(newFile);
+ int len;
+ while ((len = is.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ }
+ fos.close();
+ is.close();
+ }
}
+ jarFile.close();
}
-
}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index bb428b87b..eeb1e58b7 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -6,8 +6,7 @@
import java.util.ArrayList;
public interface IGXCompressor {
- static Boolean compressFiles(ArrayList files, String path, String format, GXBaseCollection[] messages) {return false;}
- static Boolean compressFolder(String folder, String path, String format, GXBaseCollection[] messages) {return false;}
- static Compression newCompression(String path, String format, int dictionarySize, GXBaseCollection[] messages) { return new Compression();}
+ static Boolean compress(ArrayList files, String path, GXBaseCollection[] messages) {return false;}
+ static Compression newCompression(String path, GXBaseCollection[] messages) { return new Compression();}
static Boolean decompress(String file, String path, GXBaseCollection[] messages) {return false;}
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 8831ff8f8..3555788ad 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -53,7 +53,7 @@ public void tearDown() {
@Test
public void testCompressToZip() {
String outputPath = new File(testDirectory, "output.zip").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "ZIP", msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -61,7 +61,7 @@ public void testCompressToZip() {
@Test
public void testCompressToSevenZ() {
String outputPath = new File(testDirectory, "output.7z").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "SEVENZ", msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -69,7 +69,7 @@ public void testCompressToSevenZ() {
@Test
public void testCompressToTar() {
String outputPath = new File(testDirectory, "output.tar").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "TAR", msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -79,7 +79,7 @@ public void testCompressToGzip() {
String outputPath = new File(testDirectory, "output.gz").getAbsolutePath();
ArrayList singleFileCollection = new ArrayList<>();
singleFileCollection.add(files.get(0));
- Boolean result = GXCompressor.compressFiles(singleFileCollection, outputPath, "GZIP", msgs);
+ Boolean result = GXCompressor.compress(singleFileCollection, outputPath, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -87,7 +87,7 @@ public void testCompressToGzip() {
@Test
public void testCompressToJar() {
String outputPath = new File(testDirectory, "output.jar").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "JAR", msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -95,7 +95,7 @@ public void testCompressToJar() {
@Test
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
- Boolean result = GXCompressor.compressFiles(files, outputPath, "UNKNOWN", msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, msgs);
assertFalse(result);
}
}
From 7a6d936b1fad6237af81b3ceeaca4b88dc79fd4e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 12 Nov 2024 11:08:25 +0900
Subject: [PATCH 36/49] Prevent directory traversal attack
---
.../com/genexus/compression/GXCompressor.java | 21 ++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 2aae9fe13..61ed2ebf4 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -61,12 +61,23 @@ public static Boolean compress(ArrayList files, String path, GXBaseColle
int index = 0;
for (String filePath : files) {
File file = new File(filePath);
- if (!file.exists()) {
- log.error("{}{}", FILE_NOT_EXISTS, filePath);
- storageMessages(FILE_NOT_EXISTS + filePath, messages[0]);
- continue;
+ try {
+ String normalizedPath = file.getCanonicalPath();
+ if (!file.exists()) {
+ log.error("{}{}", FILE_NOT_EXISTS, filePath);
+ storageMessages(FILE_NOT_EXISTS + filePath, messages[0]);
+ continue;
+ }
+ if (normalizedPath.contains(File.separator + ".." + File.separator) ||
+ normalizedPath.endsWith(File.separator + "..") ||
+ normalizedPath.startsWith(".." + File.separator)) {
+ log.warn("Potential directory traversal attack detected: {}", filePath);
+ continue;
+ }
+ toCompress[index++] = file;
+ } catch (IOException e) {
+ log.error("Error normalizing path for file: {}", filePath, e);
}
- toCompress[index++] = file;
}
String format = CommonUtil.getFileType(path).toLowerCase();
try {
From c2d49847b75b72b3b1315c0cdb43370118efe6ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 18 Nov 2024 12:11:06 +0900
Subject: [PATCH 37/49] Add check for DoS attack and clear error messages
---
.../com/genexus/compression/GXCompressor.java | 31 ++++++++++++-------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 61ed2ebf4..a13f6e683 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -34,9 +34,10 @@ public class GXCompressor implements IGXCompressor {
private static final String GENERIC_ERROR = "An error occurred during the compression/decompression process: ";
private static final String NO_FILES_ADDED = "No files have been added for compression.";
private static final String FILE_NOT_EXISTS = "File does not exist: ";
- private static final String FOLDER_NOT_EXISTS = "The specified folder does not exist: ";
- private static final String UNSUPPORTED_FORMAT = "Unsupported compression/decompression format: ";
+ private static final String UNSUPPORTED_FORMAT = " is an unsupported format. Supported formats are zip, 7z, tar, gz and jar.";
private static final String EMPTY_FILE = "The selected file is empty: ";
+ private static final String DIRECTORY_ATTACK = "Potential directory traversal attack detected: ";
+ private static final String MAX_FILESIZE_EXCEEDED = "The files selected for compression exceed the maximum permitted file size of ";
private static void storageMessages(String error, GXBaseCollection messages) {
try {
@@ -48,15 +49,15 @@ private static void storageMessages(String error, GXBaseCollection files, String path, GXBaseCollection[] messages) {
+ public static Boolean compress(ArrayList files, String path, long maxCombinedFileSize, GXBaseCollection[] messages) {
if (files.isEmpty()){
log.error(NO_FILES_ADDED);
storageMessages(NO_FILES_ADDED, messages[0]);
return false;
}
+ long totalSize = 0;
File[] toCompress = new File[files.size()];
int index = 0;
for (String filePath : files) {
@@ -71,8 +72,16 @@ public static Boolean compress(ArrayList files, String path, GXBaseColle
if (normalizedPath.contains(File.separator + ".." + File.separator) ||
normalizedPath.endsWith(File.separator + "..") ||
normalizedPath.startsWith(".." + File.separator)) {
- log.warn("Potential directory traversal attack detected: {}", filePath);
- continue;
+ log.error(DIRECTORY_ATTACK + "{}", filePath);
+ storageMessages(DIRECTORY_ATTACK + filePath, messages[0]);
+ return false;
+ }
+ long fileSize = file.length();
+ totalSize += fileSize;
+ if (totalSize > maxCombinedFileSize) {
+ log.error(MAX_FILESIZE_EXCEEDED + "{}", maxCombinedFileSize);
+ storageMessages(MAX_FILESIZE_EXCEEDED + maxCombinedFileSize, messages[0]);
+ return false;
}
toCompress[index++] = file;
} catch (IOException e) {
@@ -98,13 +107,11 @@ public static Boolean compress(ArrayList files, String path, GXBaseColle
compressToJar(toCompress, path);
break;
default:
+ log.error("{}" + UNSUPPORTED_FORMAT, format);
+ storageMessages(format + UNSUPPORTED_FORMAT, messages[0]);
return false;
}
return true;
- } catch (IllegalArgumentException iae) {
- log.error("{}{}. Supported compression formats are zip, 7z, tar, gz and jar", UNSUPPORTED_FORMAT, format, iae);
- storageMessages(UNSUPPORTED_FORMAT + format, messages[0]);
- return false;
} catch (Exception e) {
log.error(GENERIC_ERROR, e);
storageMessages(e.getMessage(), messages[0]);
@@ -147,8 +154,8 @@ public static Boolean decompress(String file, String path, GXBaseCollection
Date: Mon, 18 Nov 2024 12:51:21 +0900
Subject: [PATCH 38/49] Fix compilation error
---
.../java/com/genexus/compression/Compression.java | 6 ++++--
.../java/com/genexus/compression/GXCompressor.java | 6 +++---
.../java/com/genexus/compression/IGXCompressor.java | 4 ++--
.../com/genexus/compression/TestCompression.java | 12 ++++++------
4 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 8b656fea5..6a9860cda 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -15,13 +15,15 @@ public class Compression {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Compression.class);
private String absolutePath;
+ private long maxCombinedFileSize;
private GXBaseCollection[] messages;
private ArrayList filesToCompress;
public Compression() {}
- public Compression(String absolutePath, GXBaseCollection[] messages) {
+ public Compression(String absolutePath, long maxCombinedFileSize, GXBaseCollection[] messages) {
this.absolutePath = absolutePath;
+ this.maxCombinedFileSize = maxCombinedFileSize;
this.messages = messages;
filesToCompress = new ArrayList<>();
}
@@ -35,7 +37,7 @@ public void addElement(String filePath) {
}
public Boolean save() {
- return GXCompressor.compress(filesToCompress, absolutePath, messages);
+ return GXCompressor.compress(filesToCompress, absolutePath, maxCombinedFileSize, messages);
}
public void clear() {
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index a13f6e683..f910662af 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -78,7 +78,7 @@ public static Boolean compress(ArrayList files, String path, long maxCom
}
long fileSize = file.length();
totalSize += fileSize;
- if (totalSize > maxCombinedFileSize) {
+ if (totalSize > maxCombinedFileSize && maxCombinedFileSize > -1) {
log.error(MAX_FILESIZE_EXCEEDED + "{}", maxCombinedFileSize);
storageMessages(MAX_FILESIZE_EXCEEDED + maxCombinedFileSize, messages[0]);
return false;
@@ -119,8 +119,8 @@ public static Boolean compress(ArrayList files, String path, long maxCom
}
}
- public static Compression newCompression(String path, GXBaseCollection[] messages) {
- return new Compression(path, messages);
+ public static Compression newCompression(String path, long maxCombinedFileSize, GXBaseCollection[] messages) {
+ return new Compression(path, maxCombinedFileSize, messages);
}
public static Boolean decompress(String file, String path, GXBaseCollection[] messages) {
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
index eeb1e58b7..2dc308a97 100644
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
@@ -6,7 +6,7 @@
import java.util.ArrayList;
public interface IGXCompressor {
- static Boolean compress(ArrayList files, String path, GXBaseCollection[] messages) {return false;}
- static Compression newCompression(String path, GXBaseCollection[] messages) { return new Compression();}
+ static Boolean compress(ArrayList files, String path, long maxCombinedFileSize, GXBaseCollection[] messages) {return false;}
+ static Compression newCompression(String path, long maxCombinedFileSize, GXBaseCollection[] messages) { return new Compression();}
static Boolean decompress(String file, String path, GXBaseCollection[] messages) {return false;}
}
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 3555788ad..4a8cec4c7 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -53,7 +53,7 @@ public void tearDown() {
@Test
public void testCompressToZip() {
String outputPath = new File(testDirectory, "output.zip").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -61,7 +61,7 @@ public void testCompressToZip() {
@Test
public void testCompressToSevenZ() {
String outputPath = new File(testDirectory, "output.7z").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -69,7 +69,7 @@ public void testCompressToSevenZ() {
@Test
public void testCompressToTar() {
String outputPath = new File(testDirectory, "output.tar").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -79,7 +79,7 @@ public void testCompressToGzip() {
String outputPath = new File(testDirectory, "output.gz").getAbsolutePath();
ArrayList singleFileCollection = new ArrayList<>();
singleFileCollection.add(files.get(0));
- Boolean result = GXCompressor.compress(singleFileCollection, outputPath, msgs);
+ Boolean result = GXCompressor.compress(singleFileCollection, outputPath, -1, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -87,7 +87,7 @@ public void testCompressToGzip() {
@Test
public void testCompressToJar() {
String outputPath = new File(testDirectory, "output.jar").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -95,7 +95,7 @@ public void testCompressToJar() {
@Test
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
assertFalse(result);
}
}
From a396d40a36afc925dab80532e540f59745640a57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Thu, 9 Jan 2025 10:34:13 -0300
Subject: [PATCH 39/49] Fix gz compression and decompression issues
---
.../com/genexus/compression/GXCompressor.java | 276 ++++++++++++------
1 file changed, 191 insertions(+), 85 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index f910662af..b03aaf0cf 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -4,8 +4,8 @@
import com.genexus.GXBaseCollection;
import com.genexus.SdtMessages_Message;
import com.genexus.StructSdtMessages_Message;
-import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipParameters;
import org.apache.logging.log4j.Logger;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
@@ -18,10 +18,9 @@
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.Stack;
import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.zip.*;
@@ -287,62 +286,106 @@ private static void addFileToTar(TarArchiveOutputStream tarOut, File file, Strin
}
private static void compressToGzip(File[] files, String outputPath) throws IOException {
+ if (files == null || files.length == 0) {
+ throw new IllegalArgumentException("No files to compress");
+ }
if (outputPath == null || outputPath.isEmpty()) {
throw new IllegalArgumentException("Output path is null or empty");
}
File outputFile = new File(outputPath);
if (outputFile.exists() && !outputFile.canWrite()) {
throw new IOException("Cannot write to output file");
- } else {
- File parentDir = outputFile.getParentFile();
- if (parentDir != null && !parentDir.exists() && !parentDir.mkdirs()) {
- throw new IOException("Failed to create output directory");
- }
}
- try (FileOutputStream fos = new FileOutputStream(outputFile);
- BufferedOutputStream bos = new BufferedOutputStream(fos);
- GzipCompressorOutputStream gcos = new GzipCompressorOutputStream(bos);
- TarArchiveOutputStream taos = new TarArchiveOutputStream(gcos)) {
- taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
- Stack stack = new Stack<>();
- Stack pathStack = new Stack<>();
- for (File file : files) {
- if (file == null) continue;
- stack.push(file);
- pathStack.push("");
+ File parentDir = outputFile.getParentFile();
+ if (parentDir != null && !parentDir.exists() && !parentDir.mkdirs()) {
+ throw new IOException("Failed to create output directory");
+ }
+ boolean singleFile = files.length == 1 && files[0].isFile();
+ File tempFile = File.createTempFile("compress_", ".tmp", parentDir);
+ if (singleFile) {
+ try (
+ FileInputStream fis = new FileInputStream(files[0]);
+ FileOutputStream fos = new FileOutputStream(tempFile);
+ BufferedOutputStream bos = new BufferedOutputStream(fos);
+ GzipCompressorOutputStream gcos = new GzipCompressorOutputStream(bos)
+ ) {
+ byte[] buffer = new byte[8192];
+ int len;
+ while ((len = fis.read(buffer)) != -1) {
+ gcos.write(buffer, 0, len);
+ }
}
- while (!stack.isEmpty()) {
- File currentFile = stack.pop();
- String path = pathStack.pop();
- String entryName = path + currentFile.getName();
- if (currentFile.isDirectory()) {
- File[] dirFiles = currentFile.listFiles();
- if (dirFiles != null) {
- if (dirFiles.length == 0) {
+ } else {
+ try (
+ FileOutputStream fos = new FileOutputStream(tempFile);
+ BufferedOutputStream bos = new BufferedOutputStream(fos);
+ GzipCompressorOutputStream gcos = new GzipCompressorOutputStream(bos);
+ TarArchiveOutputStream taos = new TarArchiveOutputStream(gcos)
+ ) {
+ taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
+ Stack fileStack = new Stack<>();
+ Stack pathStack = new Stack<>();
+ for (File f : files) {
+ if (f != null) {
+ fileStack.push(f);
+ pathStack.push("");
+ }
+ }
+ while (!fileStack.isEmpty()) {
+ File currentFile = fileStack.pop();
+ String path = pathStack.pop();
+ String entryName = path + currentFile.getName();
+ if (currentFile.isDirectory()) {
+ File[] children = currentFile.listFiles();
+ if (children != null && children.length > 0) {
+ for (File child : children) {
+ fileStack.push(child);
+ pathStack.push(entryName + "/");
+ }
+ } else {
TarArchiveEntry entry = new TarArchiveEntry(entryName + "/");
taos.putArchiveEntry(entry);
taos.closeArchiveEntry();
- } else {
- for (File child : dirFiles) {
- stack.push(child);
- pathStack.push(entryName + "/");
- }
}
- }
- } else {
- TarArchiveEntry entry = new TarArchiveEntry(currentFile, entryName);
- taos.putArchiveEntry(entry);
- try (FileInputStream fis = new FileInputStream(currentFile)) {
- byte[] buffer = new byte[1024];
- int len;
- while ((len = fis.read(buffer)) != -1) {
- taos.write(buffer, 0, len);
+ } else {
+ TarArchiveEntry entry = new TarArchiveEntry(currentFile, entryName);
+ taos.putArchiveEntry(entry);
+ try (FileInputStream fis = new FileInputStream(currentFile)) {
+ byte[] buffer = new byte[8192];
+ int len;
+ while ((len = fis.read(buffer)) != -1) {
+ taos.write(buffer, 0, len);
+ }
}
+ taos.closeArchiveEntry();
}
- taos.closeArchiveEntry();
}
}
}
+ if (!tempFile.exists()) {
+ throw new IOException("Failed to create the archive");
+ }
+ String finalName = outputPath;
+ if (singleFile) {
+ if (!finalName.toLowerCase().endsWith(".gz")) {
+ finalName += ".gz";
+ }
+ } else {
+ if (finalName.toLowerCase().endsWith(".tar.gz")) {
+ // do nothing
+ } else if (finalName.toLowerCase().endsWith(".gz")) {
+ finalName = finalName.substring(0, finalName.length() - 3) + ".tar.gz";
+ } else {
+ finalName += ".tar.gz";
+ }
+ }
+ File finalFile = new File(finalName);
+ if (finalFile.exists() && !finalFile.delete()) {
+ throw new IOException("Failed to delete existing file with desired name");
+ }
+ if (!tempFile.renameTo(finalFile)) {
+ throw new IOException("Failed to rename archive to desired name");
+ }
}
private static void compressToJar(File[] files, String outputPath) throws IOException {
@@ -481,54 +524,117 @@ private static void decompressTar(File archive, String directory) throws IOExcep
}
private static void decompressGzip(File archive, String directory) throws IOException {
- byte[] buffer = new byte[8192];
- InputStream fi = Files.newInputStream(archive.toPath());
- InputStream bi = new BufferedInputStream(fi);
- InputStream gzi = new GzipCompressorInputStream(bi);
- String fileName = archive.getName();
- if (fileName.endsWith(".gz")) {
- fileName = fileName.substring(0, fileName.length() - 3);
- }
- File outputFile = new File(directory, fileName);
- File parent = outputFile.getParentFile();
- if (!parent.exists()) {
- parent.mkdirs();
- }
- OutputStream fo = Files.newOutputStream(outputFile.toPath());
- int len;
- while ((len = gzi.read(buffer)) != -1) {
- fo.write(buffer, 0, len);
- }
- fo.close();
- gzi.close();
- }
+ if (!archive.exists() || !archive.isFile()) {
+ throw new IllegalArgumentException("The archive file does not exist or is not a file.");
+ }
+ File targetDir = new File(directory);
+ if (!targetDir.exists() || !targetDir.isDirectory()) {
+ throw new IllegalArgumentException("The specified directory does not exist or is not a directory.");
+ }
+ File tempFile = File.createTempFile("decompressed_", ".tmp");
+ try (
+ FileInputStream fis = new FileInputStream(archive);
+ GZIPInputStream gzipInputStream = new GZIPInputStream(fis);
+ FileOutputStream fos = new FileOutputStream(tempFile)
+ ) {
+ byte[] buffer = new byte[8192];
+ int len;
+ while ((len = gzipInputStream.read(buffer)) != -1) {
+ fos.write(buffer, 0, len);
+ }
+ }
- private static void decompressJar(File archive, String directory) throws IOException {
- byte[] buffer = new byte[1024];
- JarFile jarFile = new JarFile(archive);
- Enumeration entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
- File newFile = new File(directory, entry.getName());
- if (entry.isDirectory()) {
- if (!newFile.isDirectory() && !newFile.mkdirs()) {
- throw new IOException("Failed to create directory " + newFile);
+ boolean isTar = false;
+ try (FileInputStream tempFis = new FileInputStream(tempFile);
+ TarArchiveInputStream testTar = new TarArchiveInputStream(tempFis)) {
+ TarArchiveEntry testEntry = testTar.getNextTarEntry();
+ if (testEntry != null) {
+ isTar = true;
+ }
+ } catch (IOException ignored) {}
+ if (isTar) {
+ try (FileInputStream tarFis = new FileInputStream(tempFile);
+ TarArchiveInputStream tarInput = new TarArchiveInputStream(tarFis)) {
+
+ TarArchiveEntry entry;
+ while ((entry = tarInput.getNextTarEntry()) != null) {
+ File outFile = new File(targetDir, entry.getName());
+ if (entry.isDirectory()) {
+ if (!outFile.exists() && !outFile.mkdirs()) {
+ throw new IOException("Failed to create directory: " + outFile);
+ }
+ } else {
+ File parent = outFile.getParentFile();
+ if (!parent.exists() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory: " + parent);
+ }
+ try (FileOutputStream os = new FileOutputStream(outFile)) {
+ byte[] buffer = new byte[8192];
+ int count;
+ while ((count = tarInput.read(buffer)) != -1) {
+ os.write(buffer, 0, count);
+ }
+ }
+ }
}
- } else {
- File parent = newFile.getParentFile();
- if (!parent.isDirectory() && !parent.mkdirs()) {
- throw new IOException("Failed to create directory " + parent);
+ }
+ } else {
+ String name = archive.getName();
+ if (name.toLowerCase().endsWith(".gz")) {
+ name = name.substring(0, name.length() - 3);
+ }
+ File singleOutFile = new File(targetDir, name);
+ if (!tempFile.renameTo(singleOutFile)) {
+ try (
+ FileInputStream in = new FileInputStream(tempFile);
+ FileOutputStream out = new FileOutputStream(singleOutFile)
+ ) {
+ byte[] buffer = new byte[8192];
+ int len;
+ while ((len = in.read(buffer)) != -1) {
+ out.write(buffer, 0, len);
+ }
}
- InputStream is = jarFile.getInputStream(entry);
- FileOutputStream fos = new FileOutputStream(newFile);
- int len;
- while ((len = is.read(buffer)) > 0) {
- fos.write(buffer, 0, len);
+ }
+ }
+ if (!tempFile.delete()) {
+ tempFile.deleteOnExit();
+ }
+ }
+
+ private static void decompressJar(File archive, String directory) throws IOException {
+ if (!archive.exists() || !archive.isFile()) {
+ throw new IOException("Invalid archive file.");
+ }
+ File targetDir = new File(directory);
+ if (!targetDir.exists()) {
+ if (!targetDir.mkdirs()) {
+ throw new IOException("Failed to create target directory.");
+ }
+ }
+ try (JarInputStream jarInputStream = new JarInputStream(Files.newInputStream(archive.toPath()))) {
+ JarEntry entry;
+ while ((entry = jarInputStream.getNextJarEntry()) != null) {
+ File outputFile = new File(targetDir, entry.getName());
+ if (entry.isDirectory()) {
+ if (!outputFile.exists() && !outputFile.mkdirs()) {
+ throw new IOException("Failed to create directory: " + outputFile.getAbsolutePath());
+ }
+ } else {
+ File parent = outputFile.getParentFile();
+ if (!parent.exists() && !parent.mkdirs()) {
+ throw new IOException("Failed to create parent directory: " + parent.getAbsolutePath());
+ }
+ try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = jarInputStream.read(buffer)) != -1) {
+ fos.write(buffer, 0, bytesRead);
+ }
+ }
}
- fos.close();
- is.close();
+ jarInputStream.closeEntry();
}
}
- jarFile.close();
}
}
\ No newline at end of file
From 7c92b6ee5bd1ecf3cab2185014c5f216ca8d1a1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 26 Feb 2025 09:48:33 -0300
Subject: [PATCH 40/49] Remove unused imports
---
.../src/main/java/com/genexus/compression/Compression.java | 5 -----
1 file changed, 5 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 6a9860cda..329092c0d 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -4,12 +4,7 @@
import com.genexus.SdtMessages_Message;
import org.apache.logging.log4j.Logger;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
-import java.util.stream.Stream;
public class Compression {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Compression.class);
From efa196e0110aa15628bdf59f93c2b86ff8111ede Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 19 Mar 2025 15:24:03 -0300
Subject: [PATCH 41/49] Remove unused import and usage of deprecated method
---
.../main/java/com/genexus/compression/GXCompressor.java | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index b03aaf0cf..51c167f5e 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -5,7 +5,6 @@
import com.genexus.SdtMessages_Message;
import com.genexus.StructSdtMessages_Message;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
-import org.apache.commons.compress.compressors.gzip.GzipParameters;
import org.apache.logging.log4j.Logger;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
@@ -501,7 +500,7 @@ private static void decompressTar(File archive, String directory) throws IOExcep
TarArchiveInputStream tis = new TarArchiveInputStream(Files.newInputStream(archive.toPath()));
TarArchiveEntry entry;
byte[] buffer = new byte[8192];
- while ((entry = tis.getNextTarEntry()) != null) {
+ while ((entry = tis.getNextEntry()) != null) {
File newFile = new File(directory, entry.getName());
if (entry.isDirectory()) {
if (!newFile.isDirectory() && !newFile.mkdirs()) {
@@ -547,7 +546,7 @@ private static void decompressGzip(File archive, String directory) throws IOExce
boolean isTar = false;
try (FileInputStream tempFis = new FileInputStream(tempFile);
TarArchiveInputStream testTar = new TarArchiveInputStream(tempFis)) {
- TarArchiveEntry testEntry = testTar.getNextTarEntry();
+ TarArchiveEntry testEntry = testTar.getNextEntry();
if (testEntry != null) {
isTar = true;
}
@@ -557,7 +556,7 @@ private static void decompressGzip(File archive, String directory) throws IOExce
TarArchiveInputStream tarInput = new TarArchiveInputStream(tarFis)) {
TarArchiveEntry entry;
- while ((entry = tarInput.getNextTarEntry()) != null) {
+ while ((entry = tarInput.getNextEntry()) != null) {
File outFile = new File(targetDir, entry.getName());
if (entry.isDirectory()) {
if (!outFile.exists() && !outFile.mkdirs()) {
From 81d6fa6ccd0ae40489f249911cab1cb84c8b16ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Fri, 28 Mar 2025 12:15:53 -0300
Subject: [PATCH 42/49] Prevent slips, traversals and bombs
---
.../com/genexus/compression/GXCompressor.java | 46 ++++++++++++++++---
1 file changed, 39 insertions(+), 7 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 51c167f5e..baa6ffc27 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -35,7 +35,10 @@ public class GXCompressor implements IGXCompressor {
private static final String UNSUPPORTED_FORMAT = " is an unsupported format. Supported formats are zip, 7z, tar, gz and jar.";
private static final String EMPTY_FILE = "The selected file is empty: ";
private static final String DIRECTORY_ATTACK = "Potential directory traversal attack detected: ";
- private static final String MAX_FILESIZE_EXCEEDED = "The files selected for compression exceed the maximum permitted file size of ";
+ private static final String MAX_FILESIZE_EXCEEDED = "The file(s) selected for (de)compression exceed the maximum permitted file size of ";
+ private static final String TOO_MANY_FILES = "Too many files have been added for (de)compression. Maximum allowed is ";
+ private static final String ZIP_SLIP_DETECTED = "Zip slip or path traversal attack detected in archive: ";
+ private static final int MAX_FILES_ALLOWED = 1000;
private static void storageMessages(String error, GXBaseCollection messages) {
try {
@@ -55,6 +58,12 @@ public static Boolean compress(ArrayList files, String path, long maxCom
storageMessages(NO_FILES_ADDED, messages[0]);
return false;
}
+ if(maxCombinedFileSize > -1 && files.size() > MAX_FILES_ALLOWED){
+ log.error(TOO_MANY_FILES + MAX_FILES_ALLOWED);
+ storageMessages(TOO_MANY_FILES + MAX_FILES_ALLOWED, messages[0]);
+ files.clear();
+ return false;
+ }
long totalSize = 0;
File[] toCompress = new File[files.size()];
int index = 0;
@@ -67,18 +76,18 @@ public static Boolean compress(ArrayList files, String path, long maxCom
storageMessages(FILE_NOT_EXISTS + filePath, messages[0]);
continue;
}
- if (normalizedPath.contains(File.separator + ".." + File.separator) ||
- normalizedPath.endsWith(File.separator + "..") ||
- normalizedPath.startsWith(".." + File.separator)) {
+ if (!normalizedPath.equals(file.getAbsolutePath())) {
log.error(DIRECTORY_ATTACK + "{}", filePath);
storageMessages(DIRECTORY_ATTACK + filePath, messages[0]);
return false;
}
long fileSize = file.length();
totalSize += fileSize;
- if (totalSize > maxCombinedFileSize && maxCombinedFileSize > -1) {
- log.error(MAX_FILESIZE_EXCEEDED + "{}", maxCombinedFileSize);
+ if (maxCombinedFileSize > -1 && totalSize > maxCombinedFileSize) {
+ log.error(MAX_FILESIZE_EXCEEDED + maxCombinedFileSize);
storageMessages(MAX_FILESIZE_EXCEEDED + maxCombinedFileSize, messages[0]);
+ toCompress = null;
+ files.clear();
return false;
}
toCompress[index++] = file;
@@ -133,6 +142,29 @@ public static Boolean decompress(String file, String path, GXBaseCollection MAX_FILES_ALLOWED) {
+ log.error(TOO_MANY_FILES + fileCount);
+ storageMessages(TOO_MANY_FILES + fileCount, messages[0]);
+ return false;
+ }
+ } catch (Exception e) {
+ log.error("Error counting archive entries for file: {}", file, e);
+ storageMessages("Error counting archive entries for file: " + file, messages[0]);
+ return false;
+ }
+ try {
+ if (!CompressionUtils.isArchiveSafe(toCompress, path)) {
+ log.error(ZIP_SLIP_DETECTED + file);
+ storageMessages(ZIP_SLIP_DETECTED + file, messages[0]);
+ return false;
+ }
+ } catch (Exception e) {
+ log.error("Error checking archive safety for file: {}", file, e);
+ storageMessages("Error checking archive safety for file: " + file, messages[0]);
+ return false;
+ }
String extension = getExtension(toCompress.getName());
try {
switch (extension.toLowerCase()) {
@@ -636,4 +668,4 @@ private static void decompressJar(File archive, String directory) throws IOExcep
}
}
}
-}
\ No newline at end of file
+}
From 457efed4059b6b5a20b5c44b968d50046d610090 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Fri, 28 Mar 2025 12:16:22 -0300
Subject: [PATCH 43/49] Add compression utils
---
.../genexus/compression/CompressionUtils.java | 107 ++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java b/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
new file mode 100644
index 000000000..517d4183a
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
@@ -0,0 +1,107 @@
+package com.genexus.compression;
+
+import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
+import org.apache.commons.compress.archivers.sevenz.SevenZFile;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import static org.apache.commons.io.FileUtils.getFile;
+import static org.apache.commons.io.FilenameUtils.getExtension;
+
+public class CompressionUtils {
+ public static int countArchiveEntries(File toCompress) throws IOException {
+ String ext = getExtension(toCompress.getName()).toLowerCase();
+ switch (ext) {
+ case "zip":
+ case "jar": {
+ int count = 0;
+ try (ZipFile zip = new ZipFile(toCompress)) {
+ Enumeration extends ZipEntry> entries = zip.entries();
+ while (entries.hasMoreElements()) {
+ entries.nextElement();
+ count++;
+ }
+ }
+ return count;
+ }
+ case "tar": {
+ int count = 0;
+ try (FileInputStream fis = new FileInputStream(toCompress);
+ TarArchiveInputStream tais = new TarArchiveInputStream(fis)) {
+ while (tais.getNextEntry() != null) {
+ count++;
+ }
+ }
+ return count;
+ }
+ case "7z": {
+ int count = 0;
+ try (SevenZFile sevenZFile = getSevenZFile(toCompress.getAbsolutePath())) {
+ while (sevenZFile.getNextEntry() != null) {
+ count++;
+ }
+ }
+ return count;
+ }
+ case "gz":
+ return 1;
+ }
+ return 0;
+ }
+ public static boolean isArchiveSafe(File toCompress, String targetDir) throws IOException {
+ String ext = getExtension(toCompress.getName()).toLowerCase();
+ File target = new File(targetDir).getCanonicalFile();
+ switch (ext) {
+ case "zip":
+ case "jar":
+ try (ZipFile zip = new ZipFile(toCompress)) {
+ Enumeration extends ZipEntry> entries = zip.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = entries.nextElement();
+ File entryFile = new File(target, entry.getName());
+ if (!entryFile.getCanonicalPath().startsWith(target.getCanonicalPath() + File.separator)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ case "tar":
+ try (FileInputStream fis = new FileInputStream(toCompress);
+ TarArchiveInputStream tais = new TarArchiveInputStream(fis)) {
+ TarArchiveEntry entry;
+ while ((entry = tais.getNextEntry()) != null) {
+ File entryFile = new File(target, entry.getName());
+ if (!entryFile.getCanonicalPath().startsWith(target.getCanonicalPath() + File.separator)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ case "7z":
+ try (SevenZFile sevenZFile = getSevenZFile(toCompress.getAbsolutePath())) {
+ SevenZArchiveEntry entry;
+ while ((entry = sevenZFile.getNextEntry()) != null) {
+ File entryFile = new File(target, entry.getName());
+ if (!entryFile.getCanonicalPath().startsWith(target.getCanonicalPath() + File.separator)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ case "gz":
+ return true;
+ }
+ return true;
+ }
+
+ private static SevenZFile getSevenZFile(final String specialPath) throws IOException {
+ return SevenZFile.builder().setFile(getFile(specialPath)).get();
+ }
+}
From a131cfa20f7487e9465a63e9553bd87a6842855a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:43:33 -0300
Subject: [PATCH 44/49] Fix wrong directory traversal and zip bomb checks
---
.../genexus/compression/CompressionUtils.java | 66 +++++++++++++++++++
.../com/genexus/compression/GXCompressor.java | 64 ++++++++++++++++--
2 files changed, 123 insertions(+), 7 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java b/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
index 517d4183a..162fd6964 100644
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
@@ -4,6 +4,7 @@
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -16,6 +17,7 @@
import static org.apache.commons.io.FilenameUtils.getExtension;
public class CompressionUtils {
+
public static int countArchiveEntries(File toCompress) throws IOException {
String ext = getExtension(toCompress.getName()).toLowerCase();
switch (ext) {
@@ -101,6 +103,70 @@ public static boolean isArchiveSafe(File toCompress, String targetDir) throws IO
return true;
}
+ private static final long MAX_PERMITTED_SIZE = 1024L * 1024 * 1024 * 15; //15GB
+
+ public static long estimateDecompressedSize(File archive) throws IOException {
+ String ext = getExtension(archive.getName()).toLowerCase();
+ long totalSize = 0;
+
+ switch (ext) {
+ case "zip":
+ case "jar":
+ try (ZipFile zip = new ZipFile(archive)) {
+ Enumeration extends ZipEntry> entries = zip.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = entries.nextElement();
+ if (!entry.isDirectory()) {
+ long size = entry.getSize();
+ totalSize += (size > 0) ? size : (archive.length() * 5);
+ if (totalSize > MAX_PERMITTED_SIZE) {
+ return totalSize;
+ }
+ }
+ }
+ }
+ break;
+ case "tar":
+ try (FileInputStream fis = new FileInputStream(archive);
+ TarArchiveInputStream tais = new TarArchiveInputStream(fis)) {
+ TarArchiveEntry entry;
+ while ((entry = tais.getNextEntry()) != null) {
+ if (!entry.isDirectory()) {
+ totalSize += entry.getSize();
+ if (totalSize > MAX_PERMITTED_SIZE) {
+ return totalSize;
+ }
+ }
+ }
+ }
+ break;
+ case "7z":
+ try (SevenZFile sevenZFile = getSevenZFile(archive.getAbsolutePath())) {
+ SevenZArchiveEntry entry;
+ while ((entry = sevenZFile.getNextEntry()) != null) {
+ if (!entry.isDirectory()) {
+ totalSize += entry.getSize();
+ if (totalSize > MAX_PERMITTED_SIZE) {
+ return totalSize;
+ }
+ }
+ }
+ }
+ break;
+ case "gz":
+ try (FileInputStream fis = new FileInputStream(archive);
+ GzipCompressorInputStream ignored = new GzipCompressorInputStream(fis)) {
+ totalSize = archive.length() * 10;
+ }
+ break;
+ }
+ if (totalSize < archive.length()) {
+ totalSize = archive.length() * 5;
+ }
+
+ return totalSize;
+ }
+
private static SevenZFile getSevenZFile(final String specialPath) throws IOException {
return SevenZFile.builder().setFile(getFile(specialPath)).get();
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index baa6ffc27..fb780d83d 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -34,11 +34,16 @@ public class GXCompressor implements IGXCompressor {
private static final String FILE_NOT_EXISTS = "File does not exist: ";
private static final String UNSUPPORTED_FORMAT = " is an unsupported format. Supported formats are zip, 7z, tar, gz and jar.";
private static final String EMPTY_FILE = "The selected file is empty: ";
+ private static final String PURGED_ARCHIVE = "After performing security checks, no valid files where left to compress";
private static final String DIRECTORY_ATTACK = "Potential directory traversal attack detected: ";
private static final String MAX_FILESIZE_EXCEEDED = "The file(s) selected for (de)compression exceed the maximum permitted file size of ";
private static final String TOO_MANY_FILES = "Too many files have been added for (de)compression. Maximum allowed is ";
private static final String ZIP_SLIP_DETECTED = "Zip slip or path traversal attack detected in archive: ";
+ private static final String BIG_SINGLE_FILE = "Individual file exceeds maximum allowed size: ";
+ private static final String PROCESSING_ERROR = "Error checking archive safety for file: ";
+ private static final String ARCHIVE_SIZE_ESTIMATION_ERROR = "";
private static final int MAX_FILES_ALLOWED = 1000;
+ private static final long MAX_DECOMPRESSED_SIZE = 1024 * 1024 * 100; // 100MB limit
private static void storageMessages(String error, GXBaseCollection messages) {
try {
@@ -51,7 +56,7 @@ private static void storageMessages(String error, GXBaseCollection files, String path, long maxCombinedFileSize, GXBaseCollection[] messages) {
if (files.isEmpty()){
log.error(NO_FILES_ADDED);
@@ -76,25 +81,52 @@ public static Boolean compress(ArrayList files, String path, long maxCom
storageMessages(FILE_NOT_EXISTS + filePath, messages[0]);
continue;
}
- if (!normalizedPath.equals(file.getAbsolutePath())) {
+
+ // More permissive directory traversal check
+ // Check if the canonical path points to a parent directory of the file
+ // or if it points to a completely different location
+ File absFile = file.getAbsoluteFile();
+ if (!normalizedPath.startsWith(absFile.getParentFile().getCanonicalPath())) {
log.error(DIRECTORY_ATTACK + "{}", filePath);
storageMessages(DIRECTORY_ATTACK + filePath, messages[0]);
return false;
}
+
long fileSize = file.length();
+
+ if (maxCombinedFileSize > -1 && fileSize > maxCombinedFileSize) {
+ log.error(BIG_SINGLE_FILE + filePath);
+ storageMessages(BIG_SINGLE_FILE + filePath, messages[0]);
+ files.clear();
+ return false;
+ }
+
totalSize += fileSize;
if (maxCombinedFileSize > -1 && totalSize > maxCombinedFileSize) {
log.error(MAX_FILESIZE_EXCEEDED + maxCombinedFileSize);
storageMessages(MAX_FILESIZE_EXCEEDED + maxCombinedFileSize, messages[0]);
- toCompress = null;
files.clear();
return false;
}
toCompress[index++] = file;
} catch (IOException e) {
log.error("Error normalizing path for file: {}", filePath, e);
+ return false;
}
}
+
+ if (index < toCompress.length) {
+ File[] resized = new File[index];
+ System.arraycopy(toCompress, 0, resized, 0, index);
+ toCompress = resized;
+ }
+
+ if (toCompress.length == 0) {
+ log.error(PURGED_ARCHIVE);
+ storageMessages(PURGED_ARCHIVE, messages[0]);
+ return false;
+ }
+
String format = CommonUtil.getFileType(path).toLowerCase();
try {
switch (format.toLowerCase()) {
@@ -150,8 +182,8 @@ public static Boolean decompress(String file, String path, GXBaseCollection MAX_DECOMPRESSED_SIZE) {
+ log.error("Potential zip bomb detected. Estimated size: " + totalSizeEstimate + " bytes");
+ storageMessages("Potential zip bomb detected. Operation aborted for security reasons.", messages[0]);
+ if (!toCompress.delete()) {
+ log.error("Failed to delete suspicious archive: {}", file);
+ }
+ return false;
+ }
+ } catch (Exception e) {
+ log.error(ARCHIVE_SIZE_ESTIMATION_ERROR + file, e);
+ storageMessages(ARCHIVE_SIZE_ESTIMATION_ERROR+ file, messages[0]);
+ return false;
+ }
+
String extension = getExtension(toCompress.getName());
try {
switch (extension.toLowerCase()) {
From f4186099af234cb7be253da7c54706bc341cc34d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 1 Apr 2025 11:05:07 -0300
Subject: [PATCH 45/49] Complete rewrite of security checks, read values from
given configuration
---
.../com/genexus/compression/Compression.java | 20 +-
.../compression/CompressionConfiguration.java | 17 +
.../genexus/compression/CompressionUtils.java | 303 +++++++++++++-----
.../com/genexus/compression/GXCompressor.java | 212 +++++++-----
.../genexus/compression/IGXCompressor.java | 12 -
.../genexus/compression/TestCompression.java | 12 +-
6 files changed, 390 insertions(+), 186 deletions(-)
create mode 100644 gxcompress/src/main/java/com/genexus/compression/CompressionConfiguration.java
delete mode 100644 gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 329092c0d..08888053e 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -2,29 +2,27 @@
import com.genexus.GXBaseCollection;
import com.genexus.SdtMessages_Message;
-import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
public class Compression {
- private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Compression.class);
- private String absolutePath;
- private long maxCombinedFileSize;
+ private String destinationPath;
+ private CompressionConfiguration compressionConfiguration;
private GXBaseCollection[] messages;
private ArrayList filesToCompress;
public Compression() {}
- public Compression(String absolutePath, long maxCombinedFileSize, GXBaseCollection[] messages) {
- this.absolutePath = absolutePath;
- this.maxCombinedFileSize = maxCombinedFileSize;
+ public Compression(String destinationPath, CompressionConfiguration configuration, GXBaseCollection[] messages) {
+ this.destinationPath = destinationPath;
+ this.compressionConfiguration = configuration;
this.messages = messages;
filesToCompress = new ArrayList<>();
}
- public void setAbsolutePath(String path) {
- this.absolutePath = path;
+ public void setDestinationPath(String path) {
+ this.destinationPath = path;
}
public void addElement(String filePath) {
@@ -32,11 +30,11 @@ public void addElement(String filePath) {
}
public Boolean save() {
- return GXCompressor.compress(filesToCompress, absolutePath, maxCombinedFileSize, messages);
+ return GXCompressor.compress(filesToCompress, destinationPath, compressionConfiguration, messages);
}
public void clear() {
- absolutePath = "";
+ destinationPath = "";
filesToCompress = new ArrayList<>();
}
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionConfiguration.java b/gxcompress/src/main/java/com/genexus/compression/CompressionConfiguration.java
new file mode 100644
index 000000000..c008d2a68
--- /dev/null
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionConfiguration.java
@@ -0,0 +1,17 @@
+package com.genexus.compression;
+
+public class CompressionConfiguration {
+ public long maxCombinedFileSize = -1;
+ public long maxIndividualFileSize = -1;
+ public int maxFileCount = -1;
+ public String targetDirectory = "";
+
+ public CompressionConfiguration() {}
+
+ public CompressionConfiguration(long maxCombinedFileSize, long maxIndividualFileSize, int maxFileCount, String targetDirectory) {
+ this.maxCombinedFileSize = maxCombinedFileSize;
+ this.maxIndividualFileSize = maxIndividualFileSize;
+ this.maxFileCount = maxFileCount;
+ this.targetDirectory = (targetDirectory != null && !targetDirectory.isEmpty()) ? targetDirectory : "";
+ }
+}
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java b/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
index 162fd6964..ad4963cbd 100644
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
@@ -4,164 +4,301 @@
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
-import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.file.Files;
import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static org.apache.commons.io.FileUtils.getFile;
import static org.apache.commons.io.FilenameUtils.getExtension;
+
public class CompressionUtils {
- public static int countArchiveEntries(File toCompress) throws IOException {
- String ext = getExtension(toCompress.getName()).toLowerCase();
- switch (ext) {
+ /**
+ * Counts the number of entries in an archive file.
+ *
+ * @param archiveFile The archive file to analyze
+ * @return The number of entries in the archive
+ * @throws IOException If an I/O error occurs
+ */
+ public static int countArchiveEntries(File archiveFile) throws IOException {
+ String extension = getExtension(archiveFile.getName()).toLowerCase();
+ int count = 0;
+
+ switch (extension) {
case "zip":
- case "jar": {
- int count = 0;
- try (ZipFile zip = new ZipFile(toCompress)) {
- Enumeration extends ZipEntry> entries = zip.entries();
- while (entries.hasMoreElements()) {
- entries.nextElement();
- count++;
- }
+ try (ZipFile zipFile = new ZipFile(archiveFile)) {
+ return zipFile.size();
}
- return count;
- }
- case "tar": {
- int count = 0;
- try (FileInputStream fis = new FileInputStream(toCompress);
- TarArchiveInputStream tais = new TarArchiveInputStream(fis)) {
- while (tais.getNextEntry() != null) {
+ case "7z":
+ try (SevenZFile sevenZFile = getSevenZFile(archiveFile.getAbsolutePath())) {
+ while (sevenZFile.getNextEntry() != null) {
count++;
}
+ return count;
}
- return count;
- }
- case "7z": {
- int count = 0;
- try (SevenZFile sevenZFile = getSevenZFile(toCompress.getAbsolutePath())) {
- while (sevenZFile.getNextEntry() != null) {
+ case "tar":
+ try (TarArchiveInputStream tarStream = new TarArchiveInputStream(Files.newInputStream(archiveFile.toPath()))) {
+ while (tarStream.getNextEntry() != null) {
count++;
}
+ return count;
}
- return count;
- }
case "gz":
return 1;
+ case "jar":
+ try (JarFile jarFile = new JarFile(archiveFile)) {
+ return jarFile.size();
+ }
+ default:
+ throw new IllegalArgumentException("Unsupported archive format: " + extension);
}
- return 0;
}
- public static boolean isArchiveSafe(File toCompress, String targetDir) throws IOException {
- String ext = getExtension(toCompress.getName()).toLowerCase();
- File target = new File(targetDir).getCanonicalFile();
- switch (ext) {
+
+ /**
+ * Checks if an archive is safe to extract (no path traversal/zip slip).
+ *
+ * @param archiveFile The archive file to check
+ * @param targetDir The target directory for extraction
+ * @return true if the archive is safe, false otherwise
+ * @throws IOException If an I/O error occurs
+ */
+ public static boolean isArchiveSafe(File archiveFile, String targetDir) throws IOException {
+ String extension = getExtension(archiveFile.getName()).toLowerCase();
+ File targetPath = new File(targetDir).getCanonicalFile();
+
+ switch (extension) {
case "zip":
- case "jar":
- try (ZipFile zip = new ZipFile(toCompress)) {
- Enumeration extends ZipEntry> entries = zip.entries();
+ try (ZipFile zipFile = new ZipFile(archiveFile)) {
+ Enumeration extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
- File entryFile = new File(target, entry.getName());
- if (!entryFile.getCanonicalPath().startsWith(target.getCanonicalPath() + File.separator)) {
+ File destinationFile = new File(targetPath, entry.getName()).getCanonicalFile();
+ if (!destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) &&
+ !destinationFile.getPath().equals(targetPath.getPath())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ case "7z":
+ try (SevenZFile sevenZFile = getSevenZFile(archiveFile.getAbsolutePath())) {
+ SevenZArchiveEntry entry;
+ while ((entry = sevenZFile.getNextEntry()) != null) {
+ File destinationFile = new File(targetPath, entry.getName()).getCanonicalFile();
+ if (!destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) &&
+ !destinationFile.getPath().equals(targetPath.getPath())) {
return false;
}
}
}
return true;
case "tar":
- try (FileInputStream fis = new FileInputStream(toCompress);
- TarArchiveInputStream tais = new TarArchiveInputStream(fis)) {
+ try (TarArchiveInputStream tarStream = new TarArchiveInputStream(Files.newInputStream(archiveFile.toPath()))) {
TarArchiveEntry entry;
- while ((entry = tais.getNextEntry()) != null) {
- File entryFile = new File(target, entry.getName());
- if (!entryFile.getCanonicalPath().startsWith(target.getCanonicalPath() + File.separator)) {
+ while ((entry = tarStream.getNextEntry()) != null) {
+ File destinationFile = new File(targetPath, entry.getName()).getCanonicalFile();
+ if (!destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) &&
+ !destinationFile.getPath().equals(targetPath.getPath())) {
return false;
}
}
}
return true;
+ case "gz":
+ String fileName = archiveFile.getName();
+ if (fileName.endsWith(".gz") && fileName.length() > 3) {
+ String extractedName = fileName.substring(0, fileName.length() - 3);
+ File destinationFile = new File(targetPath, extractedName).getCanonicalFile();
+ return destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) ||
+ destinationFile.getPath().equals(targetPath.getPath());
+ }
+ return true;
+ case "jar":
+ try (JarFile jarFile = new JarFile(archiveFile)) {
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ File destinationFile = new File(targetPath, entry.getName()).getCanonicalFile();
+ if (!destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) &&
+ !destinationFile.getPath().equals(targetPath.getPath())) {
+ return false;
+ }
+ }
+ }
+ return true;
+ default:
+ throw new IllegalArgumentException("Unsupported archive format: " + extension);
+ }
+ }
+
+ /**
+ * Gets the maximum file size of any entry in the archive.
+ *
+ * @param archiveFile The archive file to analyze
+ * @return The size of the largest file in the archive
+ * @throws IOException If an I/O error occurs
+ */
+ public static long getMaxFileSize(File archiveFile) throws IOException {
+ String extension = getExtension(archiveFile.getName()).toLowerCase();
+ long maxSize = 0;
+
+ switch (extension) {
+ case "zip":
+ try (ZipFile zipFile = new ZipFile(archiveFile)) {
+ Enumeration extends ZipEntry> entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = entries.nextElement();
+ if (!entry.isDirectory() && entry.getSize() > maxSize) {
+ maxSize = entry.getSize();
+ }
+ }
+ }
+ break;
case "7z":
- try (SevenZFile sevenZFile = getSevenZFile(toCompress.getAbsolutePath())) {
+ try (SevenZFile sevenZFile = getSevenZFile(archiveFile.getAbsolutePath())) {
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null) {
- File entryFile = new File(target, entry.getName());
- if (!entryFile.getCanonicalPath().startsWith(target.getCanonicalPath() + File.separator)) {
- return false;
+ if (!entry.isDirectory() && entry.getSize() > maxSize) {
+ maxSize = entry.getSize();
}
}
}
- return true;
+ break;
+ case "tar":
+ try (TarArchiveInputStream tarStream = new TarArchiveInputStream(Files.newInputStream(archiveFile.toPath()))) {
+ TarArchiveEntry entry;
+ while ((entry = tarStream.getNextEntry()) != null) {
+ if (!entry.isDirectory() && entry.getSize() > maxSize) {
+ maxSize = entry.getSize();
+ }
+ }
+ }
+ break;
case "gz":
- return true;
+ try (GZIPInputStream gzStream = new GZIPInputStream(Files.newInputStream(archiveFile.toPath()))) {
+ byte[] buffer = new byte[8192];
+ long size = 0;
+ int n;
+ while ((n = gzStream.read(buffer)) != -1) {
+ size += n;
+ }
+ maxSize = size;
+ }
+ break;
+ case "jar":
+ try (JarFile jarFile = new JarFile(archiveFile)) {
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ if (!entry.isDirectory() && entry.getSize() > maxSize) {
+ maxSize = entry.getSize();
+ }
+ }
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported archive format: " + extension);
}
- return true;
- }
- private static final long MAX_PERMITTED_SIZE = 1024L * 1024 * 1024 * 15; //15GB
+ return maxSize;
+ }
- public static long estimateDecompressedSize(File archive) throws IOException {
- String ext = getExtension(archive.getName()).toLowerCase();
+ /**
+ * Estimates the total size of all files after decompression.
+ *
+ * @param archiveFile The archive file to analyze
+ * @return The estimated total size after decompression
+ * @throws IOException If an I/O error occurs
+ */
+ public static long estimateDecompressedSize(File archiveFile) throws IOException {
+ String extension = getExtension(archiveFile.getName()).toLowerCase();
long totalSize = 0;
- switch (ext) {
+ switch (extension) {
case "zip":
- case "jar":
- try (ZipFile zip = new ZipFile(archive)) {
- Enumeration extends ZipEntry> entries = zip.entries();
+ try (ZipFile zipFile = new ZipFile(archiveFile)) {
+ Enumeration extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
long size = entry.getSize();
- totalSize += (size > 0) ? size : (archive.length() * 5);
- if (totalSize > MAX_PERMITTED_SIZE) {
- return totalSize;
+ if (size != -1) {
+ totalSize += size;
+ } else {
+ totalSize += entry.getCompressedSize() * 3;
}
}
}
}
break;
- case "tar":
- try (FileInputStream fis = new FileInputStream(archive);
- TarArchiveInputStream tais = new TarArchiveInputStream(fis)) {
- TarArchiveEntry entry;
- while ((entry = tais.getNextEntry()) != null) {
+ case "7z":
+ try (SevenZFile sevenZFile = getSevenZFile(archiveFile.getAbsolutePath())) {
+ SevenZArchiveEntry entry;
+ while ((entry = sevenZFile.getNextEntry()) != null) {
if (!entry.isDirectory()) {
totalSize += entry.getSize();
- if (totalSize > MAX_PERMITTED_SIZE) {
- return totalSize;
- }
}
}
}
break;
- case "7z":
- try (SevenZFile sevenZFile = getSevenZFile(archive.getAbsolutePath())) {
- SevenZArchiveEntry entry;
- while ((entry = sevenZFile.getNextEntry()) != null) {
+ case "tar":
+ try (TarArchiveInputStream tarStream = new TarArchiveInputStream(Files.newInputStream(archiveFile.toPath()))) {
+ TarArchiveEntry entry;
+ while ((entry = tarStream.getNextEntry()) != null) {
if (!entry.isDirectory()) {
totalSize += entry.getSize();
- if (totalSize > MAX_PERMITTED_SIZE) {
- return totalSize;
- }
}
}
}
break;
case "gz":
- try (FileInputStream fis = new FileInputStream(archive);
- GzipCompressorInputStream ignored = new GzipCompressorInputStream(fis)) {
- totalSize = archive.length() * 10;
+ try (RandomAccessFile raf = new RandomAccessFile(archiveFile, "r")) {
+ raf.seek(raf.length() - 4);
+ int b4 = raf.read();
+ int b3 = raf.read();
+ int b2 = raf.read();
+ int b1 = raf.read();
+ if (b1 != -1 && b2 != -1 && b3 != -1 && b4 != -1) {
+ long size = ((long) b1 << 24) | ((long) b2 << 16) | ((long) b3 << 8) | b4;
+ if (size > 0) {
+ totalSize = size;
+ } else {
+ totalSize = archiveFile.length() * 5;
+ }
+ } else {
+ totalSize = archiveFile.length() * 5;
+ }
+ } catch (Exception e) {
+ totalSize = archiveFile.length() * 5;
}
break;
- }
- if (totalSize < archive.length()) {
- totalSize = archive.length() * 5;
+ case "jar":
+ try (JarFile jarFile = new JarFile(archiveFile)) {
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ if (!entry.isDirectory()) {
+ long size = entry.getSize();
+ if (size != -1) {
+ totalSize += size;
+ } else {
+ totalSize += entry.getCompressedSize() * 3;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported archive format: " + extension);
}
return totalSize;
@@ -170,4 +307,4 @@ public static long estimateDecompressedSize(File archive) throws IOException {
private static SevenZFile getSevenZFile(final String specialPath) throws IOException {
return SevenZFile.builder().setFile(getFile(specialPath)).get();
}
-}
+}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index fb780d83d..cfccbb8f8 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -17,6 +17,7 @@
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
+import java.util.List;
import java.util.Stack;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
@@ -25,7 +26,7 @@
import static org.apache.commons.io.FilenameUtils.getExtension;
-public class GXCompressor implements IGXCompressor {
+public class GXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
@@ -42,8 +43,6 @@ public class GXCompressor implements IGXCompressor {
private static final String BIG_SINGLE_FILE = "Individual file exceeds maximum allowed size: ";
private static final String PROCESSING_ERROR = "Error checking archive safety for file: ";
private static final String ARCHIVE_SIZE_ESTIMATION_ERROR = "";
- private static final int MAX_FILES_ALLOWED = 1000;
- private static final long MAX_DECOMPRESSED_SIZE = 1024 * 1024 * 100; // 100MB limit
private static void storageMessages(String error, GXBaseCollection messages) {
try {
@@ -57,21 +56,23 @@ private static void storageMessages(String error, GXBaseCollection files, String path, long maxCombinedFileSize, GXBaseCollection[] messages) {
- if (files.isEmpty()){
+ /**
+ * Compresses specified files into an archive at the given path based on configuration parameters.
+ *
+ * @param files List of file paths to compress
+ * @param path Target path for the compressed archive
+ * @param configuration Configuration parameters for compression
+ * @param messages Collection to store output messages
+ * @return Boolean indicating success or failure of compression operation
+ */
+ public static Boolean compress(ArrayList files, String path, CompressionConfiguration configuration, GXBaseCollection[] messages) {
+ if (files.isEmpty()) {
log.error(NO_FILES_ADDED);
storageMessages(NO_FILES_ADDED, messages[0]);
return false;
}
- if(maxCombinedFileSize > -1 && files.size() > MAX_FILES_ALLOWED){
- log.error(TOO_MANY_FILES + MAX_FILES_ALLOWED);
- storageMessages(TOO_MANY_FILES + MAX_FILES_ALLOWED, messages[0]);
- files.clear();
- return false;
- }
+ List validFiles = new ArrayList<>();
long totalSize = 0;
- File[] toCompress = new File[files.size()];
- int index = 0;
for (String filePath : files) {
File file = new File(filePath);
try {
@@ -81,52 +82,65 @@ public static Boolean compress(ArrayList files, String path, long maxCom
storageMessages(FILE_NOT_EXISTS + filePath, messages[0]);
continue;
}
-
- // More permissive directory traversal check
- // Check if the canonical path points to a parent directory of the file
- // or if it points to a completely different location
File absFile = file.getAbsoluteFile();
if (!normalizedPath.startsWith(absFile.getParentFile().getCanonicalPath())) {
log.error(DIRECTORY_ATTACK + "{}", filePath);
storageMessages(DIRECTORY_ATTACK + filePath, messages[0]);
return false;
}
-
long fileSize = file.length();
-
- if (maxCombinedFileSize > -1 && fileSize > maxCombinedFileSize) {
+ if (configuration.maxIndividualFileSize > -1 && fileSize > configuration.maxIndividualFileSize) {
log.error(BIG_SINGLE_FILE + filePath);
storageMessages(BIG_SINGLE_FILE + filePath, messages[0]);
- files.clear();
- return false;
+ continue;
}
-
totalSize += fileSize;
- if (maxCombinedFileSize > -1 && totalSize > maxCombinedFileSize) {
- log.error(MAX_FILESIZE_EXCEEDED + maxCombinedFileSize);
- storageMessages(MAX_FILESIZE_EXCEEDED + maxCombinedFileSize, messages[0]);
- files.clear();
- return false;
- }
- toCompress[index++] = file;
+ validFiles.add(file);
} catch (IOException e) {
log.error("Error normalizing path for file: {}", filePath, e);
+ storageMessages("Error normalizing path for file: " + filePath, messages[0]);
return false;
}
}
-
- if (index < toCompress.length) {
- File[] resized = new File[index];
- System.arraycopy(toCompress, 0, resized, 0, index);
- toCompress = resized;
- }
-
- if (toCompress.length == 0) {
+ if (validFiles.isEmpty()) {
log.error(PURGED_ARCHIVE);
storageMessages(PURGED_ARCHIVE, messages[0]);
return false;
}
-
+ if (configuration.maxCombinedFileSize > -1 && totalSize > configuration.maxCombinedFileSize) {
+ log.error(MAX_FILESIZE_EXCEEDED + configuration.maxCombinedFileSize);
+ storageMessages(MAX_FILESIZE_EXCEEDED + configuration.maxCombinedFileSize, messages[0]);
+ return false;
+ }
+ if (configuration.maxFileCount > -1 && validFiles.size() > configuration.maxFileCount) {
+ log.error(TOO_MANY_FILES + configuration.maxFileCount);
+ storageMessages(TOO_MANY_FILES + configuration.maxFileCount, messages[0]);
+ return false;
+ }
+ try {
+ File targetFile = new File(path);
+ File targetDir = targetFile.getParentFile();
+ if (path.contains("/../") || path.contains("../") || path.contains("/..")) {
+ log.error(DIRECTORY_ATTACK + path);
+ storageMessages(DIRECTORY_ATTACK + path, messages[0]);
+ return false;
+ }
+ if (configuration.targetDirectory != null && !configuration.targetDirectory.isEmpty()) {
+ File configTargetDir = new File(configuration.targetDirectory);
+ String normalizedTargetPath = targetDir.getCanonicalPath();
+ String normalizedConfigPath = configTargetDir.getCanonicalPath();
+ if (!normalizedTargetPath.startsWith(normalizedConfigPath)) {
+ log.error(DIRECTORY_ATTACK + path);
+ storageMessages(DIRECTORY_ATTACK + path, messages[0]);
+ return false;
+ }
+ }
+ } catch (IOException e) {
+ log.error("Error validating target path: {}", path, e);
+ storageMessages("Error validating target path: " + path, messages[0]);
+ return false;
+ }
+ File[] toCompress = validFiles.toArray(new File[0]);
String format = CommonUtil.getFileType(path).toLowerCase();
try {
switch (format.toLowerCase()) {
@@ -146,39 +160,57 @@ public static Boolean compress(ArrayList files, String path, long maxCom
compressToJar(toCompress, path);
break;
default:
- log.error("{}" + UNSUPPORTED_FORMAT, format);
+ log.error(format + UNSUPPORTED_FORMAT);
storageMessages(format + UNSUPPORTED_FORMAT, messages[0]);
return false;
}
return true;
} catch (Exception e) {
log.error(GENERIC_ERROR, e);
- storageMessages(e.getMessage(), messages[0]);
+ storageMessages(e.getMessage(), messages[0]);
return false;
}
}
-
- public static Compression newCompression(String path, long maxCombinedFileSize, GXBaseCollection[] messages) {
- return new Compression(path, maxCombinedFileSize, messages);
+
+ /**
+ * Compresses files interactively, add files to a collection until the GXCompressor.compress method is executed
+ *
+ * @param path Target path for the compressed archive
+ * @param configuration Configuration parameters for decompression
+ * @param messages Collection to store output messages
+ * @return Boolean indicating success or failure of decompression operation
+ */
+ public static Compression newCompression(String path, CompressionConfiguration configuration, GXBaseCollection[] messages) {
+ return new Compression(path, configuration, messages);
}
- public static Boolean decompress(String file, String path, GXBaseCollection[] messages) {
- File toCompress = new File(file);
- if (!toCompress.exists()) {
- log.error("{}{}", FILE_NOT_EXISTS, toCompress.getAbsolutePath());
- storageMessages(FILE_NOT_EXISTS + toCompress.getAbsolutePath(), messages[0]);
+ /**
+ * Decompresses an archive file to the specified path based on configuration parameters.
+ *
+ * @param file Path to the archive file to decompress
+ * @param path Target path for the decompressed files
+ * @param configuration Configuration parameters for decompression
+ * @param messages Collection to store output messages
+ * @return Boolean indicating success or failure of decompression operation
+ */
+ public static Boolean decompress(String file, String path, CompressionConfiguration configuration, GXBaseCollection[] messages) {
+ File archiveFile = new File(file);
+ if (!archiveFile.exists()) {
+ log.error("{}{}", FILE_NOT_EXISTS, archiveFile.getAbsolutePath());
+ storageMessages(FILE_NOT_EXISTS + archiveFile.getAbsolutePath(), messages[0]);
return false;
}
- if (toCompress.length() == 0L){
+ if (archiveFile.length() == 0L) {
log.error("{}{}", EMPTY_FILE, file);
storageMessages(EMPTY_FILE + file, messages[0]);
return false;
}
+ int fileCount;
try {
- int fileCount = CompressionUtils.countArchiveEntries(toCompress);
- if (fileCount > MAX_FILES_ALLOWED) {
- log.error(TOO_MANY_FILES + fileCount);
- storageMessages(TOO_MANY_FILES + fileCount, messages[0]);
+ fileCount = CompressionUtils.countArchiveEntries(archiveFile);
+ if (fileCount <= 0) {
+ log.error("{}{}", EMPTY_FILE, file);
+ storageMessages(EMPTY_FILE + file, messages[0]);
return false;
}
} catch (Exception e) {
@@ -187,54 +219,86 @@ public static Boolean decompress(String file, String path, GXBaseCollection MAX_DECOMPRESSED_SIZE) {
- log.error("Potential zip bomb detected. Estimated size: " + totalSizeEstimate + " bytes");
- storageMessages("Potential zip bomb detected. Operation aborted for security reasons.", messages[0]);
- if (!toCompress.delete()) {
- log.error("Failed to delete suspicious archive: {}", file);
+ if (configuration.maxIndividualFileSize > -1) {
+ long maxFileSize = CompressionUtils.getMaxFileSize(archiveFile);
+ if (maxFileSize > configuration.maxIndividualFileSize) {
+ log.error(BIG_SINGLE_FILE + maxFileSize + " bytes");
+ storageMessages(BIG_SINGLE_FILE + maxFileSize + " bytes", messages[0]);
+ return false;
+ }
+ }
+ if (configuration.maxCombinedFileSize > -1) {
+ long totalSizeEstimate = CompressionUtils.estimateDecompressedSize(archiveFile);
+ if (totalSizeEstimate > configuration.maxCombinedFileSize) {
+ log.error(MAX_FILESIZE_EXCEEDED + configuration.maxCombinedFileSize);
+ storageMessages(MAX_FILESIZE_EXCEEDED + configuration.maxCombinedFileSize, messages[0]);
+ return false;
}
- return false;
}
} catch (Exception e) {
log.error(ARCHIVE_SIZE_ESTIMATION_ERROR + file, e);
- storageMessages(ARCHIVE_SIZE_ESTIMATION_ERROR+ file, messages[0]);
+ storageMessages("Error estimating archive size: " + file, messages[0]);
return false;
}
-
- String extension = getExtension(toCompress.getName());
+ if (configuration.maxFileCount > -1 && fileCount > configuration.maxFileCount) {
+ log.error(TOO_MANY_FILES + configuration.maxFileCount);
+ storageMessages(TOO_MANY_FILES + configuration.maxFileCount, messages[0]);
+ return false;
+ }
+ String extension = getExtension(archiveFile.getName());
try {
switch (extension.toLowerCase()) {
case "zip":
- decompressZip(toCompress, path);
+ decompressZip(archiveFile, path);
break;
case "7z":
- decompress7z(toCompress, path);
+ decompress7z(archiveFile, path);
break;
case "tar":
- decompressTar(toCompress, path);
+ decompressTar(archiveFile, path);
break;
case "gz":
- decompressGzip(toCompress, path);
+ decompressGzip(archiveFile, path);
break;
case "jar":
- decompressJar(toCompress, path);
+ decompressJar(archiveFile, path);
break;
default:
- log.error("{}" + UNSUPPORTED_FORMAT, extension);
+ log.error(extension + UNSUPPORTED_FORMAT);
storageMessages(extension + UNSUPPORTED_FORMAT, messages[0]);
return false;
}
diff --git a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
deleted file mode 100644
index 2dc308a97..000000000
--- a/gxcompress/src/main/java/com/genexus/compression/IGXCompressor.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.genexus.compression;
-
-import com.genexus.GXBaseCollection;
-import com.genexus.SdtMessages_Message;
-
-import java.util.ArrayList;
-
-public interface IGXCompressor {
- static Boolean compress(ArrayList files, String path, long maxCombinedFileSize, GXBaseCollection[] messages) {return false;}
- static Compression newCompression(String path, long maxCombinedFileSize, GXBaseCollection[] messages) { return new Compression();}
- static Boolean decompress(String file, String path, GXBaseCollection[] messages) {return false;}
-}
diff --git a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
index 4a8cec4c7..8d8e0ac90 100644
--- a/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
+++ b/gxcompress/src/test/java/com/genexus/compression/TestCompression.java
@@ -53,7 +53,7 @@ public void tearDown() {
@Test
public void testCompressToZip() {
String outputPath = new File(testDirectory, "output.zip").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, new CompressionConfiguration(), msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -61,7 +61,7 @@ public void testCompressToZip() {
@Test
public void testCompressToSevenZ() {
String outputPath = new File(testDirectory, "output.7z").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, new CompressionConfiguration(), msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -69,7 +69,7 @@ public void testCompressToSevenZ() {
@Test
public void testCompressToTar() {
String outputPath = new File(testDirectory, "output.tar").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, new CompressionConfiguration(), msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -79,7 +79,7 @@ public void testCompressToGzip() {
String outputPath = new File(testDirectory, "output.gz").getAbsolutePath();
ArrayList singleFileCollection = new ArrayList<>();
singleFileCollection.add(files.get(0));
- Boolean result = GXCompressor.compress(singleFileCollection, outputPath, -1, msgs);
+ Boolean result = GXCompressor.compress(singleFileCollection, outputPath, new CompressionConfiguration(), msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -87,7 +87,7 @@ public void testCompressToGzip() {
@Test
public void testCompressToJar() {
String outputPath = new File(testDirectory, "output.jar").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, new CompressionConfiguration(), msgs);
assertTrue(result);
assertTrue(new File(outputPath).exists());
}
@@ -95,7 +95,7 @@ public void testCompressToJar() {
@Test
public void testUnsupportedFormat() {
String outputPath = new File(testDirectory, "output.unknown").getAbsolutePath();
- Boolean result = GXCompressor.compress(files, outputPath, -1, msgs);
+ Boolean result = GXCompressor.compress(files, outputPath, new CompressionConfiguration(), msgs);
assertFalse(result);
}
}
From 6b786bd761f85caba7c8499a9b6b779cfd9e4fbc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 9 Apr 2025 14:48:03 -0300
Subject: [PATCH 46/49] Fix clear method
---
.../src/main/java/com/genexus/compression/Compression.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/gxcompress/src/main/java/com/genexus/compression/Compression.java b/gxcompress/src/main/java/com/genexus/compression/Compression.java
index 08888053e..51bd5fd20 100644
--- a/gxcompress/src/main/java/com/genexus/compression/Compression.java
+++ b/gxcompress/src/main/java/com/genexus/compression/Compression.java
@@ -36,5 +36,7 @@ public Boolean save() {
public void clear() {
destinationPath = "";
filesToCompress = new ArrayList<>();
+ messages = null;
+ compressionConfiguration = new CompressionConfiguration();
}
}
From 21b11bd183343fe29cd0f71b9c04be6e3722371e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 9 Apr 2025 15:44:17 -0300
Subject: [PATCH 47/49] Remove not empty constructor
---
.../com/genexus/compression/CompressionConfiguration.java | 7 -------
1 file changed, 7 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionConfiguration.java b/gxcompress/src/main/java/com/genexus/compression/CompressionConfiguration.java
index c008d2a68..f5c768935 100644
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionConfiguration.java
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionConfiguration.java
@@ -7,11 +7,4 @@ public class CompressionConfiguration {
public String targetDirectory = "";
public CompressionConfiguration() {}
-
- public CompressionConfiguration(long maxCombinedFileSize, long maxIndividualFileSize, int maxFileCount, String targetDirectory) {
- this.maxCombinedFileSize = maxCombinedFileSize;
- this.maxIndividualFileSize = maxIndividualFileSize;
- this.maxFileCount = maxFileCount;
- this.targetDirectory = (targetDirectory != null && !targetDirectory.isEmpty()) ? targetDirectory : "";
- }
}
From d1d90e7feaac1321329a60ac8b3417b1d186dc5f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Tue, 22 Apr 2025 14:49:06 -0300
Subject: [PATCH 48/49] Create gzip decompression directory if its not there
---
.../com/genexus/compression/GXCompressor.java | 24 +++++++++++++++----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index cfccbb8f8..796a1fb43 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -270,7 +270,7 @@ public static Boolean decompress(String file, String path, CompressionConfigurat
}
}
} catch (Exception e) {
- log.error(ARCHIVE_SIZE_ESTIMATION_ERROR + file, e);
+ log.error(ARCHIVE_SIZE_ESTIMATION_ERROR + "{}", file, e);
storageMessages("Error estimating archive size: " + file, messages[0]);
return false;
}
@@ -672,10 +672,18 @@ private static void decompressGzip(File archive, String directory) throws IOExce
if (!archive.exists() || !archive.isFile()) {
throw new IllegalArgumentException("The archive file does not exist or is not a file.");
}
+
File targetDir = new File(directory);
- if (!targetDir.exists() || !targetDir.isDirectory()) {
- throw new IllegalArgumentException("The specified directory does not exist or is not a directory.");
+ if (!targetDir.exists()) {
+ if (!targetDir.mkdirs()) {
+ String error = "Failed to create target directory: " + directory;
+ log.error(error);
+ throw new IOException(error);
+ }
+ } else if (!targetDir.isDirectory()) {
+ throw new IllegalArgumentException("The specified path exists but is not a directory.");
}
+
File tempFile = File.createTempFile("decompressed_", ".tmp");
try (
FileInputStream fis = new FileInputStream(archive);
@@ -697,6 +705,7 @@ private static void decompressGzip(File archive, String directory) throws IOExce
isTar = true;
}
} catch (IOException ignored) {}
+
if (isTar) {
try (FileInputStream tarFis = new FileInputStream(tempFile);
TarArchiveInputStream tarInput = new TarArchiveInputStream(tarFis)) {
@@ -706,12 +715,16 @@ private static void decompressGzip(File archive, String directory) throws IOExce
File outFile = new File(targetDir, entry.getName());
if (entry.isDirectory()) {
if (!outFile.exists() && !outFile.mkdirs()) {
- throw new IOException("Failed to create directory: " + outFile);
+ String error = "Failed to create directory: " + outFile;
+ log.error(error);
+ throw new IOException(error);
}
} else {
File parent = outFile.getParentFile();
if (!parent.exists() && !parent.mkdirs()) {
- throw new IOException("Failed to create directory: " + parent);
+ String error = "Failed to create parent directory: " + parent;
+ log.error(error);
+ throw new IOException(error);
}
try (FileOutputStream os = new FileOutputStream(outFile)) {
byte[] buffer = new byte[8192];
@@ -742,6 +755,7 @@ private static void decompressGzip(File archive, String directory) throws IOExce
}
}
}
+
if (!tempFile.delete()) {
tempFile.deleteOnExit();
}
From 9bfe03c9878da9d548b541ba8259df1a19487089 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1s=20Sexenian?=
<99925035+tomas-sexenian@users.noreply.github.com>
Date: Wed, 2 Jul 2025 11:19:49 -0300
Subject: [PATCH 49/49] Improvements and optimizations
---
.../genexus/compression/CompressionUtils.java | 41 ++---
.../com/genexus/compression/GXCompressor.java | 165 +++++++++---------
2 files changed, 97 insertions(+), 109 deletions(-)
diff --git a/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java b/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
index ad4963cbd..85aff8520 100644
--- a/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
+++ b/gxcompress/src/main/java/com/genexus/compression/CompressionUtils.java
@@ -22,6 +22,8 @@
public class CompressionUtils {
+ private static final int BUFFER_SIZE = 8192;
+
/**
* Counts the number of entries in an archive file.
*
@@ -39,7 +41,7 @@ public static int countArchiveEntries(File archiveFile) throws IOException {
return zipFile.size();
}
case "7z":
- try (SevenZFile sevenZFile = getSevenZFile(archiveFile.getAbsolutePath())) {
+ try (SevenZFile sevenZFile = getSevenZFile(archiveFile)) {
while (sevenZFile.getNextEntry() != null) {
count++;
}
@@ -81,21 +83,17 @@ public static boolean isArchiveSafe(File archiveFile, String targetDir) throws I
Enumeration extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
- File destinationFile = new File(targetPath, entry.getName()).getCanonicalFile();
- if (!destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) &&
- !destinationFile.getPath().equals(targetPath.getPath())) {
+ if (!isEntryPathSafe(targetPath, entry.getName())) {
return false;
}
}
}
return true;
case "7z":
- try (SevenZFile sevenZFile = getSevenZFile(archiveFile.getAbsolutePath())) {
+ try (SevenZFile sevenZFile = getSevenZFile(archiveFile)) {
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null) {
- File destinationFile = new File(targetPath, entry.getName()).getCanonicalFile();
- if (!destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) &&
- !destinationFile.getPath().equals(targetPath.getPath())) {
+ if (!isEntryPathSafe(targetPath, entry.getName())) {
return false;
}
}
@@ -105,9 +103,7 @@ public static boolean isArchiveSafe(File archiveFile, String targetDir) throws I
try (TarArchiveInputStream tarStream = new TarArchiveInputStream(Files.newInputStream(archiveFile.toPath()))) {
TarArchiveEntry entry;
while ((entry = tarStream.getNextEntry()) != null) {
- File destinationFile = new File(targetPath, entry.getName()).getCanonicalFile();
- if (!destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) &&
- !destinationFile.getPath().equals(targetPath.getPath())) {
+ if (!isEntryPathSafe(targetPath, entry.getName())) {
return false;
}
}
@@ -117,9 +113,7 @@ public static boolean isArchiveSafe(File archiveFile, String targetDir) throws I
String fileName = archiveFile.getName();
if (fileName.endsWith(".gz") && fileName.length() > 3) {
String extractedName = fileName.substring(0, fileName.length() - 3);
- File destinationFile = new File(targetPath, extractedName).getCanonicalFile();
- return destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) ||
- destinationFile.getPath().equals(targetPath.getPath());
+ return isEntryPathSafe(targetPath, extractedName);
}
return true;
case "jar":
@@ -127,9 +121,7 @@ public static boolean isArchiveSafe(File archiveFile, String targetDir) throws I
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
- File destinationFile = new File(targetPath, entry.getName()).getCanonicalFile();
- if (!destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) &&
- !destinationFile.getPath().equals(targetPath.getPath())) {
+ if (!isEntryPathSafe(targetPath, entry.getName())) {
return false;
}
}
@@ -164,7 +156,7 @@ public static long getMaxFileSize(File archiveFile) throws IOException {
}
break;
case "7z":
- try (SevenZFile sevenZFile = getSevenZFile(archiveFile.getAbsolutePath())) {
+ try (SevenZFile sevenZFile = getSevenZFile(archiveFile)) {
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null) {
if (!entry.isDirectory() && entry.getSize() > maxSize) {
@@ -185,7 +177,7 @@ public static long getMaxFileSize(File archiveFile) throws IOException {
break;
case "gz":
try (GZIPInputStream gzStream = new GZIPInputStream(Files.newInputStream(archiveFile.toPath()))) {
- byte[] buffer = new byte[8192];
+ byte[] buffer = new byte[BUFFER_SIZE];
long size = 0;
int n;
while ((n = gzStream.read(buffer)) != -1) {
@@ -241,7 +233,7 @@ public static long estimateDecompressedSize(File archiveFile) throws IOException
}
break;
case "7z":
- try (SevenZFile sevenZFile = getSevenZFile(archiveFile.getAbsolutePath())) {
+ try (SevenZFile sevenZFile = getSevenZFile(archiveFile)) {
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null) {
if (!entry.isDirectory()) {
@@ -304,7 +296,12 @@ public static long estimateDecompressedSize(File archiveFile) throws IOException
return totalSize;
}
- private static SevenZFile getSevenZFile(final String specialPath) throws IOException {
- return SevenZFile.builder().setFile(getFile(specialPath)).get();
+ private static SevenZFile getSevenZFile(File archiveFile) throws IOException {
+ return SevenZFile.builder().setFile(archiveFile).get();
+ }
+
+ private static boolean isEntryPathSafe(File targetPath, String entryName) throws IOException {
+ File destinationFile = new File(targetPath, entryName).getCanonicalFile();
+ return destinationFile.getPath().startsWith(targetPath.getPath() + File.separator) || destinationFile.getPath().equals(targetPath.getPath());
}
}
\ No newline at end of file
diff --git a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
index 796a1fb43..85b4ed934 100644
--- a/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
+++ b/gxcompress/src/main/java/com/genexus/compression/GXCompressor.java
@@ -29,6 +29,7 @@
public class GXCompressor {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(GXCompressor.class);
+ private static final int BUFFER_SIZE = 8192;
private static final String GENERIC_ERROR = "An error occurred during the compression/decompression process: ";
private static final String NO_FILES_ADDED = "No files have been added for compression.";
@@ -338,7 +339,7 @@ private static void zipFile(File fileToZip, String fileName, ZipOutputStream zip
} else {
try (FileInputStream fis = new FileInputStream(fileToZip)) {
zipOut.putNextEntry(new ZipEntry(fileName));
- byte[] bytes = new byte[1024];
+ byte[] bytes = new byte[BUFFER_SIZE];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
@@ -377,7 +378,7 @@ private static void addFileToSevenZ(SevenZOutputFile sevenZOutput, File file, St
SevenZArchiveEntry entry = sevenZOutput.createArchiveEntry(file, entryName);
sevenZOutput.putArchiveEntry(entry);
try (FileInputStream fis = new FileInputStream(file)) {
- byte[] buffer = new byte[8192];
+ byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = fis.read(buffer)) > 0) {
sevenZOutput.write(buffer, 0, len);
@@ -420,7 +421,7 @@ private static void addFileToTar(TarArchiveOutputStream tarOut, File file, Strin
entry.setSize(file.length());
tarOut.putArchiveEntry(entry);
try (FileInputStream fis = new FileInputStream(file)) {
- byte[] buffer = new byte[8192];
+ byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = fis.read(buffer)) != -1) {
tarOut.write(buffer, 0, len);
@@ -454,7 +455,7 @@ private static void compressToGzip(File[] files, String outputPath) throws IOExc
BufferedOutputStream bos = new BufferedOutputStream(fos);
GzipCompressorOutputStream gcos = new GzipCompressorOutputStream(bos)
) {
- byte[] buffer = new byte[8192];
+ byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = fis.read(buffer)) != -1) {
gcos.write(buffer, 0, len);
@@ -487,16 +488,12 @@ private static void compressToGzip(File[] files, String outputPath) throws IOExc
fileStack.push(child);
pathStack.push(entryName + "/");
}
- } else {
- TarArchiveEntry entry = new TarArchiveEntry(entryName + "/");
- taos.putArchiveEntry(entry);
- taos.closeArchiveEntry();
}
} else {
TarArchiveEntry entry = new TarArchiveEntry(currentFile, entryName);
taos.putArchiveEntry(entry);
try (FileInputStream fis = new FileInputStream(currentFile)) {
- byte[] buffer = new byte[8192];
+ byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = fis.read(buffer)) != -1) {
taos.write(buffer, 0, len);
@@ -542,7 +539,7 @@ private static void compressToJar(File[] files, String outputPath) throws IOExce
throw new IOException("Output file already exists");
}
try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(outputFile.toPath()))) {
- byte[] buffer = new byte[1024];
+ byte[] buffer = new byte[BUFFER_SIZE];
for (File file : files) {
if (file == null || !file.exists()) {
continue;
@@ -568,19 +565,16 @@ private static void compressToJar(File[] files, String outputPath) throws IOExce
jos.closeEntry();
}
} else {
- FileInputStream fis = null;
+ jos.putNextEntry(new JarEntry(entryName));
try {
- jos.putNextEntry(new JarEntry(entryName));
- fis = new FileInputStream(currentFile);
- int len;
- while ((len = fis.read(buffer)) > 0) {
- jos.write(buffer, 0, len);
+ try (FileInputStream fis = new FileInputStream(currentFile)) {
+ int len;
+ while ((len = fis.read(buffer)) > 0) {
+ jos.write(buffer, 0, len);
+ }
}
- jos.closeEntry();
} finally {
- if (fis != null) {
- fis.close();
- }
+ jos.closeEntry();
}
}
}
@@ -589,83 +583,81 @@ private static void compressToJar(File[] files, String outputPath) throws IOExce
}
private static void decompressZip(File archive, String directory) throws IOException {
- byte[] buffer = new byte[1024];
- ZipInputStream zis = new ZipInputStream(Files.newInputStream(archive.toPath()));
- ZipEntry zipEntry = zis.getNextEntry();
- while (zipEntry != null) {
- File newFile = new File(directory, zipEntry.getName());
- if (zipEntry.isDirectory()) {
- if (!newFile.isDirectory() && !newFile.mkdirs()) {
- throw new IOException("Failed to create directory " + newFile);
- }
- } else {
- File parent = newFile.getParentFile();
- if (!parent.isDirectory() && !parent.mkdirs()) {
- throw new IOException("Failed to create directory " + parent);
- }
- FileOutputStream fos = new FileOutputStream(newFile);
- int len;
- while ((len = zis.read(buffer)) > 0) {
- fos.write(buffer, 0, len);
+ byte[] buffer = new byte[BUFFER_SIZE];
+ try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(archive.toPath()))) {
+ ZipEntry zipEntry;
+ while ((zipEntry = zis.getNextEntry()) != null) {
+ File newFile = new File(directory, zipEntry.getName());
+ if (zipEntry.isDirectory()) {
+ if (!newFile.isDirectory() && !newFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + newFile);
+ }
+ } else {
+ File parent = newFile.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory " + parent);
+ }
+ try (FileOutputStream fos = new FileOutputStream(newFile)) {
+ int len;
+ while ((len = zis.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ }
+ }
}
- fos.close();
}
- zipEntry = zis.getNextEntry();
}
- zis.closeEntry();
- zis.close();
}
private static void decompress7z(File archive, String directory) throws IOException {
- SevenZFile sevenZFile = new SevenZFile(archive);
- SevenZArchiveEntry entry;
- byte[] buffer = new byte[8192];
- while ((entry = sevenZFile.getNextEntry()) != null) {
- File newFile = new File(directory, entry.getName());
- if (entry.isDirectory()) {
- if (!newFile.isDirectory() && !newFile.mkdirs()) {
- throw new IOException("Failed to create directory " + newFile);
- }
- } else {
- File parent = newFile.getParentFile();
- if (!parent.isDirectory() && !parent.mkdirs()) {
- throw new IOException("Failed to create directory " + parent);
- }
- OutputStream out = Files.newOutputStream(newFile.toPath());
- int bytesRead;
- while ((bytesRead = sevenZFile.read(buffer)) != -1) {
- out.write(buffer, 0, bytesRead);
+ byte[] buffer = new byte[BUFFER_SIZE];
+ try (SevenZFile sevenZFile = new SevenZFile(archive)) {
+ SevenZArchiveEntry entry;
+ while ((entry = sevenZFile.getNextEntry()) != null) {
+ File newFile = new File(directory, entry.getName());
+ if (entry.isDirectory()) {
+ if (!newFile.isDirectory() && !newFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + newFile);
+ }
+ } else {
+ File parent = newFile.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory " + parent);
+ }
+ try (OutputStream out = Files.newOutputStream(newFile.toPath())) {
+ int bytesRead;
+ while ((bytesRead = sevenZFile.read(buffer)) != -1) {
+ out.write(buffer, 0, bytesRead);
+ }
+ }
}
- out.close();
}
}
- sevenZFile.close();
}
private static void decompressTar(File archive, String directory) throws IOException {
- TarArchiveInputStream tis = new TarArchiveInputStream(Files.newInputStream(archive.toPath()));
- TarArchiveEntry entry;
- byte[] buffer = new byte[8192];
- while ((entry = tis.getNextEntry()) != null) {
- File newFile = new File(directory, entry.getName());
- if (entry.isDirectory()) {
- if (!newFile.isDirectory() && !newFile.mkdirs()) {
- throw new IOException("Failed to create directory " + newFile);
- }
- } else {
- File parent = newFile.getParentFile();
- if (!parent.isDirectory() && !parent.mkdirs()) {
- throw new IOException("Failed to create directory " + parent);
- }
- OutputStream out = Files.newOutputStream(newFile.toPath());
- int len;
- while ((len = tis.read(buffer)) != -1) {
- out.write(buffer, 0, len);
+ byte[] buffer = new byte[BUFFER_SIZE];
+ try (TarArchiveInputStream tis = new TarArchiveInputStream(Files.newInputStream(archive.toPath()))) {
+ TarArchiveEntry entry;
+ while ((entry = tis.getNextEntry()) != null) {
+ File newFile = new File(directory, entry.getName());
+ if (entry.isDirectory()) {
+ if (!newFile.isDirectory() && !newFile.mkdirs()) {
+ throw new IOException("Failed to create directory " + newFile);
+ }
+ } else {
+ File parent = newFile.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ throw new IOException("Failed to create directory " + parent);
+ }
+ try (OutputStream out = Files.newOutputStream(newFile.toPath())) {
+ int len;
+ while ((len = tis.read(buffer)) != -1) {
+ out.write(buffer, 0, len);
+ }
+ }
}
- out.close();
}
}
- tis.close();
}
private static void decompressGzip(File archive, String directory) throws IOException {
@@ -690,7 +682,7 @@ private static void decompressGzip(File archive, String directory) throws IOExce
GZIPInputStream gzipInputStream = new GZIPInputStream(fis);
FileOutputStream fos = new FileOutputStream(tempFile)
) {
- byte[] buffer = new byte[8192];
+ byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = gzipInputStream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
@@ -727,7 +719,7 @@ private static void decompressGzip(File archive, String directory) throws IOExce
throw new IOException(error);
}
try (FileOutputStream os = new FileOutputStream(outFile)) {
- byte[] buffer = new byte[8192];
+ byte[] buffer = new byte[BUFFER_SIZE];
int count;
while ((count = tarInput.read(buffer)) != -1) {
os.write(buffer, 0, count);
@@ -747,7 +739,7 @@ private static void decompressGzip(File archive, String directory) throws IOExce
FileInputStream in = new FileInputStream(tempFile);
FileOutputStream out = new FileOutputStream(singleOutFile)
) {
- byte[] buffer = new byte[8192];
+ byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
@@ -785,14 +777,13 @@ private static void decompressJar(File archive, String directory) throws IOExcep
throw new IOException("Failed to create parent directory: " + parent.getAbsolutePath());
}
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- byte[] buffer = new byte[1024];
+ byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = jarInputStream.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
}
- jarInputStream.closeEntry();
}
}
}