Bladeren bron

Replaced DirectoryWalker by FileSystemVisitor

Markus Kreusch 9 jaren geleden
bovenliggende
commit
260303127e

+ 46 - 9
main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystemVisitor.java

@@ -1,5 +1,7 @@
 package org.cryptomator.filesystem;
 
+import static java.lang.String.format;
+
 import java.util.function.Consumer;
 
 public class FileSystemVisitor {
@@ -7,11 +9,15 @@ public class FileSystemVisitor {
 	private final Consumer<Folder> beforeFolderVisitor;
 	private final Consumer<Folder> afterFolderVisitor;
 	private final Consumer<File> fileVisitor;
-
-	private FileSystemVisitor(Consumer<Folder> beforeFolderVisitor, Consumer<Folder> afterFolderVisitor, Consumer<File> fileVisitor) {
-		this.beforeFolderVisitor = beforeFolderVisitor;
-		this.afterFolderVisitor = afterFolderVisitor;
-		this.fileVisitor = fileVisitor;
+	private final Consumer<Node> nodeVisitor;
+	private final int maxDepth;
+
+	public FileSystemVisitor(FileSystemVisitorBuilder builder) {
+		this.beforeFolderVisitor = builder.beforeFolderVisitor;
+		this.afterFolderVisitor = builder.afterFolderVisitor;
+		this.fileVisitor = builder.fileVisitor;
+		this.nodeVisitor = builder.nodeVisitor;
+		this.maxDepth = builder.maxDepth;
 	}
 
 	public static FileSystemVisitorBuilder fileSystemVisitor() {
@@ -19,14 +25,27 @@ public class FileSystemVisitor {
 	}
 
 	public FileSystemVisitor visit(Folder folder) {
+		return visit(folder, 0);
+	}
+
+	public FileSystemVisitor visit(File file) {
+		return visit(file, 0);
+	}
+
+	private FileSystemVisitor visit(Folder folder, int depth) {
 		beforeFolderVisitor.accept(folder);
-		folder.folders().forEach(this::visit);
-		folder.files().forEach(this::visit);
+		nodeVisitor.accept(folder);
+		final int childDepth = depth + 1;
+		if (childDepth <= maxDepth) {
+			folder.folders().forEach(childFolder -> visit(childFolder, childDepth));
+			folder.files().forEach(childFile -> visit(childFile, childDepth));
+		}
 		afterFolderVisitor.accept(folder);
 		return this;
 	}
 
-	public FileSystemVisitor visit(File file) {
+	private FileSystemVisitor visit(File file, int depth) {
+		nodeVisitor.accept(file);
 		fileVisitor.accept(file);
 		return this;
 	}
@@ -36,6 +55,8 @@ public class FileSystemVisitor {
 		private Consumer<Folder> beforeFolderVisitor = noOp();
 		private Consumer<Folder> afterFolderVisitor = noOp();
 		private Consumer<File> fileVisitor = noOp();
+		private Consumer<Node> nodeVisitor = noOp();
+		private int maxDepth = Integer.MAX_VALUE;
 
 		private FileSystemVisitorBuilder() {
 		}
@@ -64,6 +85,22 @@ public class FileSystemVisitor {
 			return this;
 		}
 
+		public FileSystemVisitorBuilder forEachNode(Consumer<Node> nodeVisitor) {
+			if (nodeVisitor == null) {
+				throw new IllegalArgumentException("Vistior may not be null");
+			}
+			this.nodeVisitor = nodeVisitor;
+			return this;
+		}
+
+		public FileSystemVisitorBuilder withMaxDepth(int maxDepth) {
+			if (maxDepth < 0) {
+				throw new IllegalArgumentException(format("maxDepth must not be smaller 0 but was %d", maxDepth));
+			}
+			this.maxDepth = maxDepth;
+			return this;
+		}
+
 		public FileSystemVisitor visit(Folder folder) {
 			return build().visit(folder);
 		}
@@ -73,7 +110,7 @@ public class FileSystemVisitor {
 		}
 
 		public FileSystemVisitor build() {
-			return new FileSystemVisitor(beforeFolderVisitor, afterFolderVisitor, fileVisitor);
+			return new FileSystemVisitor(this);
 		}
 
 		private static <T> Consumer<T> noOp() {

+ 12 - 9
main/filesystem-crypto/src/test/java/org/cryptomator/crypto/fs/CryptoFileSystemTest.java

@@ -8,6 +8,8 @@
  *******************************************************************************/
 package org.cryptomator.crypto.fs;
 
+import static org.cryptomator.filesystem.FileSystemVisitor.fileSystemVisitor;
+
 import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.nio.ByteBuffer;
@@ -175,15 +177,16 @@ public class CryptoFileSystemTest {
 	 */
 	private static int countDataFolders(Folder dataRoot) {
 		final AtomicInteger num = new AtomicInteger();
-		DirectoryWalker.walk(dataRoot, 0, 2, (node) -> {
-			if (node instanceof Folder) {
-				final Folder nodeParent = node.parent().get();
-				final Folder nodeParentParent = nodeParent.parent().orElse(null);
-				if (nodeParentParent != null && nodeParentParent.equals(dataRoot)) {
-					num.incrementAndGet();
-				}
-			}
-		});
+		fileSystemVisitor() //
+				.afterFolder(folder -> {
+					final Folder parent = folder.parent().get();
+					final Folder parentOfParent = parent.parent().orElse(null);
+					if (parentOfParent != null && parentOfParent.equals(dataRoot)) {
+						num.incrementAndGet();
+					}
+				}) //
+				.withMaxDepth(2) //
+				.visit(dataRoot);
 		return num.get();
 	}
 

+ 16 - 19
main/filesystem-crypto/src/test/java/org/cryptomator/crypto/fs/DirectoryPrinter.java

@@ -8,9 +8,8 @@
  *******************************************************************************/
 package org.cryptomator.crypto.fs;
 
-import java.util.Optional;
+import static org.cryptomator.filesystem.FileSystemVisitor.fileSystemVisitor;
 
-import org.cryptomator.filesystem.File;
 import org.cryptomator.filesystem.Folder;
 
 public final class DirectoryPrinter {
@@ -18,23 +17,21 @@ public final class DirectoryPrinter {
 	private DirectoryPrinter() {
 	}
 
-	public static String print(Folder folder) {
-		StringBuilder sb = new StringBuilder(folder.name()).append('\n');
-
-		DirectoryWalker.walk(folder, (node) -> {
-			Optional<? extends Folder> parent = node.parent();
-			while (parent.isPresent()) {
-				sb.append("  ");
-				parent = parent.get().parent();
-			}
-			if (node instanceof Folder) {
-				sb.append(node.name()).append('/').append('\n');
-			} else if (node instanceof File) {
-				sb.append(node.name()).append('\n');
-			}
-		});
-
-		return sb.toString();
+	public static String print(Folder rootFolder) {
+		StringBuilder result = new StringBuilder();
+		StringBuilder identation = new StringBuilder();
+		fileSystemVisitor() //
+				.beforeFolder(folder -> {
+					result.append(identation).append(folder.name()).append("/\n");
+					identation.append("  ");
+				}) //
+				.afterFolder(folder -> {
+					identation.delete(identation.length() - 2, identation.length());
+				}).forEachFile(file -> {
+					result.append(identation).append(file.name()).append('\n');
+				}) //
+				.visit(rootFolder);
+		return result.toString();
 	}
 
 }

+ 0 - 38
main/filesystem-crypto/src/test/java/org/cryptomator/crypto/fs/DirectoryWalker.java

@@ -1,38 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015 Sebastian Stenzel and others.
- * This file is licensed under the terms of the MIT license.
- * See the LICENSE.txt file for more info.
- *
- * Contributors:
- *     Sebastian Stenzel - initial API and implementation
- *******************************************************************************/
-package org.cryptomator.crypto.fs;
-
-import java.util.function.Consumer;
-
-import org.cryptomator.filesystem.Folder;
-import org.cryptomator.filesystem.Node;
-
-final class DirectoryWalker {
-
-	private DirectoryWalker() {
-	}
-
-	public static void walk(Folder folder, Consumer<Node> visitor) {
-		walk(folder, 0, Integer.MAX_VALUE, visitor);
-	}
-
-	public static void walk(Folder folder, int depth, int maxDepth, Consumer<Node> visitor) {
-		folder.files().forEach(visitor);
-		if (depth == maxDepth) {
-			return;
-		} else {
-			folder.folders().forEach(childFolder -> {
-				visitor.accept(childFolder);
-				walk(childFolder, depth + 1, maxDepth, visitor);
-			});
-		}
-
-	}
-
-}

+ 7 - 4
main/filesystem-crypto/src/test/java/org/cryptomator/crypto/fs/EncryptAndShortenIntegrationTest.java

@@ -1,5 +1,7 @@
 package org.cryptomator.crypto.fs;
 
+import static org.cryptomator.filesystem.FileSystemVisitor.fileSystemVisitor;
+
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 
@@ -43,10 +45,11 @@ public class EncryptAndShortenIntegrationTest {
 		// names:
 		// LOG.debug("Unlimited filename length:\n" +
 		// DirectoryPrinter.print(shorteningFs));
-		DirectoryWalker.walk(shorteningFs, node -> {
-			Assert.assertFalse(node.name().endsWith(".lng"));
-		});
-
+		fileSystemVisitor() //
+				.forEachNode(node -> {
+					Assert.assertFalse(node.name().endsWith(".lng"));
+				}) //
+				.visit(shorteningFs);
 		// on the third (cleartext layer) we have cleartext names on the root
 		// level:
 		// LOG.debug("Cleartext files:\n" + DirectoryPrinter.print(fs));