Added new filesystem layer for read/write alignment with boundary of encrypted chunks.

This commit is contained in:
Sebastian Stenzel
2015-12-29 13:41:47 +01:00
parent c21654eac1
commit 44d1250986
15 changed files with 283 additions and 117 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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