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 abba6c3  [IO-633] Add DeletingFileVisitor.
abba6c3 is described below

commit abba6c3735d0c8c7930011063739ca1467990317
Author: Gary Gregory <gardgreg...@gmail.com>
AuthorDate: Thu Oct 10 15:01:32 2019 -0400

    [IO-633] Add DeletingFileVisitor.
    
    Also add a test to CountingFileVisitor.
---
 src/changes/changes.xml                            |   3 +
 .../commons/io/file/DeletingFileVisitor.java       |  77 +++++++++++
 .../commons/io/file/CountingFileVisitorTest.java   |   7 +-
 .../commons/io/file/DeletingFileVisitorTest.java   | 144 +++++++++++++++++++++
 4 files changed, 230 insertions(+), 1 deletion(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index cdb38e6..87403bd 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -149,6 +149,9 @@ The <action> type attribute can be add,update,fix,remove.
       <action issue="IO-632" dev="ggregory" type="add" due-to="Gary Gregory">
         Add PathUtils for operations on NIO Path.
       </action>
+      <action issue="IO-633" dev="ggregory" type="add" due-to="Gary Gregory">
+        Add DeletingFileVisitor.
+      </action>
     </release>
 
     <release version="2.6" date="2017-10-15" description="Java 7 required, 
Java 9 supported.">
diff --git a/src/main/java/org/apache/commons/io/file/DeletingFileVisitor.java 
b/src/main/java/org/apache/commons/io/file/DeletingFileVisitor.java
new file mode 100644
index 0000000..ed5d5e1
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/file/DeletingFileVisitor.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.io.file;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+
+import org.apache.commons.io.PathUtils;
+
+/**
+ * Deletes files and directories as a visit proceeds.
+ * 
+ * @since 2.7
+ */
+public class DeletingFileVisitor extends CountingFileVisitor {
+
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+    private final String[] skip;
+
+    /**
+     * Constructs a new visitor that deletes files except for the files and 
directories explicitly given.
+     * 
+     * @param skip The files to skip deleting.
+     */
+    public DeletingFileVisitor(final String... skip) {
+        final String[] temp = skip != null ? skip.clone() : EMPTY_STRING_ARRAY;
+        Arrays.sort(temp);
+        this.skip = temp;
+    }
+
+    private boolean accept(final Path path) {
+        return Arrays.binarySearch(skip, path.getFileName().toString()) < 0;
+    }
+
+    @Override
+    public FileVisitResult postVisitDirectory(final Path dir, final 
IOException exc) throws IOException {
+        super.postVisitDirectory(dir, exc);
+        if (PathUtils.isEmptyDirectory(dir)) {
+            Files.deleteIfExists(dir);
+        }
+        return FileVisitResult.CONTINUE;
+    }
+
+    @Override
+    public FileVisitResult preVisitDirectory(final Path dir, final 
BasicFileAttributes attrs) throws IOException {
+        super.preVisitDirectory(dir, attrs);
+        return accept(dir) ? FileVisitResult.CONTINUE : 
FileVisitResult.SKIP_SUBTREE;
+    }
+
+    @Override
+    public FileVisitResult visitFile(final Path file, final 
BasicFileAttributes attrs) throws IOException {
+        super.visitFile(file, attrs);
+        if (accept(file) && Files.exists(file)) {
+            Files.deleteIfExists(file);
+        }
+        return FileVisitResult.CONTINUE;
+    }
+}
\ No newline at end of file
diff --git 
a/src/test/java/org/apache/commons/io/file/CountingFileVisitorTest.java 
b/src/test/java/org/apache/commons/io/file/CountingFileVisitorTest.java
index b65e783..cd2c828 100644
--- a/src/test/java/org/apache/commons/io/file/CountingFileVisitorTest.java
+++ b/src/test/java/org/apache/commons/io/file/CountingFileVisitorTest.java
@@ -43,7 +43,7 @@ public class CountingFileVisitorTest {
             Assertions.assertEquals(0, visitor.getFileCount());
             Assertions.assertEquals(0, visitor.getByteCount());
         } finally {
-            Files.delete(tempDirectory);
+            Files.deleteIfExists(tempDirectory);
         }
     }
 
@@ -82,4 +82,9 @@ public class CountingFileVisitorTest {
         Assertions.assertEquals(2, visitor.getFileCount());
         Assertions.assertEquals(2, visitor.getByteCount());
     }
+    
+    @Test void testToString() {
+        // Make sure it does not blow up
+        new CountingFileVisitor().toString();
+    }
 }
diff --git 
a/src/test/java/org/apache/commons/io/file/DeletingFileVisitorTest.java 
b/src/test/java/org/apache/commons/io/file/DeletingFileVisitorTest.java
new file mode 100644
index 0000000..f9cff34
--- /dev/null
+++ b/src/test/java/org/apache/commons/io/file/DeletingFileVisitorTest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.io.file;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.PathUtils;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link DeletingFileVisitor}.
+ */
+public class DeletingFileVisitorTest {
+
+    private Path tempDirectory;
+
+    @AfterEach
+    public void afterEach() throws IOException {
+        // backstop
+        if (Files.exists(tempDirectory) && 
PathUtils.isEmptyDirectory(tempDirectory)) {
+            Files.deleteIfExists(tempDirectory);
+        }
+    }
+
+    @BeforeEach
+    public void beforeEach() throws IOException {
+        tempDirectory = 
Files.createTempDirectory(getClass().getCanonicalName());
+    }
+
+    /**
+     * Tests an empty folder.
+     */
+    @Test
+    public void testEmptyDirectory() throws IOException {
+        testEmptyDirectory(new DeletingFileVisitor());
+        // This will throw if not empty.
+        Files.deleteIfExists(tempDirectory);
+    }
+
+    private void testEmptyDirectory(final CountingFileVisitor visitor) throws 
IOException {
+        Files.walkFileTree(tempDirectory, visitor);
+        Assertions.assertEquals(1, visitor.getDirectoryCount());
+        Assertions.assertEquals(0, visitor.getFileCount());
+        Assertions.assertEquals(0, visitor.getByteCount());
+    }
+
+    /**
+     * Tests an empty folder.
+     */
+    @Test
+    public void testEmptyDirectoryNullCtorArg() throws IOException {
+        testEmptyDirectory(new DeletingFileVisitor((String[]) null));
+        // This will throw if not empty.
+        Files.deleteIfExists(tempDirectory);
+    }
+
+    /**
+     * Tests a directory with one file of size 0.
+     */
+    @Test
+    public void testFolders1FileSize0() throws IOException {
+        
FileUtils.copyDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-0").toFile(),
+                tempDirectory.toFile());
+        final CountingFileVisitor visitor = new DeletingFileVisitor();
+        Files.walkFileTree(tempDirectory, visitor);
+        Assertions.assertEquals(1, visitor.getDirectoryCount());
+        Assertions.assertEquals(1, visitor.getFileCount());
+        Assertions.assertEquals(0, visitor.getByteCount());
+        // This will throw if not empty.
+        Files.deleteIfExists(tempDirectory);
+    }
+
+    /**
+     * Tests a directory with one file of size 1.
+     */
+    @Test
+    public void testFolders1FileSize1() throws IOException {
+        
FileUtils.copyDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1").toFile(),
+                tempDirectory.toFile());
+        final CountingFileVisitor visitor = new DeletingFileVisitor();
+        Files.walkFileTree(tempDirectory, visitor);
+        Assertions.assertEquals(1, visitor.getDirectoryCount());
+        Assertions.assertEquals(1, visitor.getFileCount());
+        Assertions.assertEquals(1, visitor.getByteCount());
+        // This will throw if not empty.
+        Files.deleteIfExists(tempDirectory);
+    }
+
+    /**
+     * Tests a directory with one file of size 1 but skip that file.
+     */
+    @Test
+    public void testFolders1FileSize1Skip() throws IOException {
+        
FileUtils.copyDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1").toFile(),
+                tempDirectory.toFile());
+        final String skipFileName = "file-size-1.bin";
+        final CountingFileVisitor visitor = new 
DeletingFileVisitor(skipFileName);
+        Files.walkFileTree(tempDirectory, visitor);
+        Assertions.assertEquals(1, visitor.getDirectoryCount());
+        Assertions.assertEquals(1, visitor.getFileCount());
+        Assertions.assertEquals(1, visitor.getByteCount());
+        final Path skippedFile = tempDirectory.resolve(skipFileName);
+        Assertions.assertTrue(Files.exists(skippedFile));
+        Files.delete(skippedFile);
+    }
+
+    /**
+     * Tests a directory with two subdirectorys, each containing one file of 
size 1.
+     */
+    @Test
+    public void testFolders2FileSize2() throws IOException {
+        
FileUtils.copyDirectory(Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2").toFile(),
+                tempDirectory.toFile());
+        final CountingFileVisitor visitor = new DeletingFileVisitor();
+        Files.walkFileTree(tempDirectory, visitor);
+        Assertions.assertEquals(3, visitor.getDirectoryCount());
+        Assertions.assertEquals(2, visitor.getFileCount());
+        Assertions.assertEquals(2, visitor.getByteCount());
+        // This will throw if not empty.
+        Files.deleteIfExists(tempDirectory);
+    }
+}

Reply via email to