diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFile.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFile.java index 9c512473b..47250e1e0 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFile.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFile.java @@ -10,10 +10,9 @@ package org.cryptomator.filesystem.crypto; import static java.nio.charset.StandardCharsets.UTF_8; -import java.util.Optional; import java.io.UncheckedIOException; import java.nio.file.FileAlreadyExistsException; -import java.time.Instant; +import java.util.Optional; import org.cryptomator.crypto.engine.Cryptor; import org.cryptomator.filesystem.File; diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java index 299aea7d6..edd494a91 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFolder.java @@ -11,12 +11,10 @@ package org.cryptomator.filesystem.crypto; import static java.nio.charset.StandardCharsets.UTF_8; import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.Reader; import java.io.UncheckedIOException; -import java.io.Writer; -import java.nio.channels.Channels; import java.nio.file.FileAlreadyExistsException; +import java.util.Collection; +import java.util.HashSet; import java.util.Optional; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; @@ -29,6 +27,7 @@ import org.cryptomator.common.WeakValuedCache; import org.cryptomator.crypto.engine.Cryptor; import org.cryptomator.filesystem.Deleter; import org.cryptomator.filesystem.File; +import org.cryptomator.filesystem.FileSystemVisitor; import org.cryptomator.filesystem.Folder; import org.cryptomator.filesystem.Node; import org.cryptomator.io.FileContents; @@ -164,11 +163,15 @@ 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(); - - // explicitly delete target, otherwise same-named folders may keep their directory ids target.delete(); + // determine subFolder as long as we can still browse our current hierarchy: + Collection subFolders = new HashSet<>(); + FileSystemVisitor.fileSystemVisitor().beforeFolder(subFolders::add).visit(this); + + // perform the actual move: final File dirFile = forceGetPhysicalFile(); final String dirId = getDirectoryId().get(); boolean dirIdMovedSuccessfully = target.directoryId.compareAndSet(null, dirId); @@ -176,17 +179,20 @@ class CryptoFolder extends CryptoNode implements Folder { throw new IllegalStateException("Target's directoryId wasn't null, even though it has been explicitly deleted."); } dirFile.moveTo(target.forceGetPhysicalFile()); - directoryId.set(null); + + // invalidate the directory id of any directory beneath the _old_ location: + subFolders.stream().filter(CryptoFolder.class::isInstance).map(CryptoFolder.class::cast).forEach(folder -> { + folder.directoryId.set(null); + }); assert!exists(); assert target.exists(); - assert!dirFile.exists(); } @Override public void delete() { if (!exists()) { - directoryId.set(null); + assert directoryId.get() == null : "nonexisting folder still has a directory id"; return; } Deleter.deleteContent(this); diff --git a/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFile.java b/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFile.java index ddf7d7ee2..f5ea36a9e 100644 --- a/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFile.java +++ b/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFile.java @@ -69,6 +69,7 @@ class InMemoryFile extends InMemoryNode implements File { throw new UncheckedIOException(new FileAlreadyExistsException(k)); } else { if (v == null) { + assert!content.hasRemaining(); this.creationTime = Instant.now(); } this.lastModified = Instant.now();