From 44d1250986b21c04f69ff97d3d5caad894dec6c5 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 29 Dec 2015 13:41:47 +0100 Subject: [PATCH] Added new filesystem layer for read/write alignment with boundary of encrypted chunks. --- .../filesystem/delegating/DelegatingFile.java | 33 +++++++------- .../delegating/DelegatingFileSystem.java | 35 --------------- .../delegating/DelegatingFolder.java | 43 ++++++++++--------- .../filesystem/delegating/DelegatingNode.java | 10 +---- .../delegating/DelegatingFileTest.java | 30 ++++++------- .../delegating/DelegatingFolderTest.java | 39 +++++++++-------- .../delegating/TestDelegatingFile.java | 23 ++++++++++ .../delegating/TestDelegatingFileSystem.java | 16 +++++++ .../delegating/TestDelegatingFolder.java | 22 ++++++++++ .../blockaligned/BlockAlignedFile.java | 27 ++++++++++++ .../blockaligned/BlockAlignedFileSystem.java | 12 ++++++ .../blockaligned/BlockAlignedFolder.java | 26 +++++++++++ .../BlockAlignedReadableFile.java | 27 ++++++++++++ .../BlockAlignedWritableFile.java | 27 ++++++++++++ .../filesystem/blockaligned/package-info.java | 30 +++++++++++++ 15 files changed, 283 insertions(+), 117 deletions(-) delete mode 100644 main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFileSystem.java create mode 100644 main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFile.java create mode 100644 main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFileSystem.java create mode 100644 main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFolder.java create mode 100644 main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFile.java create mode 100644 main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFileSystem.java create mode 100644 main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFolder.java create mode 100644 main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedReadableFile.java create mode 100644 main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedWritableFile.java create mode 100644 main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/package-info.java diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFile.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFile.java index 7d1b68d63..b22f58be1 100644 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFile.java +++ b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFile.java @@ -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 DelegatingNodeimplements File { +public abstract class DelegatingFile> extends DelegatingNodeimplements File { - private final Function readableFileFactory; - private final Function writableFileFactory; + private final D parent; - public DelegatingFile(DelegatingFolder parent, File delegate, Function readableFileFactory, Function 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 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 DelegatingNodeimplements 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 DelegatingNodeimplements 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); diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFileSystem.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFileSystem.java deleted file mode 100644 index c03475dcc..000000000 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFileSystem.java +++ /dev/null @@ -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 folderFactory, BiFunction 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); - } - -} diff --git a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFolder.java b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFolder.java index ba9f7192f..960bf5389 100644 --- a/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFolder.java +++ b/main/filesystem-api/src/main/java/org/cryptomator/filesystem/delegating/DelegatingFolder.java @@ -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 DelegatingNodeimplements Folder { +public abstract class DelegatingFolder, F extends DelegatingFile> extends DelegatingNode + implements Folder { - private final BiFunction folderFactory; - private final BiFunction fileFactory; + private final D parent; - public DelegatingFolder(DelegatingFolder parent, Folder delegate, BiFunction folderFactory, BiFunction fileFactory) { - super(parent, delegate); - this.folderFactory = folderFactory; - this.fileFactory = fileFactory; + public DelegatingFolder(D parent, Folder delegate) { + super(delegate); + this.parent = parent; } @Override - public Stream> children() throws UncheckedIOException { + public Optional parent() throws UncheckedIOException { + return Optional.ofNullable(parent); + } + + @Override + public Stream children() throws UncheckedIOException { return Stream.concat(folders(), files()); } @Override - public Stream folders() { + public Stream folders() { return delegate.folders().map(this::folder); } @Override - public Stream files() throws UncheckedIOException { + public Stream 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 DelegatingNodeimplements 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 DelegatingNodeimplements 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."); 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 affeb2f3d..3a862802e 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,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 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 parent() throws UncheckedIOException { - return Optional.ofNullable(parent); - } - @Override public String name() throws UncheckedIOException { return delegate.name(); diff --git a/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/DelegatingFileTest.java b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/DelegatingFileTest.java index 6b9297dd4..8c76cf02b 100644 --- a/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/DelegatingFileTest.java +++ b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/DelegatingFileTest.java @@ -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)); } diff --git a/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/DelegatingFolderTest.java b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/DelegatingFolderTest.java index f9412fa7f..cf50046a5 100644 --- a/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/DelegatingFolderTest.java +++ b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/DelegatingFolderTest.java @@ -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.>when(mockFolder.folders()).thenAnswer((invocation) -> { return Arrays.stream(new Folder[] {subFolder1}); }); - List subFolders = delegatingFolder.folders().collect(Collectors.toList()); + List subFolders = delegatingFolder.folders().collect(Collectors.toList()); Assert.assertThat(subFolders, Matchers.containsInAnyOrder(delegatingSubFolder1)); /* files */ @@ -91,11 +92,11 @@ public class DelegatingFolderTest { Mockito.>when(mockFolder.files()).thenAnswer((invocation) -> { return Arrays.stream(new File[] {subFile1}); }); - List subFiles = delegatingFolder.files().collect(Collectors.toList()); + List subFiles = delegatingFolder.files().collect(Collectors.toList()); Assert.assertThat(subFiles, Matchers.containsInAnyOrder(delegatingSubFile1)); /* files and folders */ - List> children = delegatingFolder.children().collect(Collectors.toList()); + List 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(); diff --git a/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFile.java b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFile.java new file mode 100644 index 000000000..393e4abd6 --- /dev/null +++ b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFile.java @@ -0,0 +1,23 @@ +package org.cryptomator.filesystem.delegating; + +import java.io.UncheckedIOException; + +import org.cryptomator.filesystem.File; + +class TestDelegatingFile extends DelegatingFile { + + 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()); + } + +} diff --git a/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFileSystem.java b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFileSystem.java new file mode 100644 index 000000000..e3d8b379e --- /dev/null +++ b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFileSystem.java @@ -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); + } + +} diff --git a/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFolder.java b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFolder.java new file mode 100644 index 000000000..c33627ff7 --- /dev/null +++ b/main/filesystem-api/src/test/java/org/cryptomator/filesystem/delegating/TestDelegatingFolder.java @@ -0,0 +1,22 @@ +package org.cryptomator.filesystem.delegating; + +import org.cryptomator.filesystem.File; +import org.cryptomator.filesystem.Folder; + +class TestDelegatingFolder extends DelegatingFolder { + + 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); + } + +} diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFile.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFile.java new file mode 100644 index 000000000..f5d843992 --- /dev/null +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFile.java @@ -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 { + + 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); + } + +} 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 new file mode 100644 index 000000000..6990c10f2 --- /dev/null +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFileSystem.java @@ -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); + } + +} diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFolder.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFolder.java new file mode 100644 index 000000000..67ed2b706 --- /dev/null +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedFolder.java @@ -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 { + + 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); + } + +} diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedReadableFile.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedReadableFile.java new file mode 100644 index 000000000..51b52166e --- /dev/null +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedReadableFile.java @@ -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); + } + +} diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedWritableFile.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedWritableFile.java new file mode 100644 index 000000000..6ceeb0990 --- /dev/null +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/BlockAlignedWritableFile.java @@ -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); + } + +} diff --git a/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/package-info.java b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/package-info.java new file mode 100644 index 000000000..2ca086095 --- /dev/null +++ b/main/filesystem-crypto/src/main/java/org/cryptomator/filesystem/blockaligned/package-info.java @@ -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. + *

+ * In general the formula to align a requested read with a physical read is floor(x / blockSize) * blockSize
+ * For example blockSize=10 result in the following block-aligned read/write attempts: + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Requested ReadPhysical Read
00
50
90
1010
1110
3530
+ */ +package org.cryptomator.filesystem.blockaligned; \ No newline at end of file