mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-18 18:51:26 +00:00
Added new filesystem layer for read/write alignment with boundary of encrypted chunks.
This commit is contained in:
@@ -9,37 +9,34 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.function.Function;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.ReadableFile;
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
|
||||
public class DelegatingFile extends DelegatingNode<File>implements File {
|
||||
public abstract class DelegatingFile<R extends DelegatingReadableFile, W extends DelegatingWritableFile, D extends DelegatingFolder<R, W, D, ?>> extends DelegatingNode<File>implements File {
|
||||
|
||||
private final Function<ReadableFile, DelegatingReadableFile> readableFileFactory;
|
||||
private final Function<WritableFile, DelegatingWritableFile> writableFileFactory;
|
||||
private final D parent;
|
||||
|
||||
public DelegatingFile(DelegatingFolder parent, File delegate, Function<ReadableFile, DelegatingReadableFile> readableFileFactory, Function<WritableFile, DelegatingWritableFile> writableFileFactory) {
|
||||
super(parent, delegate);
|
||||
this.readableFileFactory = readableFileFactory;
|
||||
this.writableFileFactory = writableFileFactory;
|
||||
public DelegatingFile(D parent, File delegate) {
|
||||
super(delegate);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelegatingReadableFile openReadable() throws UncheckedIOException {
|
||||
return readableFileFactory.apply(delegate.openReadable());
|
||||
public Optional<D> parent() throws UncheckedIOException {
|
||||
return Optional.of(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelegatingWritableFile openWritable() throws UncheckedIOException {
|
||||
return writableFileFactory.apply(delegate.openWritable());
|
||||
}
|
||||
public abstract R openReadable() throws UncheckedIOException;
|
||||
|
||||
@Override
|
||||
public abstract W openWritable() throws UncheckedIOException;
|
||||
|
||||
@Override
|
||||
public void copyTo(File destination) {
|
||||
if (getClass().equals(destination.getClass())) {
|
||||
final File delegateDest = ((DelegatingFile) destination).delegate;
|
||||
final File delegateDest = ((DelegatingFile<?, ?, ?>) destination).delegate;
|
||||
delegate.copyTo(delegateDest);
|
||||
} else {
|
||||
delegate.copyTo(destination);
|
||||
@@ -49,7 +46,7 @@ public class DelegatingFile extends DelegatingNode<File>implements File {
|
||||
@Override
|
||||
public void moveTo(File destination) {
|
||||
if (getClass().equals(destination.getClass())) {
|
||||
final File delegateDest = ((DelegatingFile) destination).delegate;
|
||||
final File delegateDest = ((DelegatingFile<?, ?, ?>) destination).delegate;
|
||||
delegate.moveTo(delegateDest);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can only move DelegatingFile to other DelegatingFile.");
|
||||
@@ -59,7 +56,7 @@ public class DelegatingFile extends DelegatingNode<File>implements File {
|
||||
@Override
|
||||
public int compareTo(File o) {
|
||||
if (getClass().equals(o.getClass())) {
|
||||
final File delegateOther = ((DelegatingFile) o).delegate;
|
||||
final File delegateOther = ((DelegatingFile<?, ?, ?>) o).delegate;
|
||||
return delegate.compareTo(delegateOther);
|
||||
} else {
|
||||
return delegate.compareTo(o);
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.FileSystem;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
|
||||
public class DelegatingFileSystem extends DelegatingFolder implements FileSystem {
|
||||
|
||||
private DelegatingFileSystem(Folder delegate, BiFunction<DelegatingFolder, Folder, DelegatingFolder> folderFactory, BiFunction<DelegatingFolder, File, DelegatingFile> fileFactory) {
|
||||
super(null, delegate, folderFactory, fileFactory);
|
||||
}
|
||||
|
||||
public static DelegatingFileSystem withDelegate(Folder delegate) {
|
||||
return new DelegatingFileSystem(delegate, DelegatingFileSystem::subFolder, DelegatingFileSystem::subFile);
|
||||
}
|
||||
|
||||
private static DelegatingFolder subFolder(DelegatingFolder parent, Folder delegateSubFolder) {
|
||||
return new DelegatingFolder(parent, delegateSubFolder, DelegatingFileSystem::subFolder, DelegatingFileSystem::subFile);
|
||||
}
|
||||
|
||||
private static DelegatingFile subFile(DelegatingFolder parent, File delegateSubFile) {
|
||||
return new DelegatingFile(parent, delegateSubFile, DelegatingReadableFile::new, DelegatingWritableFile::new);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,55 +9,56 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
import org.cryptomator.filesystem.Node;
|
||||
|
||||
public class DelegatingFolder extends DelegatingNode<Folder>implements Folder {
|
||||
public abstract class DelegatingFolder<R extends DelegatingReadableFile, W extends DelegatingWritableFile, D extends DelegatingFolder<R, W, D, F>, F extends DelegatingFile<R, W, D>> extends DelegatingNode<Folder>
|
||||
implements Folder {
|
||||
|
||||
private final BiFunction<DelegatingFolder, Folder, DelegatingFolder> folderFactory;
|
||||
private final BiFunction<DelegatingFolder, File, DelegatingFile> fileFactory;
|
||||
private final D parent;
|
||||
|
||||
public DelegatingFolder(DelegatingFolder parent, Folder delegate, BiFunction<DelegatingFolder, Folder, DelegatingFolder> folderFactory, BiFunction<DelegatingFolder, File, DelegatingFile> fileFactory) {
|
||||
super(parent, delegate);
|
||||
this.folderFactory = folderFactory;
|
||||
this.fileFactory = fileFactory;
|
||||
public DelegatingFolder(D parent, Folder delegate) {
|
||||
super(delegate);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<? extends DelegatingNode<?>> children() throws UncheckedIOException {
|
||||
public Optional<D> parent() throws UncheckedIOException {
|
||||
return Optional.ofNullable(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<? extends Node> children() throws UncheckedIOException {
|
||||
return Stream.concat(folders(), files());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<DelegatingFolder> folders() {
|
||||
public Stream<D> folders() {
|
||||
return delegate.folders().map(this::folder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<DelegatingFile> files() throws UncheckedIOException {
|
||||
public Stream<F> files() throws UncheckedIOException {
|
||||
return delegate.files().map(this::file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelegatingFile file(String name) throws UncheckedIOException {
|
||||
public F file(String name) throws UncheckedIOException {
|
||||
return file(delegate.file(name));
|
||||
}
|
||||
|
||||
private DelegatingFile file(File delegate) {
|
||||
return fileFactory.apply(this, delegate);
|
||||
}
|
||||
protected abstract F file(File delegate);
|
||||
|
||||
@Override
|
||||
public DelegatingFolder folder(String name) throws UncheckedIOException {
|
||||
public D folder(String name) throws UncheckedIOException {
|
||||
return folder(delegate.folder(name));
|
||||
}
|
||||
|
||||
private DelegatingFolder folder(Folder delegate) {
|
||||
return folderFactory.apply(this, delegate);
|
||||
}
|
||||
protected abstract D folder(Folder delegate);
|
||||
|
||||
@Override
|
||||
public void create() throws UncheckedIOException {
|
||||
@@ -72,7 +73,7 @@ public class DelegatingFolder extends DelegatingNode<Folder>implements Folder {
|
||||
@Override
|
||||
public void copyTo(Folder destination) throws UncheckedIOException {
|
||||
if (destination instanceof DelegatingFolder) {
|
||||
final Folder delegateDest = ((DelegatingFolder) destination).delegate;
|
||||
final Folder delegateDest = ((DelegatingFolder<?, ?, ?, ?>) destination).delegate;
|
||||
delegate.copyTo(delegateDest);
|
||||
} else {
|
||||
delegate.copyTo(destination);
|
||||
@@ -82,7 +83,7 @@ public class DelegatingFolder extends DelegatingNode<Folder>implements Folder {
|
||||
@Override
|
||||
public void moveTo(Folder destination) {
|
||||
if (getClass().equals(destination.getClass())) {
|
||||
final Folder delegateDest = ((DelegatingFolder) destination).delegate;
|
||||
final Folder delegateDest = ((DelegatingFolder<?, ?, ?, ?>) destination).delegate;
|
||||
delegate.moveTo(delegateDest);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can only move DelegatingFolder to other DelegatingFolder.");
|
||||
|
||||
@@ -10,28 +10,20 @@ package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.filesystem.Node;
|
||||
|
||||
abstract class DelegatingNode<T extends Node> implements Node {
|
||||
|
||||
private final DelegatingFolder parent;
|
||||
protected final T delegate;
|
||||
|
||||
public DelegatingNode(DelegatingFolder parent, T delegate) {
|
||||
public DelegatingNode(T delegate) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalArgumentException("Delegate must not be null");
|
||||
}
|
||||
this.parent = parent;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<DelegatingFolder> parent() throws UncheckedIOException {
|
||||
return Optional.ofNullable(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() throws UncheckedIOException {
|
||||
return delegate.name();
|
||||
|
||||
@@ -23,7 +23,7 @@ public class DelegatingFileTest {
|
||||
@Test
|
||||
public void testName() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile delegatingFile = new DelegatingFile(null, mockFile, null, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
Mockito.when(mockFile.name()).thenReturn("Test");
|
||||
Assert.assertEquals(mockFile.name(), delegatingFile.name());
|
||||
@@ -34,15 +34,15 @@ public class DelegatingFileTest {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
|
||||
DelegatingFolder delegatingParent = DelegatingFileSystem.withDelegate(mockFolder);
|
||||
DelegatingFile delegatingFile = new DelegatingFile(delegatingParent, mockFile, null, null);
|
||||
TestDelegatingFileSystem delegatingParent = TestDelegatingFileSystem.withRoot(mockFolder);
|
||||
DelegatingFile<?, ?, ?> delegatingFile = new TestDelegatingFile(delegatingParent, mockFile);
|
||||
Assert.assertEquals(delegatingParent, delegatingFile.parent().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExists() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile delegatingFile = new DelegatingFile(null, mockFile, null, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
Mockito.when(mockFile.exists()).thenReturn(true);
|
||||
Assert.assertTrue(delegatingFile.exists());
|
||||
@@ -57,7 +57,7 @@ public class DelegatingFileTest {
|
||||
Instant now = Instant.now();
|
||||
|
||||
Mockito.when(mockFile.lastModified()).thenReturn(now);
|
||||
DelegatingFile delegatingFile = new DelegatingFile(null, mockFile, null, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
Assert.assertEquals(now, delegatingFile.lastModified());
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public class DelegatingFileTest {
|
||||
ReadableFile mockReadableFile = Mockito.mock(ReadableFile.class);
|
||||
|
||||
Mockito.when(mockFile.openReadable()).thenReturn(mockReadableFile);
|
||||
DelegatingFile delegatingFile = new DelegatingFile(null, mockFile, DelegatingReadableFile::new, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
Assert.assertNotNull(delegatingFile.openReadable());
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public class DelegatingFileTest {
|
||||
WritableFile mockWritableFile = Mockito.mock(WritableFile.class);
|
||||
|
||||
Mockito.when(mockFile.openWritable()).thenReturn(mockWritableFile);
|
||||
DelegatingFile delegatingFile = new DelegatingFile(null, mockFile, null, DelegatingWritableFile::new);
|
||||
DelegatingFile<?, ?, ?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
Assert.assertNotNull(delegatingFile.openWritable());
|
||||
}
|
||||
|
||||
@@ -85,8 +85,8 @@ public class DelegatingFileTest {
|
||||
public void testMoveTo() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
DelegatingFile delegatingFile1 = new DelegatingFile(null, mockFile1, null, null);
|
||||
DelegatingFile delegatingFile2 = new DelegatingFile(null, mockFile2, null, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
DelegatingFile<?, ?, ?> delegatingFile2 = new TestDelegatingFile(null, mockFile2);
|
||||
|
||||
delegatingFile1.moveTo(delegatingFile2);
|
||||
Mockito.verify(mockFile1).moveTo(mockFile2);
|
||||
@@ -96,7 +96,7 @@ public class DelegatingFileTest {
|
||||
public void testMoveToDestinationFromDifferentLayer() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
DelegatingFile delegatingFile1 = new DelegatingFile(null, mockFile1, null, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
|
||||
delegatingFile1.moveTo(mockFile2);
|
||||
}
|
||||
@@ -105,8 +105,8 @@ public class DelegatingFileTest {
|
||||
public void testCopyTo() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
DelegatingFile delegatingFile1 = new DelegatingFile(null, mockFile1, null, null);
|
||||
DelegatingFile delegatingFile2 = new DelegatingFile(null, mockFile2, null, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
DelegatingFile<?, ?, ?> delegatingFile2 = new TestDelegatingFile(null, mockFile2);
|
||||
|
||||
delegatingFile1.copyTo(delegatingFile2);
|
||||
Mockito.verify(mockFile1).copyTo(mockFile2);
|
||||
@@ -116,7 +116,7 @@ public class DelegatingFileTest {
|
||||
public void testCopyToDestinationFromDifferentLayer() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
DelegatingFile delegatingFile1 = new DelegatingFile(null, mockFile1, null, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
|
||||
delegatingFile1.copyTo(mockFile2);
|
||||
Mockito.verify(mockFile1).copyTo(mockFile2);
|
||||
@@ -128,8 +128,8 @@ public class DelegatingFileTest {
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
|
||||
Mockito.when(mockFile1.compareTo(mockFile2)).thenReturn(-1);
|
||||
DelegatingFile delegatingFile1 = new DelegatingFile(null, mockFile1, null, null);
|
||||
DelegatingFile delegatingFile2 = new DelegatingFile(null, mockFile2, null, null);
|
||||
DelegatingFile<?, ?, ?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
DelegatingFile<?, ?, ?> delegatingFile2 = new TestDelegatingFile(null, mockFile2);
|
||||
Assert.assertEquals(-1, delegatingFile1.compareTo(delegatingFile2));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
import org.cryptomator.filesystem.Node;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@@ -26,7 +27,7 @@ public class DelegatingFolderTest {
|
||||
@Test
|
||||
public void testName() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder = new DelegatingFolder(null, mockFolder, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
Mockito.when(mockFolder.name()).thenReturn("Test");
|
||||
Assert.assertEquals(mockFolder.name(), delegatingFolder.name());
|
||||
@@ -37,15 +38,15 @@ public class DelegatingFolderTest {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
|
||||
DelegatingFolder delegatingParent = DelegatingFileSystem.withDelegate(mockFolder1);
|
||||
DelegatingFolder delegatingFolder = new DelegatingFolder(delegatingParent, mockFolder2, null, null);
|
||||
TestDelegatingFileSystem delegatingParent = TestDelegatingFileSystem.withRoot(mockFolder1);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder = new TestDelegatingFolder(delegatingParent, mockFolder2);
|
||||
Assert.assertEquals(delegatingParent, delegatingFolder.parent().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExists() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder = new DelegatingFolder(null, mockFolder, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
Mockito.when(mockFolder.exists()).thenReturn(true);
|
||||
Assert.assertTrue(delegatingFolder.exists());
|
||||
@@ -60,19 +61,19 @@ public class DelegatingFolderTest {
|
||||
Instant now = Instant.now();
|
||||
|
||||
Mockito.when(mockFolder.lastModified()).thenReturn(now);
|
||||
DelegatingFolder delegatingFolder = new DelegatingFolder(null, mockFolder, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
Assert.assertEquals(now, delegatingFolder.lastModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChildren() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder = DelegatingFileSystem.withDelegate(mockFolder);
|
||||
TestDelegatingFileSystem delegatingFolder = TestDelegatingFileSystem.withRoot(mockFolder);
|
||||
|
||||
Folder subFolder1 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingSubFolder1 = new DelegatingFolder(delegatingFolder, subFolder1, null, null);
|
||||
TestDelegatingFolder delegatingSubFolder1 = new TestDelegatingFolder(delegatingFolder, subFolder1);
|
||||
File subFile1 = Mockito.mock(File.class);
|
||||
DelegatingFile delegatingSubFile1 = new DelegatingFile(delegatingFolder, subFile1, null, null);
|
||||
TestDelegatingFile delegatingSubFile1 = new TestDelegatingFile(delegatingFolder, subFile1);
|
||||
|
||||
/* folders */
|
||||
Mockito.when(mockFolder.folder("subFolder1")).thenReturn(subFolder1);
|
||||
@@ -81,7 +82,7 @@ public class DelegatingFolderTest {
|
||||
Mockito.<Stream<? extends Folder>>when(mockFolder.folders()).thenAnswer((invocation) -> {
|
||||
return Arrays.stream(new Folder[] {subFolder1});
|
||||
});
|
||||
List<DelegatingFolder> subFolders = delegatingFolder.folders().collect(Collectors.toList());
|
||||
List<TestDelegatingFolder> subFolders = delegatingFolder.folders().collect(Collectors.toList());
|
||||
Assert.assertThat(subFolders, Matchers.containsInAnyOrder(delegatingSubFolder1));
|
||||
|
||||
/* files */
|
||||
@@ -91,11 +92,11 @@ public class DelegatingFolderTest {
|
||||
Mockito.<Stream<? extends File>>when(mockFolder.files()).thenAnswer((invocation) -> {
|
||||
return Arrays.stream(new File[] {subFile1});
|
||||
});
|
||||
List<DelegatingFile> subFiles = delegatingFolder.files().collect(Collectors.toList());
|
||||
List<TestDelegatingFile> subFiles = delegatingFolder.files().collect(Collectors.toList());
|
||||
Assert.assertThat(subFiles, Matchers.containsInAnyOrder(delegatingSubFile1));
|
||||
|
||||
/* files and folders */
|
||||
List<DelegatingNode<?>> children = delegatingFolder.children().collect(Collectors.toList());
|
||||
List<Node> children = delegatingFolder.children().collect(Collectors.toList());
|
||||
DelegatingNode<?>[] expectedChildren = new DelegatingNode[] {delegatingSubFolder1, delegatingSubFile1};
|
||||
Assert.assertThat(children, Matchers.containsInAnyOrder(expectedChildren));
|
||||
|
||||
@@ -105,8 +106,8 @@ public class DelegatingFolderTest {
|
||||
public void testMoveTo() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder1 = new DelegatingFolder(null, mockFolder1, null, null);
|
||||
DelegatingFolder delegatingFolder2 = new DelegatingFolder(null, mockFolder2, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder1 = new TestDelegatingFolder(null, mockFolder1);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder2 = new TestDelegatingFolder(null, mockFolder2);
|
||||
|
||||
delegatingFolder1.moveTo(delegatingFolder2);
|
||||
Mockito.verify(mockFolder1).moveTo(mockFolder2);
|
||||
@@ -116,7 +117,7 @@ public class DelegatingFolderTest {
|
||||
public void testMoveToDestinationFromDifferentLayer() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder1 = new DelegatingFolder(null, mockFolder1, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder1 = new TestDelegatingFolder(null, mockFolder1);
|
||||
|
||||
delegatingFolder1.moveTo(mockFolder2);
|
||||
}
|
||||
@@ -125,8 +126,8 @@ public class DelegatingFolderTest {
|
||||
public void testCopyTo() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder1 = new DelegatingFolder(null, mockFolder1, null, null);
|
||||
DelegatingFolder delegatingFolder2 = new DelegatingFolder(null, mockFolder2, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder1 = new TestDelegatingFolder(null, mockFolder1);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder2 = new TestDelegatingFolder(null, mockFolder2);
|
||||
|
||||
delegatingFolder1.copyTo(delegatingFolder2);
|
||||
Mockito.verify(mockFolder1).copyTo(mockFolder2);
|
||||
@@ -136,7 +137,7 @@ public class DelegatingFolderTest {
|
||||
public void testCopyToDestinationFromDifferentLayer() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder1 = new DelegatingFolder(null, mockFolder1, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder1 = new TestDelegatingFolder(null, mockFolder1);
|
||||
|
||||
delegatingFolder1.copyTo(mockFolder2);
|
||||
Mockito.verify(mockFolder1).copyTo(mockFolder2);
|
||||
@@ -145,7 +146,7 @@ public class DelegatingFolderTest {
|
||||
@Test
|
||||
public void testCreate() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder = new DelegatingFolder(null, mockFolder, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
delegatingFolder.create();
|
||||
Mockito.verify(mockFolder).create();
|
||||
@@ -154,7 +155,7 @@ public class DelegatingFolderTest {
|
||||
@Test
|
||||
public void testDelete() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder delegatingFolder = new DelegatingFolder(null, mockFolder, null, null);
|
||||
DelegatingFolder<?, ?, ?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
delegatingFolder.delete();
|
||||
Mockito.verify(mockFolder).delete();
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
|
||||
class TestDelegatingFile extends DelegatingFile<DelegatingReadableFile, DelegatingWritableFile, TestDelegatingFolder> {
|
||||
|
||||
public TestDelegatingFile(TestDelegatingFolder parent, File delegate) {
|
||||
super(parent, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelegatingReadableFile openReadable() throws UncheckedIOException {
|
||||
return new DelegatingReadableFile(delegate.openReadable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelegatingWritableFile openWritable() throws UncheckedIOException {
|
||||
return new DelegatingWritableFile(delegate.openWritable());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import org.cryptomator.filesystem.FileSystem;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
|
||||
class TestDelegatingFileSystem extends TestDelegatingFolder implements FileSystem {
|
||||
|
||||
private TestDelegatingFileSystem(Folder delegate) {
|
||||
super(null, delegate);
|
||||
}
|
||||
|
||||
public static TestDelegatingFileSystem withRoot(Folder delegate) {
|
||||
return new TestDelegatingFileSystem(delegate);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
|
||||
class TestDelegatingFolder extends DelegatingFolder<DelegatingReadableFile, DelegatingWritableFile, TestDelegatingFolder, TestDelegatingFile> {
|
||||
|
||||
public TestDelegatingFolder(TestDelegatingFolder parent, Folder delegate) {
|
||||
super(parent, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TestDelegatingFile file(File delegate) {
|
||||
return new TestDelegatingFile(this, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TestDelegatingFolder folder(Folder delegate) {
|
||||
return new TestDelegatingFolder(this, delegate);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.cryptomator.filesystem.blockaligned;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.delegating.DelegatingFile;
|
||||
|
||||
class BlockAlignedFile extends DelegatingFile<BlockAlignedReadableFile, BlockAlignedWritableFile, BlockAlignedFolder> {
|
||||
|
||||
private final int blockSize;
|
||||
|
||||
public BlockAlignedFile(BlockAlignedFolder parent, File delegate, int blockSize) {
|
||||
super(parent, delegate);
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockAlignedReadableFile openReadable() throws UncheckedIOException {
|
||||
return new BlockAlignedReadableFile(delegate.openReadable(), blockSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockAlignedWritableFile openWritable() throws UncheckedIOException {
|
||||
return new BlockAlignedWritableFile(delegate.openWritable(), blockSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.cryptomator.filesystem.blockaligned;
|
||||
|
||||
import org.cryptomator.filesystem.FileSystem;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
|
||||
public class BlockAlignedFileSystem extends BlockAlignedFolder implements FileSystem {
|
||||
|
||||
public BlockAlignedFileSystem(Folder delegate, int blockSize) {
|
||||
super(null, delegate, blockSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.cryptomator.filesystem.blockaligned;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
import org.cryptomator.filesystem.delegating.DelegatingFolder;
|
||||
|
||||
class BlockAlignedFolder extends DelegatingFolder<BlockAlignedReadableFile, BlockAlignedWritableFile, BlockAlignedFolder, BlockAlignedFile> {
|
||||
|
||||
private final int blockSize;
|
||||
|
||||
public BlockAlignedFolder(BlockAlignedFolder parent, Folder delegate, int blockSize) {
|
||||
super(parent, delegate);
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockAlignedFile file(File delegate) {
|
||||
return new BlockAlignedFile(this, delegate, blockSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockAlignedFolder folder(Folder delegate) {
|
||||
return new BlockAlignedFolder(this, delegate, blockSize);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.cryptomator.filesystem.blockaligned;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.cryptomator.filesystem.ReadableFile;
|
||||
import org.cryptomator.filesystem.delegating.DelegatingReadableFile;
|
||||
|
||||
class BlockAlignedReadableFile extends DelegatingReadableFile {
|
||||
|
||||
public BlockAlignedReadableFile(ReadableFile delegate, int blockSize) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void position(long position) throws UncheckedIOException {
|
||||
// TODO Auto-generated method stub
|
||||
super.position(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(ByteBuffer target) throws UncheckedIOException {
|
||||
// TODO Auto-generated method stub
|
||||
return super.read(target);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.cryptomator.filesystem.blockaligned;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
import org.cryptomator.filesystem.delegating.DelegatingWritableFile;
|
||||
|
||||
class BlockAlignedWritableFile extends DelegatingWritableFile {
|
||||
|
||||
public BlockAlignedWritableFile(WritableFile delegate, int blockSize) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void position(long position) throws UncheckedIOException {
|
||||
// TODO Auto-generated method stub
|
||||
super.position(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ByteBuffer source) throws UncheckedIOException {
|
||||
// TODO Auto-generated method stub
|
||||
return super.write(source);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* Provides a decoration layer for the {@link org.cryptomator.filesystem Filesystem API}, which guarantees, that all read/write attempts to underlying files always begin at a block start position.
|
||||
* Block start positions are integer multiples of a block size + a fixed block shift.
|
||||
* <p>
|
||||
* In general the formula to align a requested read with a physical read is <code>floor(x / blockSize) * blockSize</code><br/>
|
||||
* For example <code>blockSize=10</code> result in the following block-aligned read/write attempts:
|
||||
*
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Requested Read</th><th>Physical Read</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td>0</td><td>0</td></td>
|
||||
* <tr><td>5</td><td>0</td></td>
|
||||
* <tr><td>9</td><td>0</td></td>
|
||||
* <tr><td>10</td><td>10</td></td>
|
||||
* <tr><td>11</td><td>10</td></td>
|
||||
* <tr><td>35</td><td>30</td></td>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*/
|
||||
package org.cryptomator.filesystem.blockaligned;
|
||||
Reference in New Issue
Block a user