mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-22 20:51:27 +00:00
Changed handling of creation time
* creationTime now creates an Optional * Removed FileSystem#supports and FileSystemFeature
This commit is contained in:
@@ -23,8 +23,4 @@ public interface FileSystem extends Folder {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
default boolean supports(FileSystemFeature feature) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
public enum FileSystemFeature {
|
||||
CREATION_TIME_FEATURE
|
||||
}
|
||||
@@ -154,10 +154,9 @@ public interface Folder extends Node {
|
||||
* 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
|
||||
* {@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"));
|
||||
|
||||
@@ -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 {
|
||||
* <p>
|
||||
* Determines 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
|
||||
* {@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<Instant> creationTime() throws UncheckedIOException {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,10 +29,9 @@ public interface WritableFile extends WritableByteChannel {
|
||||
* Sets the creation time of the file.
|
||||
* <p>
|
||||
* 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"));
|
||||
|
||||
@@ -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<T extends Node> implements Node {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant creationTime() throws UncheckedIOException {
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
return delegate.creationTime();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<Instant> creationTime() throws UncheckedIOException {
|
||||
return physicalFile().creationTime();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 + ":::/";
|
||||
|
||||
@@ -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<Instant> creationTime() throws UncheckedIOException {
|
||||
return physicalFile().creationTime();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -71,9 +71,9 @@ class InMemoryNode implements Node {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant creationTime() throws UncheckedIOException {
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
if (exists()) {
|
||||
return creationTime;
|
||||
return Optional.of(creationTime);
|
||||
} else {
|
||||
throw new UncheckedIOException(new IOException("Node does not exist"));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,4 @@ interface NioAccess {
|
||||
|
||||
void setCreationTime(Path path, FileTime creationTime, LinkOption... options) throws IOException;
|
||||
|
||||
boolean supportsCreationTime(Path path);
|
||||
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ class NioFile extends NioNode implements File {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant creationTime() throws UncheckedIOException {
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
if (nioAccess.exists(path) && !exists()) {
|
||||
throw new UncheckedIOException(new IOException(format("%s is a folder", path)));
|
||||
}
|
||||
|
||||
@@ -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<Boolean> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ class NioFolder extends NioNode implements Folder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant creationTime() throws UncheckedIOException {
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
if (nioAccess.exists(path) && !nioAccess.isDirectory(path)) {
|
||||
throw new UncheckedIOException(new IOException(format("%s is a file", path)));
|
||||
}
|
||||
|
||||
@@ -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<Instant> 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);
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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<FileLocator> {
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<FolderLocator> {
|
||||
|
||||
@Override
|
||||
protected void setCreationTime(Instant instant) {
|
||||
if (node.fileSystem().supports(FileSystemFeature.CREATION_TIME_FEATURE)) {
|
||||
node.setCreationTime(instant);
|
||||
}
|
||||
node.setCreationTime(instant);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<T extends FileSystemResourceLocator> implements DavResource {
|
||||
@@ -113,12 +113,7 @@ abstract class DavNode<T extends FileSystemResourceLocator> 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<T extends FileSystemResourceLocator> 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<String> 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<T extends FileSystemResourceLocator> implements DavResour
|
||||
return properties;
|
||||
}
|
||||
|
||||
private Optional<DavProperty<?>> 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();
|
||||
|
||||
Reference in New Issue
Block a user