fixed webdav copy/move [ci skip]

This commit is contained in:
Sebastian Stenzel
2016-02-14 00:26:47 +01:00
parent f0cb91b22f
commit cf64a6c425
14 changed files with 97 additions and 64 deletions

View File

@@ -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"));
}
}

View File

@@ -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
*/

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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();

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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 + "/";

View File

@@ -83,4 +83,9 @@ class InMemoryNode implements Node {
}
}
@Override
public void setCreationTime(Instant creationTime) throws UncheckedIOException {
this.creationTime = creationTime;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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 {