mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-18 02:31:27 +00:00
fixed webdav copy/move [ci skip]
This commit is contained in:
@@ -7,7 +7,6 @@ package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@@ -151,17 +150,4 @@ public interface Folder extends Node {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the creation time of the folder.
|
||||
* <p>
|
||||
* Setting the creation time may not be supported by all {@link FileSystem FileSystems}. If the {@code FileSystem} this {@code Folder} belongs to does not support the
|
||||
* setting the creation time the behavior of this method is unspecified.
|
||||
*
|
||||
* @param instant the time to set as creation time
|
||||
*/
|
||||
default void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
throw new UncheckedIOException(new IOException("CreationTime not supported"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
@@ -45,6 +46,19 @@ public interface Node {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the creation time of this node.
|
||||
* <p>
|
||||
* Setting the creation time may not be supported by all {@link FileSystem FileSystems}. If the {@code FileSystem} this {@code Node} belongs to does not support the
|
||||
* setting the creation time the behavior of this method is unspecified.
|
||||
*
|
||||
* @param instant the time to set as creation time
|
||||
*/
|
||||
default void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
throw new UncheckedIOException(new IOException("CreationTime not supported"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link FileSystem} this Node belongs to
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
@@ -69,4 +70,14 @@ public abstract class DelegatingFile<D extends DelegatingFolder<D, ?>> extends D
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
return delegate.creationTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
delegate.setCreationTime(instant);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -97,6 +97,11 @@ public abstract class DelegatingFolder<D extends DelegatingFolder<D, F>, F exten
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
return delegate.creationTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
delegate.setCreationTime(instant);
|
||||
|
||||
@@ -143,6 +143,11 @@ class BlockAlignedWritableFile implements WritableFile {
|
||||
delegate.get().setLastModified(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
delegate.get().setCreationTime(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() throws UncheckedIOException {
|
||||
delegate.get().delete();
|
||||
|
||||
@@ -12,7 +12,6 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.crypto.engine.Cryptor;
|
||||
import org.cryptomator.filesystem.File;
|
||||
@@ -57,9 +56,4 @@ public class CryptoFile extends CryptoNode implements File {
|
||||
return toString().compareTo(o.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
return physicalFile().creationTime();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,10 +13,9 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.io.Writer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
@@ -30,7 +29,6 @@ import org.cryptomator.filesystem.Deleter;
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
import org.cryptomator.filesystem.Node;
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
|
||||
class CryptoFolder extends CryptoNode implements Folder {
|
||||
|
||||
@@ -131,14 +129,16 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
@Override
|
||||
public void create() {
|
||||
final File dirFile = physicalFile();
|
||||
if (dirFile.exists()) {
|
||||
final Folder dir = physicalFolder();
|
||||
if (dirFile.exists() && dir.exists()) {
|
||||
return;
|
||||
}
|
||||
parent.create();
|
||||
final String directoryId = getDirectoryId();
|
||||
try (WritableFile writable = dirFile.openWritable()) {
|
||||
final ByteBuffer buf = ByteBuffer.wrap(directoryId.getBytes());
|
||||
writable.write(buf);
|
||||
try (Writer writer = Channels.newWriter(dirFile.openWritable(), UTF_8.newEncoder(), -1)) {
|
||||
writer.write(directoryId);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
physicalFolder().create();
|
||||
}
|
||||
@@ -157,13 +157,15 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
throw new IllegalArgumentException("Can not move directories containing one another (src: " + this + ", dst: " + target + ")");
|
||||
}
|
||||
|
||||
// directoryId will be used by target, from now on we must no longer use the same id
|
||||
// a new one will be generated on-demand.
|
||||
final String oldDirectoryId = getDirectoryId();
|
||||
directoryId.set(null);
|
||||
|
||||
target.physicalFile().parent().get().create();
|
||||
this.physicalFile().moveTo(target.physicalFile());
|
||||
|
||||
// directoryId is now used by target, we must no longer use the same id
|
||||
// (we'll generate a new one when needed)
|
||||
target.directoryId.set(getDirectoryId());
|
||||
directoryId.set(null);
|
||||
target.directoryId.set(oldDirectoryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,13 +174,9 @@ class CryptoFolder extends CryptoNode implements Folder {
|
||||
return;
|
||||
}
|
||||
Deleter.deleteContent(this);
|
||||
physicalFile().delete();
|
||||
physicalFolder().delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
return physicalFile().creationTime();
|
||||
physicalFile().delete();
|
||||
directoryId.set(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.crypto;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.crypto.engine.Cryptor;
|
||||
@@ -55,7 +57,16 @@ abstract class CryptoNode implements Node {
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return physicalFile().exists();
|
||||
// return parent.children().anyMatch(node -> node.equals(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
return physicalFile().creationTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
physicalFile().setCreationTime(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -86,6 +86,11 @@ class CryptoWritableFile implements WritableFile {
|
||||
file.setLastModified(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
file.setCreationTime(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
writeTask.cancel(true);
|
||||
@@ -99,11 +104,6 @@ class CryptoWritableFile implements WritableFile {
|
||||
initialize(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
file.setCreationTime(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return file.isOpen();
|
||||
|
||||
@@ -71,10 +71,6 @@ class InMemoryFile extends InMemoryNode implements File {
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
private void setCreationTime(Instant creationTime) {
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
private ByteBuffer getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@@ -10,15 +10,15 @@ package org.cryptomator.filesystem.inmem;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.time.Instant;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.io.FileExistsException;
|
||||
import org.cryptomator.common.WeakValuedCache;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
|
||||
@@ -38,7 +38,7 @@ class InMemoryFolder extends InMemoryNode implements Folder {
|
||||
if (exists()) {
|
||||
return existingChildren.values().stream();
|
||||
} else {
|
||||
throw new UncheckedIOException(new IOException(format("Folder %s does not exist", this)));
|
||||
throw new UncheckedIOException(new FileNotFoundException(format("Folder %s does not exist", this)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class InMemoryFolder extends InMemoryNode implements Folder {
|
||||
parent.existingChildren.compute(name, (k, v) -> {
|
||||
if (v != null) {
|
||||
// other file or folder with same name already exists.
|
||||
throw new UncheckedIOException(new FileExistsException(k));
|
||||
throw new UncheckedIOException(new FileAlreadyExistsException(k));
|
||||
} else {
|
||||
this.lastModified = Instant.now();
|
||||
return this;
|
||||
@@ -113,11 +113,6 @@ class InMemoryFolder extends InMemoryNode implements Folder {
|
||||
assert!this.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
creationTime = instant;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return parent.toString() + name + "/";
|
||||
|
||||
@@ -83,4 +83,9 @@ class InMemoryNode implements Node {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant creationTime) throws UncheckedIOException {
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.cryptomator.filesystem.nio;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -59,4 +60,13 @@ abstract class NioNode implements Node {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant creationTime) throws UncheckedIOException {
|
||||
try {
|
||||
nioAccess.setCreationTime(path, FileTime.from(creationTime));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -147,15 +147,20 @@ class DavFolder extends DavNode<FolderLocator> {
|
||||
|
||||
@Override
|
||||
public void copy(DavResource destination, boolean shallow) throws DavException {
|
||||
if (destination instanceof DavFolder) {
|
||||
DavFolder dst = (DavFolder) destination;
|
||||
if (dst.node.exists()) {
|
||||
dst.node.delete();
|
||||
} else if (!dst.node.parent().get().exists()) {
|
||||
if (!node.exists()) {
|
||||
throw new DavException(DavServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
if (destination instanceof DavNode) {
|
||||
DavNode<?> dst = (DavNode<?>) destination;
|
||||
if (!dst.node.parent().get().exists()) {
|
||||
throw new DavException(DavServletResponse.SC_CONFLICT, "Destination's parent doesn't exist.");
|
||||
}
|
||||
dst.node.create();
|
||||
}
|
||||
if (destination instanceof DavFolder) {
|
||||
DavFolder dst = (DavFolder) destination;
|
||||
if (shallow) {
|
||||
// create destination, if it doesn't exist yet:
|
||||
dst.node.create();
|
||||
// http://www.webdav.org/specs/rfc2518.html#copy.for.collections
|
||||
node.creationTime().ifPresent(dst::setCreationTime);
|
||||
dst.setModificationTime(node.lastModified());
|
||||
@@ -168,8 +173,6 @@ class DavFolder extends DavNode<FolderLocator> {
|
||||
Folder newDst = parent.folder(dst.node.name());
|
||||
if (dst.node.exists()) {
|
||||
dst.node.delete();
|
||||
} else if (!parent.exists()) {
|
||||
throw new DavException(DavServletResponse.SC_CONFLICT, "Destination's parent doesn't exist.");
|
||||
}
|
||||
node.copyTo(newDst);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user