From 5ff4f4c9c7d83fdd714be0a95fe946251a071895 Mon Sep 17 00:00:00 2001 From: Markus Kreusch Date: Sat, 9 Jan 2016 19:12:20 +0100 Subject: [PATCH] Changed handling of creation time * creationTime now creates an Optional * Removed FileSystem#supports and FileSystemFeature --- .../cryptomator/filesystem/FileSystem.java | 4 - .../filesystem/FileSystemFeature.java | 5 - .../org/cryptomator/filesystem/Folder.java | 3 +- .../java/org/cryptomator/filesystem/Node.java | 11 +- .../cryptomator/filesystem/WritableFile.java | 3 +- .../filesystem/delegating/DelegatingNode.java | 3 +- .../blockaligned/BlockAlignedFileSystem.java | 6 - .../filesystem/crypto/CryptoFile.java | 3 +- .../filesystem/crypto/CryptoFileSystem.java | 6 - .../filesystem/crypto/CryptoFolder.java | 3 +- .../filesystem/inmem/InMemoryFileSystem.java | 6 - .../filesystem/inmem/InMemoryNode.java | 4 +- .../filesystem/inmem/InMemoryFileTest.java | 6 +- .../blacklisting/BlacklistingFileSystem.java | 6 - .../shortening/ShorteningFileSystem.java | 6 - .../filesystem/nio/DefaultNioAccess.java | 16 --- .../cryptomator/filesystem/nio/NioAccess.java | 2 - .../cryptomator/filesystem/nio/NioFile.java | 2 +- .../filesystem/nio/NioFileSystem.java | 18 --- .../cryptomator/filesystem/nio/NioFolder.java | 2 +- .../cryptomator/filesystem/nio/NioNode.java | 11 +- .../filesystem/nio/DefaultNioAccessTest.java | 130 ------------------ .../filesystem/nio/NioFileSystemTest.java | 26 ---- .../filesystem/nio/NioFileTest.java | 2 +- .../filesystem/nio/NioFolderTest.java | 4 +- .../webdav/jackrabbitservlet/DavFile.java | 7 +- .../webdav/jackrabbitservlet/DavFolder.java | 5 +- .../webdav/jackrabbitservlet/DavNode.java | 22 ++- 28 files changed, 44 insertions(+), 278 deletions(-) delete mode 100644 main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystemFeature.java diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystem.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystem.java index b96ed1b9f..563b1f068 100644 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystem.java +++ b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystem.java @@ -23,8 +23,4 @@ public interface FileSystem extends Folder { return Optional.empty(); } - default boolean supports(FileSystemFeature feature) { - return false; - } - } diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystemFeature.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystemFeature.java deleted file mode 100644 index af683d6c6..000000000 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/FileSystemFeature.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.cryptomator.filesystem; - -public enum FileSystemFeature { - CREATION_TIME_FEATURE -} diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/Folder.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/Folder.java index 8d11d5a17..e2eae5e73 100644 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/Folder.java +++ b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/Folder.java @@ -154,10 +154,9 @@ public interface Folder extends Node { * Sets the creation time of the folder. *

* 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 - * {@link FileSystemFeature#CREATION_TIME_FEATURE} the behavior of this method is unspecified. + * setting the creation time the behavior of this method is unspecified. * * @param instant the time to set as creation time - * @see FileSystem#supports(Class) */ default void setCreationTime(Instant instant) throws UncheckedIOException { throw new UncheckedIOException(new IOException("CreationTime not supported")); diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/Node.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/Node.java index 841eba8b2..5d5ee3890 100644 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/Node.java +++ b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/Node.java @@ -5,7 +5,6 @@ ******************************************************************************/ package org.cryptomator.filesystem; -import java.io.IOException; import java.io.UncheckedIOException; import java.time.Instant; import java.util.Optional; @@ -38,14 +37,12 @@ public interface Node { *

* Determines the creation time of this node. *

- * 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 - * {@link FileSystemFeature#CREATION_TIME_FEATURE} the behavior of this method is unspecified. + * Note: Getting the creation time may not be supported by all {@link FileSystem FileSystems}. * - * @returns the creation time of the file. - * @see FileSystem#supports(Class) + * @returns the creation time of the file or {@link Optional#empty()} if not supported */ - default Instant creationTime() throws UncheckedIOException { - throw new UncheckedIOException(new IOException("CreationTime not supported")); + default Optional creationTime() throws UncheckedIOException { + return Optional.empty(); } /** diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/WritableFile.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/WritableFile.java index e14e6987f..b22ae96ea 100644 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/WritableFile.java +++ b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/WritableFile.java @@ -29,10 +29,9 @@ public interface WritableFile extends WritableByteChannel { * Sets the creation time of the file. *

* Setting the creation time may not be supported by all {@link FileSystem FileSystems}. If the {@code FileSystem} this {@code WritableFile} belongs to does not support the - * {@link FileSystemFeature#CREATION_TIME_FEATURE} the behavior of this method is unspecified. + * setting the creation time the behavior of this method is unspecified. * * @param instant the time to set as creation time - * @see FileSystem#supports(Class) */ default void setCreationTime(Instant instant) throws UncheckedIOException { throw new UncheckedIOException(new IOException("CreationTime not supported")); diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingNode.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingNode.java index bd046e176..153c0cd83 100644 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingNode.java +++ b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingNode.java @@ -10,6 +10,7 @@ package org.cryptomator.filesystem.delegating; import java.io.UncheckedIOException; import java.time.Instant; +import java.util.Optional; import org.cryptomator.filesystem.Node; @@ -40,7 +41,7 @@ abstract class DelegatingNode implements Node { } @Override - public Instant creationTime() throws UncheckedIOException { + public Optional creationTime() throws UncheckedIOException { return delegate.creationTime(); } diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFileSystem.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFileSystem.java index 636c3e216..9d182b3bb 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFileSystem.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFileSystem.java @@ -9,7 +9,6 @@ package org.cryptomator.filesystem.blockaligned; import org.cryptomator.filesystem.FileSystem; -import org.cryptomator.filesystem.FileSystemFeature; import org.cryptomator.filesystem.Folder; class BlockAlignedFileSystem extends BlockAlignedFolder implements FileSystem { @@ -18,9 +17,4 @@ class BlockAlignedFileSystem extends BlockAlignedFolder implements FileSystem { super(null, delegate, blockSize); } - @Override - public boolean supports(FileSystemFeature feature) { - return delegate.fileSystem().supports(feature); - } - } 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 8c3402418..ee8f8332e 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,6 +10,7 @@ package org.cryptomator.filesystem.crypto; import java.io.UncheckedIOException; import java.time.Instant; +import java.util.Optional; import org.cryptomator.crypto.engine.Cryptor; import org.cryptomator.filesystem.File; @@ -55,7 +56,7 @@ public class CryptoFile extends CryptoNode implements File { } @Override - public Instant creationTime() throws UncheckedIOException { + public Optional creationTime() throws UncheckedIOException { return physicalFile().creationTime(); } diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystem.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystem.java index 9266ca665..d1a69a809 100644 --- a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystem.java +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/crypto/CryptoFileSystem.java @@ -15,7 +15,6 @@ import org.cryptomator.crypto.engine.Cryptor; import org.cryptomator.crypto.engine.InvalidPassphraseException; import org.cryptomator.filesystem.File; import org.cryptomator.filesystem.FileSystem; -import org.cryptomator.filesystem.FileSystemFeature; import org.cryptomator.filesystem.Folder; import org.cryptomator.filesystem.ReadableFile; import org.cryptomator.filesystem.WritableFile; @@ -105,11 +104,6 @@ public class CryptoFileSystem extends CryptoFolder implements FileSystem { physicalFolder().create(); } - @Override - public boolean supports(FileSystemFeature feature) { - return physicalRoot.fileSystem().supports(feature); - } - @Override public String toString() { return physicalRoot + ":::/"; 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 bd9902e77..c29a1217c 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 @@ -15,6 +15,7 @@ import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.charset.StandardCharsets; import java.time.Instant; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Stream; @@ -147,7 +148,7 @@ class CryptoFolder extends CryptoNode implements Folder { } @Override - public Instant creationTime() throws UncheckedIOException { + public Optional creationTime() throws UncheckedIOException { return physicalFile().creationTime(); } diff --git a/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFileSystem.java b/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFileSystem.java index 8b4fc35c7..98b285ebb 100644 --- a/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFileSystem.java +++ b/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryFileSystem.java @@ -12,7 +12,6 @@ import java.time.Instant; import java.util.Optional; import org.cryptomator.filesystem.FileSystem; -import org.cryptomator.filesystem.FileSystemFeature; public class InMemoryFileSystem extends InMemoryFolder implements FileSystem { @@ -40,9 +39,4 @@ public class InMemoryFileSystem extends InMemoryFolder implements FileSystem { return "/"; } - @Override - public boolean supports(FileSystemFeature feature) { - return feature == FileSystemFeature.CREATION_TIME_FEATURE; - } - } diff --git a/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryNode.java b/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryNode.java index ea106b472..71b799c25 100644 --- a/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryNode.java +++ b/main/filesystem-inmemory/src/main/java/org/cryptomator/filesystem/inmem/InMemoryNode.java @@ -71,9 +71,9 @@ class InMemoryNode implements Node { } @Override - public Instant creationTime() throws UncheckedIOException { + public Optional creationTime() throws UncheckedIOException { if (exists()) { - return creationTime; + return Optional.of(creationTime); } else { throw new UncheckedIOException(new IOException("Node does not exist")); } diff --git a/main/filesystem-inmemory/src/test/java/org/cryptomator/filesystem/inmem/InMemoryFileTest.java b/main/filesystem-inmemory/src/test/java/org/cryptomator/filesystem/inmem/InMemoryFileTest.java index 8f19f811a..2304a32ee 100644 --- a/main/filesystem-inmemory/src/test/java/org/cryptomator/filesystem/inmem/InMemoryFileTest.java +++ b/main/filesystem-inmemory/src/test/java/org/cryptomator/filesystem/inmem/InMemoryFileTest.java @@ -37,8 +37,8 @@ public class InMemoryFileTest { maxCreationTime = Instant.now(); } - assertThat(inTest.creationTime().isBefore(minCreationTime), is(false)); - assertThat(inTest.creationTime().isAfter(maxCreationTime), is(false)); + assertThat(inTest.creationTime().get().isBefore(minCreationTime), is(false)); + assertThat(inTest.creationTime().get().isAfter(maxCreationTime), is(false)); } @Test @@ -50,7 +50,7 @@ public class InMemoryFileTest { writable.setCreationTime(creationTime); } - assertThat(inTest.creationTime(), is(creationTime)); + assertThat(inTest.creationTime().get(), is(creationTime)); } } diff --git a/main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/blacklisting/BlacklistingFileSystem.java b/main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/blacklisting/BlacklistingFileSystem.java index 74bf3ca54..23786805a 100644 --- a/main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/blacklisting/BlacklistingFileSystem.java +++ b/main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/blacklisting/BlacklistingFileSystem.java @@ -3,7 +3,6 @@ package org.cryptomator.filesystem.blacklisting; import java.util.function.Predicate; import org.cryptomator.filesystem.FileSystem; -import org.cryptomator.filesystem.FileSystemFeature; import org.cryptomator.filesystem.Folder; import org.cryptomator.filesystem.Node; @@ -13,9 +12,4 @@ class BlacklistingFileSystem extends BlacklistingFolder implements FileSystem { super(null, root, hiddenNodes); } - @Override - public boolean supports(FileSystemFeature feature) { - return delegate.fileSystem().supports(feature); - } - } diff --git a/main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/shortening/ShorteningFileSystem.java b/main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/shortening/ShorteningFileSystem.java index 379aced28..0a5f8f1b3 100644 --- a/main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/shortening/ShorteningFileSystem.java +++ b/main/filesystem-nameshortening/src/main/java/org/cryptomator/filesystem/shortening/ShorteningFileSystem.java @@ -1,7 +1,6 @@ package org.cryptomator.filesystem.shortening; import org.cryptomator.filesystem.FileSystem; -import org.cryptomator.filesystem.FileSystemFeature; import org.cryptomator.filesystem.Folder; class ShorteningFileSystem extends ShorteningFolder implements FileSystem { @@ -10,9 +9,4 @@ class ShorteningFileSystem extends ShorteningFolder implements FileSystem { super(null, root, "", new FilenameShortener(metadataRoot, threshold)); } - @Override - public boolean supports(FileSystemFeature feature) { - return delegate.fileSystem().supports(feature); - } - } diff --git a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/DefaultNioAccess.java b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/DefaultNioAccess.java index b57b07ece..49707a35e 100644 --- a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/DefaultNioAccess.java +++ b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/DefaultNioAccess.java @@ -91,20 +91,4 @@ class DefaultNioAccess implements NioAccess { Files.getFileAttributeView(path, BasicFileAttributeView.class, options).setTimes(null, null, creationTime); } - @Override - public boolean supportsCreationTime(Path path) { - try { - Path file = Files.createTempFile(path, "creationTimeCheck", "tmp"); - long expected = 1184725140000L; - long millisecondsInADay = 86400000L; - FileTime fileTime = FileTime.fromMillis(expected); - Files.getFileAttributeView(file, BasicFileAttributeView.class).setTimes(null, null, fileTime); - long actual = Files.readAttributes(file, BasicFileAttributes.class).creationTime().toMillis(); - return Math.abs(expected - actual) <= millisecondsInADay; - } catch (IOException e) { - LOG.info("supportsCreationTime failed", e); - return false; - } - } - } diff --git a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioAccess.java b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioAccess.java index 1d98513e5..48a61973d 100644 --- a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioAccess.java +++ b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioAccess.java @@ -44,6 +44,4 @@ interface NioAccess { void setCreationTime(Path path, FileTime creationTime, LinkOption... options) throws IOException; - boolean supportsCreationTime(Path path); - } diff --git a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFile.java b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFile.java index 1d7fa0927..fa418c186 100644 --- a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFile.java +++ b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFile.java @@ -83,7 +83,7 @@ class NioFile extends NioNode implements File { } @Override - public Instant creationTime() throws UncheckedIOException { + public Optional creationTime() throws UncheckedIOException { if (nioAccess.exists(path) && !exists()) { throw new UncheckedIOException(new IOException(format("%s is a folder", path))); } diff --git a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFileSystem.java b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFileSystem.java index c2566abd0..827c75ec5 100644 --- a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFileSystem.java +++ b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFileSystem.java @@ -2,16 +2,11 @@ package org.cryptomator.filesystem.nio; import java.nio.file.Path; import java.util.Optional; -import java.util.function.Supplier; -import org.cryptomator.common.CachingSupplier; import org.cryptomator.filesystem.FileSystem; -import org.cryptomator.filesystem.FileSystemFeature; public class NioFileSystem extends NioFolder implements FileSystem { - private final Supplier supportsCreationTime = CachingSupplier.from(this::supportsCreationTime); - public static NioFileSystem rootedAt(Path root) { return new NioFileSystem(root); } @@ -21,17 +16,4 @@ public class NioFileSystem extends NioFolder implements FileSystem { create(); } - @Override - public boolean supports(FileSystemFeature feature) { - if (feature == FileSystemFeature.CREATION_TIME_FEATURE) { - return supportsCreationTime.get(); - } else { - return false; - } - } - - private boolean supportsCreationTime() { - return nioAccess.supportsCreationTime(path); - } - } diff --git a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFolder.java b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFolder.java index 74587e235..9a8c58c4f 100644 --- a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFolder.java +++ b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioFolder.java @@ -112,7 +112,7 @@ class NioFolder extends NioNode implements Folder { } @Override - public Instant creationTime() throws UncheckedIOException { + public Optional creationTime() throws UncheckedIOException { if (nioAccess.exists(path) && !nioAccess.isDirectory(path)) { throw new UncheckedIOException(new IOException(format("%s is a file", path))); } diff --git a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioNode.java b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioNode.java index ae6d2fedd..db3d32494 100644 --- a/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioNode.java +++ b/main/filesystem-nio/src/main/java/org/cryptomator/filesystem/nio/NioNode.java @@ -43,10 +43,17 @@ abstract class NioNode implements Node { } } + private static final Instant JANNUARY_THE_SECOND_NINTEENHUNDRED_SEVENTY = Instant.parse("1970-01-02T00:00:00Z"); + @Override - public Instant creationTime() throws UncheckedIOException { + public Optional creationTime() throws UncheckedIOException { try { - return nioAccess.getCreationTime(path).toInstant(); + Instant instant = nioAccess.getCreationTime(path).toInstant(); + if (instant.isBefore(JANNUARY_THE_SECOND_NINTEENHUNDRED_SEVENTY)) { + return Optional.empty(); + } else { + return Optional.of(instant); + } } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/DefaultNioAccessTest.java b/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/DefaultNioAccessTest.java index 0f50c012c..4e98349d2 100644 --- a/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/DefaultNioAccessTest.java +++ b/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/DefaultNioAccessTest.java @@ -16,7 +16,6 @@ import static org.mockito.Mockito.when; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.channels.FileChannel; -import java.nio.channels.SeekableByteChannel; import java.nio.file.CopyOption; import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; @@ -36,7 +35,6 @@ import java.util.HashSet; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Matchers; import de.bechte.junit.runners.context.HierarchicalContextRunner; @@ -217,134 +215,6 @@ public class DefaultNioAccessTest { verify(attributes).setTimes(null, null, fileTime); } - public class SupportsCreationTimeTests { - - @Test - public void testSupportsCreationTimeReturnsTrueIfGetCreationTimeIsADayOfFromSetCreationTime() throws IOException { - long expectedMillisSet = 1184725140000L; - long millisecondsInADay = 86400000L; - Path tempFileName = mock(Path.class); - Path tempFile = mock(Path.class); - when(tempFile.getFileSystem()).thenReturn(fileSystem); - when(fileSystem.getPath(Matchers.any())).thenReturn(tempFileName); - when(path.resolve(tempFileName)).thenReturn(tempFile); - when(provider.newByteChannel(any(), any())).thenReturn(mock(SeekableByteChannel.class)); - BasicFileAttributeView attributesView = mock(BasicFileAttributeView.class); - BasicFileAttributes attributes = mock(BasicFileAttributes.class); - when(provider.getFileAttributeView(tempFile, BasicFileAttributeView.class)).thenReturn(attributesView); - when(provider.readAttributes(tempFile, BasicFileAttributes.class)).thenReturn(attributes); - when(attributes.creationTime()).thenReturn(FileTime.fromMillis(expectedMillisSet + millisecondsInADay)); - - boolean result = inTest.supportsCreationTime(path); - - assertThat(result, is(true)); - verify(attributesView).setTimes(null, null, FileTime.fromMillis(expectedMillisSet)); - } - - @Test - public void testSupportsCreationTimeReturnsTrueIfGetCreationTimeIsADayOfBeforeSetCreationTime() throws IOException { - long expectedMillisSet = 1184725140000L; - long millisecondsInADay = 86400000L; - Path tempFileName = mock(Path.class); - Path tempFile = mock(Path.class); - when(tempFile.getFileSystem()).thenReturn(fileSystem); - when(fileSystem.getPath(Matchers.any())).thenReturn(tempFileName); - when(path.resolve(tempFileName)).thenReturn(tempFile); - when(provider.newByteChannel(any(), any())).thenReturn(mock(SeekableByteChannel.class)); - BasicFileAttributeView attributesView = mock(BasicFileAttributeView.class); - BasicFileAttributes attributes = mock(BasicFileAttributes.class); - when(provider.getFileAttributeView(tempFile, BasicFileAttributeView.class)).thenReturn(attributesView); - when(provider.readAttributes(tempFile, BasicFileAttributes.class)).thenReturn(attributes); - when(attributes.creationTime()).thenReturn(FileTime.fromMillis(expectedMillisSet - millisecondsInADay)); - - boolean result = inTest.supportsCreationTime(path); - - assertThat(result, is(true)); - verify(attributesView).setTimes(null, null, FileTime.fromMillis(expectedMillisSet)); - } - - @Test - public void testSupportsCreationTimeSucceedsIfGetCreationTimeIsADayOfBeforeSetCreationTime() throws IOException { - long expectedMillisSet = 1184725140000L; - long millisecondsInADay = 86400000L; - Path tempFileName = mock(Path.class); - Path tempFile = mock(Path.class); - when(tempFile.getFileSystem()).thenReturn(fileSystem); - when(fileSystem.getPath(Matchers.any())).thenReturn(tempFileName); - when(path.resolve(tempFileName)).thenReturn(tempFile); - when(provider.newByteChannel(any(), any())).thenReturn(mock(SeekableByteChannel.class)); - BasicFileAttributeView attributesView = mock(BasicFileAttributeView.class); - BasicFileAttributes attributes = mock(BasicFileAttributes.class); - when(provider.getFileAttributeView(tempFile, BasicFileAttributeView.class)).thenReturn(attributesView); - when(provider.readAttributes(tempFile, BasicFileAttributes.class)).thenReturn(attributes); - when(attributes.creationTime()).thenReturn(FileTime.fromMillis(expectedMillisSet - millisecondsInADay)); - - boolean result = inTest.supportsCreationTime(path); - - assertThat(result, is(true)); - verify(attributesView).setTimes(null, null, FileTime.fromMillis(expectedMillisSet)); - } - - @Test - public void testSupportsCreationTimeReturnsFalseIfGetCreationTimeIsMoreAsADayOfFromSetCreationTime() throws IOException { - long expectedMillisSet = 1184725140000L; - long millisecondsInADay = 86400000L; - Path tempFileName = mock(Path.class); - Path tempFile = mock(Path.class); - when(tempFile.getFileSystem()).thenReturn(fileSystem); - when(fileSystem.getPath(Matchers.any())).thenReturn(tempFileName); - when(path.resolve(tempFileName)).thenReturn(tempFile); - when(provider.newByteChannel(any(), any())).thenReturn(mock(SeekableByteChannel.class)); - BasicFileAttributeView attributesView = mock(BasicFileAttributeView.class); - BasicFileAttributes attributes = mock(BasicFileAttributes.class); - when(provider.getFileAttributeView(tempFile, BasicFileAttributeView.class)).thenReturn(attributesView); - when(provider.readAttributes(tempFile, BasicFileAttributes.class)).thenReturn(attributes); - when(attributes.creationTime()).thenReturn(FileTime.fromMillis(expectedMillisSet + millisecondsInADay + 1)); - - boolean result = inTest.supportsCreationTime(path); - - assertThat(result, is(false)); - verify(attributesView).setTimes(null, null, FileTime.fromMillis(expectedMillisSet)); - } - - @Test - public void testSupportsCreationTimeReturnsFalseIfGetCreationTimeIsMoreAsADayBeforeSetCreationTime() throws IOException { - long expectedMillisSet = 1184725140000L; - long millisecondsInADay = 86400000L; - Path tempFileName = mock(Path.class); - Path tempFile = mock(Path.class); - when(tempFile.getFileSystem()).thenReturn(fileSystem); - when(fileSystem.getPath(Matchers.any())).thenReturn(tempFileName); - when(path.resolve(tempFileName)).thenReturn(tempFile); - when(provider.newByteChannel(any(), any())).thenReturn(mock(SeekableByteChannel.class)); - BasicFileAttributeView attributesView = mock(BasicFileAttributeView.class); - BasicFileAttributes attributes = mock(BasicFileAttributes.class); - when(provider.getFileAttributeView(tempFile, BasicFileAttributeView.class)).thenReturn(attributesView); - when(provider.readAttributes(tempFile, BasicFileAttributes.class)).thenReturn(attributes); - when(attributes.creationTime()).thenReturn(FileTime.fromMillis(expectedMillisSet - millisecondsInADay - 1)); - - boolean result = inTest.supportsCreationTime(path); - - assertThat(result, is(false)); - verify(attributesView).setTimes(null, null, FileTime.fromMillis(expectedMillisSet)); - } - - @Test - public void testSupportsCreationTimeReturnsFalseIfIOExceptionOccurs() throws IOException { - Path tempFileName = mock(Path.class); - Path tempFile = mock(Path.class); - when(tempFile.getFileSystem()).thenReturn(fileSystem); - when(fileSystem.getPath(Matchers.any())).thenReturn(tempFileName); - when(path.resolve(tempFileName)).thenReturn(tempFile); - when(provider.newByteChannel(any(), any())).thenThrow(new IOException()); - - boolean result = inTest.supportsCreationTime(path); - - assertThat(result, is(false)); - } - - } - @Test public void testSeparatorReturnsSeparatorOfDefaultFileSystem() { assertThat(inTest.separator(), is(FileSystems.getDefault().getSeparator())); diff --git a/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFileSystemTest.java b/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFileSystemTest.java index 916797ba2..07ef1eb66 100644 --- a/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFileSystemTest.java +++ b/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFileSystemTest.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.nio.file.Path; import java.util.Optional; -import org.cryptomator.filesystem.FileSystemFeature; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -52,31 +51,6 @@ public class NioFileSystemTest { verify(nioAccess).createDirectories(path); } - @Test - public void testSupportsCreationTimeDelegatesToNioAccessWithTrue() { - when(nioAccess.supportsCreationTime(path)).thenReturn(true); - - boolean result = inTest.supports(FileSystemFeature.CREATION_TIME_FEATURE); - - assertThat(result, is(true)); - } - - @Test - public void testSupportsWithOtherFeatureReturnsFalse() { - boolean result = inTest.supports(null); - - assertThat(result, is(false)); - } - - @Test - public void testSupportsCreationTimeDelegatesToNioAccessWithFalse() { - when(nioAccess.supportsCreationTime(path)).thenReturn(false); - - boolean result = inTest.supports(FileSystemFeature.CREATION_TIME_FEATURE); - - assertThat(result, is(false)); - } - @After public void tearDown() { InstanceFactory.DEFAULT.reset(); diff --git a/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFileTest.java b/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFileTest.java index 3b0ee216c..cbe579275 100644 --- a/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFileTest.java +++ b/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFileTest.java @@ -304,7 +304,7 @@ public class NioFileTest { when(nioAccess.exists(path)).thenReturn(true); when(nioAccess.isRegularFile(path)).thenReturn(true); - Instant result = inTest.creationTime(); + Instant result = inTest.creationTime().get(); assertThat(result, is(exectedResult)); } diff --git a/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFolderTest.java b/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFolderTest.java index e4404dcee..068b29e34 100644 --- a/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFolderTest.java +++ b/main/filesystem-nio/src/test/java/org/cryptomator/filesystem/nio/NioFolderTest.java @@ -419,7 +419,7 @@ public class NioFolderTest { when(nioAccess.exists(path)).thenReturn(true); when(nioAccess.isDirectory(path)).thenReturn(true); - Instant result = inTest.creationTime(); + Instant result = inTest.creationTime().get(); assertThat(result, is(exectedResult)); } @@ -430,7 +430,7 @@ public class NioFolderTest { when(nioAccess.getCreationTime(path)).thenReturn(FileTime.from(exectedResult)); when(nioAccess.exists(path)).thenReturn(false); - Instant result = inTest.creationTime(); + Instant result = inTest.creationTime().get(); assertThat(result, is(exectedResult)); } diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavFile.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavFile.java index ebd693d61..1bff09d9d 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavFile.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavFile.java @@ -26,7 +26,6 @@ import org.apache.jackrabbit.webdav.property.DavProperty; import org.apache.jackrabbit.webdav.property.DavPropertyName; import org.apache.jackrabbit.webdav.property.DavPropertySet; import org.apache.jackrabbit.webdav.property.DefaultDavProperty; -import org.cryptomator.filesystem.FileSystemFeature; import org.cryptomator.filesystem.ReadableFile; import org.cryptomator.filesystem.WritableFile; import org.cryptomator.filesystem.jackrabbit.FileLocator; @@ -129,10 +128,8 @@ class DavFile extends DavNode { @Override protected void setCreationTime(Instant instant) { - if (node.fileSystem().supports(FileSystemFeature.CREATION_TIME_FEATURE)) { - try (WritableFile writable = node.openWritable()) { - writable.setCreationTime(instant); - } + try (WritableFile writable = node.openWritable()) { + writable.setCreationTime(instant); } } diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavFolder.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavFolder.java index 7d204613e..5d789ebdd 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavFolder.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavFolder.java @@ -31,7 +31,6 @@ import org.apache.jackrabbit.webdav.property.DavPropertyName; import org.apache.jackrabbit.webdav.property.DefaultDavProperty; import org.apache.jackrabbit.webdav.property.ResourceType; import org.cryptomator.filesystem.File; -import org.cryptomator.filesystem.FileSystemFeature; import org.cryptomator.filesystem.Folder; import org.cryptomator.filesystem.Node; import org.cryptomator.filesystem.WritableFile; @@ -156,9 +155,7 @@ class DavFolder extends DavNode { @Override protected void setCreationTime(Instant instant) { - if (node.fileSystem().supports(FileSystemFeature.CREATION_TIME_FEATURE)) { - node.setCreationTime(instant); - } + node.setCreationTime(instant); } } diff --git a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavNode.java b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavNode.java index 17bfaa0aa..e7891c2a2 100644 --- a/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavNode.java +++ b/main/jackrabbit-filesystem-adapter/src/main/java/org/cryptomator/webdav/jackrabbitservlet/DavNode.java @@ -16,6 +16,7 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.Temporal; import java.util.Arrays; import java.util.List; +import java.util.Optional; import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavResource; @@ -33,7 +34,6 @@ import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; import org.apache.jackrabbit.webdav.property.DavPropertySet; import org.apache.jackrabbit.webdav.property.DefaultDavProperty; import org.apache.jackrabbit.webdav.property.PropEntry; -import org.cryptomator.filesystem.FileSystemFeature; import org.cryptomator.filesystem.jackrabbit.FileSystemResourceLocator; abstract class DavNode implements DavResource { @@ -113,12 +113,7 @@ abstract class DavNode implements DavResour public DavProperty getProperty(DavPropertyName name) { final String namespacelessPropertyName = name.getName(); if (Arrays.asList(DAV_CREATIONDATE_PROPNAMES).contains(namespacelessPropertyName)) { - if (node.fileSystem().supports(FileSystemFeature.CREATION_TIME_FEATURE)) { - Temporal creationDate = OffsetDateTime.ofInstant(node.creationTime(), ZoneOffset.UTC); - return new DefaultDavProperty<>(name, DateTimeFormatter.RFC_1123_DATE_TIME.format(creationDate)); - } else { - return null; - } + return creationDateProperty(name).orElse(null); } else if (Arrays.asList(DAV_MODIFIEDDATE_PROPNAMES).contains(namespacelessPropertyName)) { Temporal lastModifiedDate = OffsetDateTime.ofInstant(node.lastModified(), ZoneOffset.UTC); return new DefaultDavProperty<>(name, DateTimeFormatter.RFC_1123_DATE_TIME.format(lastModifiedDate)); @@ -133,11 +128,8 @@ abstract class DavNode implements DavResour @Override public DavPropertySet getProperties() { // creation date: - if (node.exists() && node.fileSystem().supports(FileSystemFeature.CREATION_TIME_FEATURE)) { - Temporal creationDate = OffsetDateTime.ofInstant(node.creationTime(), ZoneOffset.UTC); - String createionDateStr = DateTimeFormatter.RFC_1123_DATE_TIME.format(creationDate); - DavProperty creationDateProp = new DefaultDavProperty<>(DavPropertyName.CREATIONDATE, createionDateStr); - properties.add(creationDateProp); + if (node.exists()) { + creationDateProperty(DavPropertyName.CREATIONDATE).ifPresent(properties::add); } // modification date: if (node.exists()) { @@ -150,6 +142,12 @@ abstract class DavNode implements DavResour return properties; } + private Optional> creationDateProperty(DavPropertyName name) { + return node.creationTime() // + .map(creationTime -> OffsetDateTime.ofInstant(creationTime, ZoneOffset.UTC)) // + .map(creationDate -> new DefaultDavProperty<>(name, DateTimeFormatter.RFC_1123_DATE_TIME.format(creationDate))); + } + @Override public void setProperty(DavProperty property) throws DavException { final String namespacelessPropertyName = property.getName().getName();