Simplify DeleteTrashFolder

Replace inner class with Java 8 stream, Files.walkFileTree() with Files.
walk() and for recursive removal of subtree, use Guava's MoreFiles.
deleteRecursively.

Change-Id: I3007bb608ab27920627d016943b1de67682fd590
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/DeleteTrashFolders.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/DeleteTrashFolders.java
index 07ef2e6..02dc82c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/DeleteTrashFolders.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/fs/DeleteTrashFolders.java
@@ -15,22 +15,20 @@
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Sets;
+import com.google.common.io.MoreFiles;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.config.RepositoryConfig;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
 import java.io.IOException;
-import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitOption;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Set;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.lib.RepositoryCache.FileKey;
-import org.eclipse.jgit.util.FS;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -77,78 +75,36 @@
     repoFolders.addAll(repositoryCfg.getAllBasePaths());
   }
 
-  class TrashFolderRemover extends SimpleFileVisitor<Path> {
-
-    @Override
-    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
-        throws IOException {
-      String fName = dir.getFileName().toString();
-      if (TrashFolderPredicate.match(fName)) {
-        log.warn("Will delete this folder: {}", dir);
-        recursiveDelete(dir);
-        return FileVisitResult.SKIP_SUBTREE;
-      } else if (FileKey.isGitRepository(dir.toFile(), FS.DETECTED)) {
-        // We are in a GITDIR and don't expect trash folders inside GITDIR's.
-        return FileVisitResult.SKIP_SUBTREE;
-      }
-
-      return super.preVisitDirectory(dir, attrs);
-    }
-
-    /**
-     * Recursively delete the specified file and all of its contents.
-     *
-     * @throws IOException
-     */
-    private void recursiveDelete(Path file) throws IOException {
-      Files.walkFileTree(
-          file,
-          new SimpleFileVisitor<Path>() {
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
-                throws IOException {
-              Files.delete(file);
-              return FileVisitResult.CONTINUE;
-            }
-
-            @Override
-            public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
-              if (e != null) {
-                throw e;
-              }
-              Files.delete(dir);
-              return FileVisitResult.CONTINUE;
-            }
-          });
-    }
-  }
-
   @Override
   public void start() {
     thread =
-        new Thread(
-            () -> {
-              for (Path folder : repoFolders) {
-                if (!folder.toFile().exists()) {
-                  log.debug("Base path {} does not exist", folder);
-                  continue;
-                }
-                try {
-                  Files.walkFileTree(folder, new TrashFolderRemover());
-                } catch (IOException e) {
-                  log.warn("Exception while trying to delete trash folders", e);
-                }
-              }
-            },
-            "DeleteTrashFolders");
+        new Thread(() -> repoFolders.stream().forEach(this::evaluateIfTrash), "DeleteTrashFolders");
     thread.start();
   }
 
+  private void evaluateIfTrash(Path folder) {
+    try (Stream<Path> dir = Files.walk(folder, FileVisitOption.FOLLOW_LINKS)) {
+      dir.filter(Files::isDirectory)
+          .filter(TrashFolderPredicate::match)
+          .forEach(this::recursivelyDelete);
+    } catch (IOException e) {
+      log.error("Failed to evaluate {}", folder, e);
+    }
+  }
+
   @VisibleForTesting
   Thread getWorkerThread() {
     return thread;
   }
 
+  private void recursivelyDelete(Path folder) {
+    try {
+      MoreFiles.deleteRecursively(folder);
+    } catch (IOException e) {
+      log.error("Failed to delete {}", folder, e);
+    }
+  }
+
   @Override
   public void stop() {}
 }