diff --git a/solidify-util/src/main/java/ch/unige/solidify/util/ZipTool.java b/solidify-util/src/main/java/ch/unige/solidify/util/ZipTool.java index b3e310b9d86a2b6465719e89eafa56376ae61c1c..a2631596f273963abcbb24412751d9ed6e401017 100644 --- a/solidify-util/src/main/java/ch/unige/solidify/util/ZipTool.java +++ b/solidify-util/src/main/java/ch/unige/solidify/util/ZipTool.java @@ -50,6 +50,7 @@ import java.util.zip.ZipOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.AntPathMatcher; import ch.unige.solidify.SolidifyConstants; import ch.unige.solidify.exception.SolidifyRuntimeException; @@ -162,10 +163,11 @@ public class ZipTool { if (fileAndDirectoryList == null) { return true; } + final AntPathMatcher antPathMatcher = new AntPathMatcher(); for (final String file : fileAndDirectoryList) { final String normalizedPath = normalizePath(file); final String zePath = ze.getName(); - if (zePath.equals(normalizedPath) || zePath.startsWith(useAsDirectory(normalizedPath))) { + if (antPathMatcher.match(normalizedPath, zePath) || zePath.startsWith(useAsDirectory(normalizedPath))) { return true; } } @@ -316,6 +318,16 @@ public class ZipTool { return extractedFiles; } + /** + * Unzip the specified list of files and directories into the given destination. + * files can be specified with Ant-style path patterns. + * directories must be specified explicitly, an optional trailing slash can be added + * + * @param destination the directory in which to extract the provided files and directories + * @param fileAndDirectoryList a list of file or directory paths to unzip + * @param checkEmptyDestination if {@code true}, verifies that the destination directory is empty before unzipping + * @return {@code true} if the unzip operation completes successfully; {@code false} otherwise + */ public boolean unzipFiles(Path destination, List<String> fileAndDirectoryList, boolean checkEmptyDestination) { return this.unzipFiles(destination, fileAndDirectoryList, null, checkEmptyDestination); } diff --git a/solidify-util/src/test/java/ch/unige/solidify/test/util/ZipTest.java b/solidify-util/src/test/java/ch/unige/solidify/test/util/ZipTest.java index 986a0d1466064efa76c761391960df578eb046d9..cbae719966524009f2c2b46480d4f542536f159f 100644 --- a/solidify-util/src/test/java/ch/unige/solidify/test/util/ZipTest.java +++ b/solidify-util/src/test/java/ch/unige/solidify/test/util/ZipTest.java @@ -31,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.io.IOException; import java.net.URI; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -39,6 +40,7 @@ import java.util.List; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.core.io.ClassPathResource; @@ -64,7 +66,6 @@ class ZipTest { private static final String ZIP_DIR = "dlcm"; private static final int ZIP_FILE_NUMBER = 17; private static final int ZIP_INCLUDE_NUMBER = 8; - private static final int ZIP_XSD_NUMBER = 9; @Test void createZipByListFilesTest() throws IOException { @@ -172,6 +173,41 @@ class ZipTest { assertTrue(FileTool.deleteFolder(unzipDir)); } + @ParameterizedTest + @CsvSource({"abc*, 1", + "*, 2", + "dir1/ab.txt, 1", + "dir1/ab*.txt, 2", + "**, 6", + "dir1, 4", + "dir1/, 4", + "dir1\\, 4", + "dir1/*, 2", + "di*/*, 2", + "di*, 0", + "dir1/dir2, 2", + "dir1/dir2/ab.txt, 1", + "dir1/dir2/ab*, 2"}) + void antExpressionUnzipArchiveTest(String antExpression, int expectedNumber) throws IOException { + final Path zipFilePath = Paths.get(new ClassPathResource("zip/zip_ant_test.zip").getURI()); + final Path unzipDir = Paths + .get(System.getProperty("java.io.tmpdir") + File.separatorChar + UNZIP_DIR); + final ZipTool zipTool = new ZipTool(zipFilePath.toString()); + final List<String> extractList = List.of(antExpression); + assertTrue(zipTool.unzipFiles(unzipDir, extractList, true)); + final List<Path> fileList = new ArrayList<>(FileTool.readFolder(unzipDir)); + final Path dir1 = unzipDir.resolve("dir1"); + final Path dir2 = unzipDir.resolve("dir1/dir2"); + if (Files.exists(dir1)) { + fileList.addAll(FileTool.readFolder(dir1)); + } + if (Files.exists(dir2)) { + fileList.addAll(FileTool.readFolder(dir2)); + } + assertEquals(expectedNumber, fileList.size()); + assertTrue(FileTool.deleteFolder(unzipDir)); + } + @Test void unzipArchiveTest() throws IOException { final Path zipDir = Paths.get(new ClassPathResource(ZIP_DIR).getURI()); diff --git a/solidify-util/src/test/resources/zip/zip_ant_test.zip b/solidify-util/src/test/resources/zip/zip_ant_test.zip new file mode 100644 index 0000000000000000000000000000000000000000..30d39890cecedceee844411a901b16f0186d234e Binary files /dev/null and b/solidify-util/src/test/resources/zip/zip_ant_test.zip differ