diff --git a/src/main/java/nl/knaw/dans/lib/util/PathIteratorZipper.java b/src/main/java/nl/knaw/dans/lib/util/PathIteratorZipper.java index cddd0a2..999ba6c 100644 --- a/src/main/java/nl/knaw/dans/lib/util/PathIteratorZipper.java +++ b/src/main/java/nl/knaw/dans/lib/util/PathIteratorZipper.java @@ -35,7 +35,7 @@ /** * Zips files from an iterator of paths into a zip file up to a maximum number of files and bytes (the first limit reached). The resulting ZIP file can be compressed or not. The files in the ZIP file - * can be renamed. The ZIP file can be overwritten if it already exists. + * can be renamed. The ZIP file can be overwritten if it already exists. Note that directory entries are not included in the ZIP file, as this is not formally required by the ZIP file format. */ @Builder @RequiredArgsConstructor(access = AccessLevel.PRIVATE) @@ -114,6 +114,8 @@ public Path zip() throws IOException { catch (IOException e) { throw new RuntimeException(e); } + } else if (!Files.exists(path)) { + throw new IllegalArgumentException("File to zip does not exist: " + path); } } } diff --git a/src/test/java/nl/knaw/dans/lib/util/PathIteratorZipperTest.java b/src/test/java/nl/knaw/dans/lib/util/PathIteratorZipperTest.java index 46baf40..49c9d12 100644 --- a/src/test/java/nl/knaw/dans/lib/util/PathIteratorZipperTest.java +++ b/src/test/java/nl/knaw/dans/lib/util/PathIteratorZipperTest.java @@ -16,16 +16,21 @@ package nl.knaw.dans.lib.util; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.TrueFileFilter; import org.junit.jupiter.api.Test; +import java.io.File; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.Iterator; +import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; public class PathIteratorZipperTest extends AbstractTestWithTestDir { @@ -113,7 +118,7 @@ public void zip_should_zip_also_files_in_subdirectories() throws Exception { FileUtils.writeStringToFile(inputDir.resolve("dir2/file4.txt").toFile(), "Bonjour, monde!", StandardCharsets.UTF_8); // When - Iterator pathIterator = new PathIterator(FileUtils.iterateFiles(inputDir.toFile(), null, true)); + Iterator pathIterator = new PathIterator(FileUtils.iterateFilesAndDirs(inputDir.toFile(), TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE)); PathIteratorZipper.builder() .rootDir(inputDir) .sourceIterator(pathIterator) @@ -166,4 +171,71 @@ public void zip_should_zip_only_files_up_to_maxNumberOfFiles() throws Exception assertThat(zipFile.stream().map(ZipEntry::getName)).containsExactlyInAnyOrder("file3.txt", "file4.txt"); } } + + @Test + public void zip_should_throw_IllegalArgumentException_if_non_existent_file_included_by_iterator() throws Exception { + // Given + Iterator mockIterator = new Iterator() { + + @Override + public boolean hasNext() { + return true; + } + + @Override + public File next() { + return new File("non-existent-file"); + } + }; + + Path inputDir = testDir.resolve("input"); + Files.createDirectories(inputDir); + + // When + Iterator pathIterator = new PathIterator(mockIterator); + PathIteratorZipper zipper = PathIteratorZipper.builder() + .rootDir(inputDir) + .sourceIterator(pathIterator) + .targetZipFile(testDir.resolve("output.zip")) + .build(); + + // Then + assertThatThrownBy(zipper::zip) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("File to zip does not exist: non-existent-file"); + } + + @Test + public void zip_should_throw_IllegalArgumentException_if_non_existent_file_included_by_iterator_after_several_valid_files() throws Exception { + // Given + File inputDir = testDir.resolve("input").toFile(); + List files = Arrays.asList( + new File(inputDir, "file1.txt"), + new File(inputDir, "file2.txt"), + new File(inputDir, "non-existent-file"), + new File(inputDir, "file3.txt") + ); + + Iterator iterator = files.iterator(); + + Files.createDirectories(inputDir.toPath()); + FileUtils.writeStringToFile(files.get(0), "Hello, world!", StandardCharsets.UTF_8); + FileUtils.writeStringToFile(files.get(1), "Hola, mundo!", StandardCharsets.UTF_8); + FileUtils.writeStringToFile(files.get(3), "Hallo, wereld!", StandardCharsets.UTF_8); + + // When + Iterator pathIterator = new PathIterator(iterator); + PathIteratorZipper zipper = PathIteratorZipper.builder() + .rootDir(inputDir.toPath()) + .sourceIterator(pathIterator) + .targetZipFile(testDir.resolve("output.zip")) + .build(); + + // Then + assertThatThrownBy(zipper::zip) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("File to zip does not exist: target/test/PathIteratorZipperTest/input/non-existent-file"); + + } + } \ No newline at end of file