mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-04-19 09:06:54 -04:00
delete empty directories inside ./d/
This commit is contained in:
@@ -12,7 +12,7 @@ import static java.lang.String.format;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class FileSystemVisitor {
|
||||
public class FolderVisitor {
|
||||
|
||||
private final Consumer<Folder> beforeFolderVisitor;
|
||||
private final Consumer<Folder> afterFolderVisitor;
|
||||
@@ -20,7 +20,7 @@ public class FileSystemVisitor {
|
||||
private final Consumer<Node> nodeVisitor;
|
||||
private final int maxDepth;
|
||||
|
||||
public FileSystemVisitor(FileSystemVisitorBuilder builder) {
|
||||
public FolderVisitor(FolderVisitorBuilder builder) {
|
||||
this.beforeFolderVisitor = builder.beforeFolderVisitor;
|
||||
this.afterFolderVisitor = builder.afterFolderVisitor;
|
||||
this.fileVisitor = builder.fileVisitor;
|
||||
@@ -28,19 +28,19 @@ public class FileSystemVisitor {
|
||||
this.maxDepth = builder.maxDepth;
|
||||
}
|
||||
|
||||
public static FileSystemVisitorBuilder fileSystemVisitor() {
|
||||
return new FileSystemVisitorBuilder();
|
||||
public static FolderVisitorBuilder folderVisitor() {
|
||||
return new FolderVisitorBuilder();
|
||||
}
|
||||
|
||||
public FileSystemVisitor visit(Folder folder) {
|
||||
public FolderVisitor visit(Folder folder) {
|
||||
return visit(folder, 0);
|
||||
}
|
||||
|
||||
public FileSystemVisitor visit(File file) {
|
||||
public FolderVisitor visit(File file) {
|
||||
return visit(file, 0);
|
||||
}
|
||||
|
||||
private FileSystemVisitor visit(Folder folder, int depth) {
|
||||
private FolderVisitor visit(Folder folder, int depth) {
|
||||
beforeFolderVisitor.accept(folder);
|
||||
nodeVisitor.accept(folder);
|
||||
final int childDepth = depth + 1;
|
||||
@@ -52,13 +52,13 @@ public class FileSystemVisitor {
|
||||
return this;
|
||||
}
|
||||
|
||||
private FileSystemVisitor visit(File file, int depth) {
|
||||
private FolderVisitor visit(File file, int depth) {
|
||||
nodeVisitor.accept(file);
|
||||
fileVisitor.accept(file);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class FileSystemVisitorBuilder {
|
||||
public static class FolderVisitorBuilder {
|
||||
|
||||
private Consumer<Folder> beforeFolderVisitor = noOp();
|
||||
private Consumer<Folder> afterFolderVisitor = noOp();
|
||||
@@ -66,10 +66,10 @@ public class FileSystemVisitor {
|
||||
private Consumer<Node> nodeVisitor = noOp();
|
||||
private int maxDepth = Integer.MAX_VALUE;
|
||||
|
||||
private FileSystemVisitorBuilder() {
|
||||
private FolderVisitorBuilder() {
|
||||
}
|
||||
|
||||
public FileSystemVisitorBuilder beforeFolder(Consumer<Folder> beforeFolderVisitor) {
|
||||
public FolderVisitorBuilder beforeFolder(Consumer<Folder> beforeFolderVisitor) {
|
||||
if (beforeFolderVisitor == null) {
|
||||
throw new IllegalArgumentException("Vistior may not be null");
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public class FileSystemVisitor {
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileSystemVisitorBuilder afterFolder(Consumer<Folder> afterFolderVisitor) {
|
||||
public FolderVisitorBuilder afterFolder(Consumer<Folder> afterFolderVisitor) {
|
||||
if (afterFolderVisitor == null) {
|
||||
throw new IllegalArgumentException("Vistior may not be null");
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public class FileSystemVisitor {
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileSystemVisitorBuilder forEachFile(Consumer<File> fileVisitor) {
|
||||
public FolderVisitorBuilder forEachFile(Consumer<File> fileVisitor) {
|
||||
if (fileVisitor == null) {
|
||||
throw new IllegalArgumentException("Vistior may not be null");
|
||||
}
|
||||
@@ -93,7 +93,7 @@ public class FileSystemVisitor {
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileSystemVisitorBuilder forEachNode(Consumer<Node> nodeVisitor) {
|
||||
public FolderVisitorBuilder forEachNode(Consumer<Node> nodeVisitor) {
|
||||
if (nodeVisitor == null) {
|
||||
throw new IllegalArgumentException("Vistior may not be null");
|
||||
}
|
||||
@@ -101,7 +101,7 @@ public class FileSystemVisitor {
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileSystemVisitorBuilder withMaxDepth(int maxDepth) {
|
||||
public FolderVisitorBuilder withMaxDepth(int maxDepth) {
|
||||
if (maxDepth < 0) {
|
||||
throw new IllegalArgumentException(format("maxDepth must not be smaller 0 but was %d", maxDepth));
|
||||
}
|
||||
@@ -109,16 +109,16 @@ public class FileSystemVisitor {
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileSystemVisitor visit(Folder folder) {
|
||||
public FolderVisitor visit(Folder folder) {
|
||||
return build().visit(folder);
|
||||
}
|
||||
|
||||
public FileSystemVisitor visit(File file) {
|
||||
public FolderVisitor visit(File file) {
|
||||
return build().visit(file);
|
||||
}
|
||||
|
||||
public FileSystemVisitor build() {
|
||||
return new FileSystemVisitor(this);
|
||||
public FolderVisitor build() {
|
||||
return new FolderVisitor(this);
|
||||
}
|
||||
|
||||
private static <T> Consumer<T> noOp() {
|
||||
@@ -160,8 +160,8 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
assert target.parent().isPresent() : "Target can not be root, thus has a parent";
|
||||
|
||||
// prepare target:
|
||||
target.parent().get().create();
|
||||
target.delete();
|
||||
target.parent().get().create();
|
||||
|
||||
// perform the actual move:
|
||||
final File dirFile = forceGetPhysicalFile();
|
||||
@@ -186,7 +186,12 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
return;
|
||||
}
|
||||
Deleter.deleteContent(this);
|
||||
forceGetPhysicalFolder().delete();
|
||||
Folder physicalFolder = forceGetPhysicalFolder();
|
||||
physicalFolder.delete();
|
||||
Folder physicalFolderParent = physicalFolder.parent().get();
|
||||
if (physicalFolderParent.folders().count() == 0) {
|
||||
physicalFolderParent.delete();
|
||||
}
|
||||
forceGetPhysicalFile().delete();
|
||||
invalidateDirectoryIdsRecursively();
|
||||
}
|
||||
|
||||
@@ -8,14 +8,15 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.crypto;
|
||||
|
||||
import static org.cryptomator.filesystem.FileSystemVisitor.fileSystemVisitor;
|
||||
import static org.hamcrest.Matchers.both;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.cryptomator.crypto.engine.Cryptor;
|
||||
import org.cryptomator.crypto.engine.NoCryptor;
|
||||
@@ -37,7 +38,6 @@ public class CryptoFileSystemTest {
|
||||
final FileSystem physicalFs = new InMemoryFileSystem();
|
||||
final Folder physicalDataRoot = physicalFs.folder("d");
|
||||
final FileSystem fs = new CryptoFileSystem(physicalFs, cryptor, Mockito.mock(CryptoFileSystemDelegate.class), "foo");
|
||||
fs.create();
|
||||
|
||||
// add another encrypted folder:
|
||||
final Folder fooFolder = fs.folder("foo");
|
||||
@@ -47,8 +47,24 @@ public class CryptoFileSystemTest {
|
||||
fooBarFolder.create();
|
||||
Assert.assertTrue(fooFolder.exists());
|
||||
Assert.assertTrue(fooBarFolder.exists());
|
||||
Assert.assertEquals(3, countDataFolders(physicalDataRoot)); // parent +
|
||||
// foo + bar
|
||||
Assert.assertEquals(3, countDataFolders(physicalDataRoot)); // parent + foo + bar
|
||||
}
|
||||
|
||||
@Test(timeout = 1000)
|
||||
public void testDirectoryDeletion() throws UncheckedIOException, IOException {
|
||||
// mock stuff and prepare crypto FS:
|
||||
final Cryptor cryptor = new NoCryptor();
|
||||
final FileSystem physicalFs = new InMemoryFileSystem();
|
||||
final Folder physicalDataRoot = physicalFs.folder("d");
|
||||
final FileSystem fs = new CryptoFileSystem(physicalFs, cryptor, Mockito.mock(CryptoFileSystemDelegate.class), "foo");
|
||||
|
||||
// create and delete folders:
|
||||
fs.folder("foo").folder("bar").folder("baz").create();
|
||||
Assert.assertEquals(4, countDataFolders(physicalDataRoot)); // root + foo + bar + baz
|
||||
Assert.assertThat(physicalDataRoot.folders().count(), both(greaterThanOrEqualTo(1l)).and(lessThanOrEqualTo(4l))); // parent folders of the 4 folders
|
||||
fs.folder("foo").delete();
|
||||
Assert.assertEquals(1, countDataFolders(physicalDataRoot)); // just root
|
||||
Assert.assertEquals(1, physicalDataRoot.folders().count()); // just the parent of root
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
@@ -204,22 +220,10 @@ public class CryptoFileSystemTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of folders on second level inside the given dataRoot
|
||||
* folder.
|
||||
* @return number of folders on second level inside the given dataRoot folder.
|
||||
*/
|
||||
private static int countDataFolders(Folder dataRoot) {
|
||||
final AtomicInteger num = new AtomicInteger();
|
||||
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();
|
||||
return (int) dataRoot.folders().flatMap(Folder::folders).count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user