You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2025/05/05 12:14:21 UTC
(commons-io) branch master updated: [IO-875] CopyDirectoryVisitor ignores fileFilter (#743)
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git
The following commit(s) were added to refs/heads/master by this push:
new 5bcc9a889 [IO-875] CopyDirectoryVisitor ignores fileFilter (#743)
5bcc9a889 is described below
commit 5bcc9a8890ccb33b1615ac5e0a74f56bc7c01037
Author: Pierre Baumard <pb...@gmail.com>
AuthorDate: Mon May 5 14:14:16 2025 +0200
[IO-875] CopyDirectoryVisitor ignores fileFilter (#743)
* [IO-875] CopyDirectoryVisitor ignores fileFilter
* 100% test coverage for CopyDirectoryVisitor
* Fix javadoc typo
---
.../commons/io/file/CopyDirectoryVisitor.java | 11 ++++--
.../commons/io/file/CountingPathVisitor.java | 16 +++++++-
.../commons/io/file/CopyDirectoryVisitorTest.java | 44 ++++++++++++++++++----
3 files changed, 58 insertions(+), 13 deletions(-)
diff --git a/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java b/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java
index 2716357b8..da9d1408c 100644
--- a/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java
+++ b/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java
@@ -45,7 +45,7 @@ private static CopyOption[] toCopyOption(final CopyOption... copyOptions) {
private final Path targetDirectory;
/**
- * Constructs a instance that deletes files except for the files and directories explicitly given.
+ * Constructs an instance that copies all files.
*
* @param pathCounter How to count visits.
* @param sourceDirectory The source directory
@@ -60,7 +60,7 @@ public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDir
}
/**
- * Constructs a instance that deletes files except for the files and directories explicitly given.
+ * Constructs an instance that copies files matching the given file and directory filters.
*
* @param pathCounter How to count visits.
* @param fileFilter How to filter file paths.
@@ -171,8 +171,11 @@ private Path resolveRelativeAsString(final Path directory) {
@Override
public FileVisitResult visitFile(final Path sourceFile, final BasicFileAttributes attributes) throws IOException {
final Path targetFile = resolveRelativeAsString(sourceFile);
- copy(sourceFile, targetFile);
- return super.visitFile(targetFile, attributes);
+ if (accept(sourceFile, attributes)) {
+ copy(sourceFile, targetFile);
+ updateFileCounters(targetFile, attributes);
+ }
+ return FileVisitResult.CONTINUE;
}
}
diff --git a/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java b/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java
index a8ca9055f..d0a58251e 100644
--- a/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java
+++ b/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java
@@ -290,6 +290,18 @@ protected void updateDirCounter(final Path dir, final IOException exc) {
pathCounters.getDirectoryCounter().increment();
}
+ /**
+ * Returns true to copy the given file, false if not.
+ *
+ * @param file the visited file.
+ * @param attributes the visited file attributes.
+ * @return true to copy the given file, false if not.
+ */
+ protected boolean accept(final Path file, final BasicFileAttributes attributes) {
+ // Note: A file can be a symbolic link to a directory.
+ return Files.exists(file) && fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE;
+ }
+
/**
* Updates the counters for visiting the given file.
*
@@ -303,10 +315,10 @@ protected void updateFileCounters(final Path file, final BasicFileAttributes att
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) throws IOException {
- // Note: A file can be a symbolic link to a directory.
- if (Files.exists(file) && fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE) {
+ if (accept(file, attributes)) {
updateFileCounters(file, attributes);
}
return FileVisitResult.CONTINUE;
}
+
}
diff --git a/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java b/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java
index e61c5cfe7..1bf5e90cd 100644
--- a/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java
+++ b/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java
@@ -20,23 +20,27 @@
import static org.apache.commons.io.file.CounterAssertions.assertCounts;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.nio.file.CopyOption;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.function.Supplier;
import org.apache.commons.io.file.Counters.PathCounters;
+import org.apache.commons.io.filefilter.NameFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/**
- * Tests {@link CountingPathVisitor}.
+ * Tests {@link CopyDirectoryVisitor}.
*/
public class CopyDirectoryVisitorTest extends TestArguments {
@@ -59,19 +63,22 @@ public void testCopyDirectoryEmptyFolder(final PathCounters pathCounters) throws
assertEquals(sourceDir.get(), ((AbstractPathWrapper) visitFileTree.getSourceDirectory()).get());
assertEquals(sourceDir, visitFileTree.getSourceDirectory());
assertEquals(targetDir, visitFileTree.getTargetDirectory());
- assertEquals(targetDir, visitFileTree.getTargetDirectory());
- //
+ // Tests equals and hashCode
assertEquals(visitFileTree, supplier.get());
assertEquals(visitFileTree.hashCode(), supplier.get().hashCode());
assertEquals(visitFileTree, visitFileTree);
assertEquals(visitFileTree.hashCode(), visitFileTree.hashCode());
assertNotEquals(visitFileTree, "not");
+ assertNotEquals(visitFileTree, new DeletingPathVisitor(pathCounters));
+ assertNotEquals(visitFileTree, new CopyDirectoryVisitor(pathCounters, sourceDir, targetDir));
+ assertNotEquals(visitFileTree, new CopyDirectoryVisitor(pathCounters, sourceDir, sourceDir, EXPECTED_COPY_OPTIONS));
+ assertNotEquals(visitFileTree, new CopyDirectoryVisitor(pathCounters, targetDir, sourceDir, EXPECTED_COPY_OPTIONS));
assertNotEquals(visitFileTree, CountingPathVisitor.withLongCounters());
}
}
/**
- * Tests an empty folder.
+ * Tests an empty folder with filters.
*/
@ParameterizedTest
@MethodSource("pathCounters")
@@ -84,7 +91,7 @@ public void testCopyDirectoryEmptyFolderFilters(final PathCounters pathCounters)
assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions());
assertEquals(sourceDir, visitFileTree.getSourceDirectory());
assertEquals(targetDir, visitFileTree.getTargetDirectory());
- //
+ // Tests equals and hashCode
assertEquals(visitFileTree, supplier.get());
assertEquals(visitFileTree.hashCode(), supplier.get().hashCode());
assertEquals(visitFileTree, visitFileTree);
@@ -92,6 +99,26 @@ public void testCopyDirectoryEmptyFolderFilters(final PathCounters pathCounters)
}
}
+ /**
+ * Tests filters.
+ */
+ @ParameterizedTest
+ @MethodSource("pathCounters")
+ public void testCopyDirectoryFilters(final PathCounters pathCounters) throws IOException {
+ final Path sourceDir = Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-4");
+ final CopyDirectoryVisitor visitFileTree = PathUtils.visitFileTree(new CopyDirectoryVisitor(pathCounters, new NameFileFilter("file-size-1.bin"),
+ new NameFileFilter("dirs-2-file-size-4", "dirs-a-file-size-1"), sourceDir, targetDir, null),
+ sourceDir);
+ assertCounts(2, 1, 2, visitFileTree);
+ assertArrayEquals(PathUtils.EMPTY_COPY_OPTIONS, visitFileTree.getCopyOptions());
+ assertEquals(sourceDir, visitFileTree.getSourceDirectory());
+ assertEquals(targetDir, visitFileTree.getTargetDirectory());
+ assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1/file-size-1.bin")));
+ assertFalse(Files.exists(targetDir.resolve("dirs-a-file-size-1/file-size-2.bin")));
+ assertFalse(Files.exists(targetDir.resolve("dirs-a-file-size-2")));
+ }
+
+
/**
* Tests a directory with one file of size 0.
*/
@@ -105,10 +132,10 @@ public void testCopyDirectoryFolders1FileSize0(final PathCounters pathCounters)
assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions());
assertEquals(sourceDir, visitFileTree.getSourceDirectory());
assertEquals(targetDir, visitFileTree.getTargetDirectory());
- //
+ assertTrue(Files.exists(targetDir.resolve("file-size-0.bin")));
+ // Tests equals and hashCode
assertEquals(visitFileTree, supplier.get());
assertEquals(visitFileTree.hashCode(), supplier.get().hashCode());
- assertEquals(visitFileTree, visitFileTree);
assertEquals(visitFileTree.hashCode(), visitFileTree.hashCode());
}
@@ -125,6 +152,7 @@ public void testCopyDirectoryFolders1FileSize1(final PathCounters pathCounters)
assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions());
assertEquals(sourceDir, visitFileTree.getSourceDirectory());
assertEquals(targetDir, visitFileTree.getTargetDirectory());
+ assertTrue(Files.exists(targetDir.resolve("file-size-1.bin")));
}
/**
@@ -140,6 +168,8 @@ public void testCopyDirectoryFolders2FileSize2(final PathCounters pathCounters)
assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions());
assertEquals(sourceDir, visitFileTree.getSourceDirectory());
assertEquals(targetDir, visitFileTree.getTargetDirectory());
+ assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1/file-size-1.bin")));
+ assertTrue(Files.exists(targetDir.resolve("dirs-b-file-size-1/file-size-1.bin")));
}
}