Skip to content

Commit 2594595

Browse files
authored
Merge pull request #159 from cryptomator/feature/use-dagger-factories
Feature: Use dagger factories instead of builders
2 parents d61d57a + 62d7e9e commit 2594595

17 files changed

Lines changed: 100 additions & 251 deletions

src/main/java/org/cryptomator/cryptofs/CryptoFileSystemComponent.java

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,13 @@ public interface CryptoFileSystemComponent {
1212

1313
CryptoFileSystemImpl cryptoFileSystem();
1414

15-
@Subcomponent.Builder
16-
interface Builder {
17-
18-
@BindsInstance
19-
Builder cryptor(Cryptor cryptor);
20-
21-
@BindsInstance
22-
Builder vaultConfig(VaultConfig vaultConfig);
23-
24-
@BindsInstance
25-
Builder provider(CryptoFileSystemProvider provider);
26-
27-
@BindsInstance
28-
Builder pathToVault(@PathToVault Path pathToVault);
29-
30-
@BindsInstance
31-
Builder properties(CryptoFileSystemProperties cryptoFileSystemProperties);
32-
33-
CryptoFileSystemComponent build();
15+
@Subcomponent.Factory
16+
interface Factory {
17+
CryptoFileSystemComponent create(@BindsInstance Cryptor cryptor, //
18+
@BindsInstance VaultConfig vaultConfig, //
19+
@BindsInstance CryptoFileSystemProvider provider, //
20+
@BindsInstance @PathToVault Path pathToVault, //
21+
@BindsInstance CryptoFileSystemProperties cryptoFileSystemProperties);
3422
}
3523

3624
}

src/main/java/org/cryptomator/cryptofs/CryptoFileSystems.java

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ class CryptoFileSystems {
3333
private static final Logger LOG = LoggerFactory.getLogger(CryptoFileSystems.class);
3434

3535
private final ConcurrentMap<Path, CryptoFileSystemImpl> fileSystems = new ConcurrentHashMap<>();
36-
private final CryptoFileSystemComponent.Builder cryptoFileSystemComponentBuilder; // sharing reusable builder via synchronized
36+
private final CryptoFileSystemComponent.Factory cryptoFileSystemComponentFactory;
3737
private final FileSystemCapabilityChecker capabilityChecker;
3838
private final SecureRandom csprng;
3939

4040
@Inject
41-
public CryptoFileSystems(CryptoFileSystemComponent.Builder cryptoFileSystemComponentBuilder, FileSystemCapabilityChecker capabilityChecker, SecureRandom csprng) {
42-
this.cryptoFileSystemComponentBuilder = cryptoFileSystemComponentBuilder;
41+
public CryptoFileSystems(CryptoFileSystemComponent.Factory cryptoFileSystemComponentFactory, FileSystemCapabilityChecker capabilityChecker, SecureRandom csprng) {
42+
this.cryptoFileSystemComponentFactory = cryptoFileSystemComponentFactory;
4343
this.capabilityChecker = capabilityChecker;
4444
this.csprng = csprng;
4545
}
@@ -59,7 +59,7 @@ public CryptoFileSystemImpl create(CryptoFileSystemProvider provider, Path pathT
5959
checkVaultRootExistence(pathToVault, cryptor);
6060
return fileSystems.compute(normalizedPathToVault, (path, fs) -> {
6161
if (fs == null) {
62-
return create(provider, normalizedPathToVault, adjustedProperties, cryptor, config);
62+
return cryptoFileSystemComponentFactory.create(cryptor, config, provider, normalizedPathToVault, adjustedProperties).cryptoFileSystem();
6363
} else {
6464
throw new FileSystemAlreadyExistsException();
6565
}
@@ -86,18 +86,6 @@ private void checkVaultRootExistence(Path pathToVault, Cryptor cryptor) throws C
8686
}
8787
}
8888

89-
// synchronized access to non-threadsafe cryptoFileSystemComponentBuilder required
90-
private synchronized CryptoFileSystemImpl create(CryptoFileSystemProvider provider, Path pathToVault, CryptoFileSystemProperties properties, Cryptor cryptor, VaultConfig config) {
91-
return cryptoFileSystemComponentBuilder //
92-
.cryptor(cryptor) //
93-
.vaultConfig(config) //
94-
.pathToVault(pathToVault) //
95-
.properties(properties) //
96-
.provider(provider) //
97-
.build() //
98-
.cryptoFileSystem();
99-
}
100-
10189
/**
10290
* Attempts to read a vault config file
10391
*

src/main/java/org/cryptomator/cryptofs/attr/AttributeComponent.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,12 @@ default <T extends BasicFileAttributes> T attributes(Class<T> type) {
2424
}
2525
}
2626

27-
@Subcomponent.Builder
28-
interface Builder {
27+
@Subcomponent.Factory
28+
interface Factory {
2929

30-
@BindsInstance
31-
Builder ciphertextPath(Path ciphertextPath);
30+
AttributeComponent create(@BindsInstance Path ciphertextPath, //
31+
@BindsInstance CiphertextFileType ciphertextFileType, //
32+
@BindsInstance @Named("ciphertext") BasicFileAttributes ciphertextAttributes);
3233

33-
@BindsInstance
34-
Builder ciphertextFileType(CiphertextFileType ciphertextFileType);
35-
36-
@BindsInstance
37-
Builder ciphertextAttributes(@Named("ciphertext") BasicFileAttributes ciphertextAttributes);
38-
39-
AttributeComponent build();
4034
}
4135
}

src/main/java/org/cryptomator/cryptofs/attr/AttributeProvider.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.cryptomator.cryptofs.common.CiphertextFileType;
1717

1818
import javax.inject.Inject;
19-
import javax.inject.Provider;
2019
import java.io.IOException;
2120
import java.nio.file.Files;
2221
import java.nio.file.LinkOption;
@@ -26,13 +25,13 @@
2625
@CryptoFileSystemScoped
2726
public class AttributeProvider {
2827

29-
private final Provider<AttributeComponent.Builder> attributeComponentBuilderProvider;
28+
private final AttributeComponent.Factory attributeComponentFactory;
3029
private final CryptoPathMapper pathMapper;
3130
private final Symlinks symlinks;
3231

3332
@Inject
34-
AttributeProvider(Provider<AttributeComponent.Builder> attributeComponentBuilderProvider, CryptoPathMapper pathMapper, Symlinks symlinks) {
35-
this.attributeComponentBuilderProvider = attributeComponentBuilderProvider;
33+
AttributeProvider(AttributeComponent.Factory attributeComponentFactory, CryptoPathMapper pathMapper, Symlinks symlinks) {
34+
this.attributeComponentFactory = attributeComponentFactory;
3635
this.pathMapper = pathMapper;
3736
this.symlinks = symlinks;
3837
}
@@ -45,13 +44,10 @@ public <A extends BasicFileAttributes> A readAttributes(CryptoPath cleartextPath
4544
}
4645
Path ciphertextPath = getCiphertextPath(cleartextPath, ciphertextFileType);
4746
A ciphertextAttrs = Files.readAttributes(ciphertextPath, type);
48-
AttributeComponent.Builder builder = attributeComponentBuilderProvider.get();
49-
return builder //
50-
.ciphertextFileType(ciphertextFileType) //
51-
.ciphertextPath(ciphertextPath) //
52-
.ciphertextAttributes(ciphertextAttrs) //
53-
.build() //
54-
.attributes(type);
47+
return attributeComponentFactory.create(ciphertextPath, //
48+
ciphertextFileType, //
49+
ciphertextAttrs) //
50+
.attributes(type); //
5551
}
5652

5753
private Path getCiphertextPath(CryptoPath path, CiphertextFileType type) throws IOException {

src/main/java/org/cryptomator/cryptofs/attr/AttributeViewComponent.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,11 @@ public interface AttributeViewComponent {
1414

1515
Optional<FileAttributeView> attributeView();
1616

17-
@Subcomponent.Builder
18-
interface Builder {
17+
@Subcomponent.Factory
18+
interface Factory {
1919

20-
@BindsInstance
21-
Builder cleartextPath(CryptoPath cleartextPath);
20+
AttributeViewComponent create(@BindsInstance CryptoPath cleartextPath, @BindsInstance Class<? extends FileAttributeView> type, @BindsInstance LinkOption[] linkOptions);
2221

23-
@BindsInstance
24-
Builder viewType(Class<? extends FileAttributeView> type);
25-
26-
@BindsInstance
27-
Builder linkOptions(LinkOption[] linkOptions);
28-
29-
AttributeViewComponent build();
3022
}
3123

3224
}

src/main/java/org/cryptomator/cryptofs/attr/AttributeViewProvider.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import org.slf4j.LoggerFactory;
1515

1616
import javax.inject.Inject;
17-
import javax.inject.Provider;
1817
import java.nio.file.Files;
1918
import java.nio.file.LinkOption;
2019
import java.nio.file.attribute.FileAttributeView;
@@ -25,27 +24,21 @@ public class AttributeViewProvider {
2524

2625
private static final Logger LOG = LoggerFactory.getLogger(AttributeViewProvider.class);
2726

28-
private final Provider<AttributeViewComponent.Builder> attrViewComponentBuilderProvider;
27+
private final AttributeViewComponent.Factory attrViewComponentFactory;
2928

3029
@Inject
31-
AttributeViewProvider(Provider<AttributeViewComponent.Builder> attrViewComponentBuilderProvider) {
32-
this.attrViewComponentBuilderProvider = attrViewComponentBuilderProvider;
30+
AttributeViewProvider(AttributeViewComponent.Factory attrViewComponentFactory) {
31+
this.attrViewComponentFactory = attrViewComponentFactory;
3332
}
3433

3534
/**
3635
* @param cleartextPath the unencrypted path to the file
37-
* @param type the Class object corresponding to the file attribute view
36+
* @param type the Class object corresponding to the file attribute view
3837
* @return a file attribute view of the specified type, or <code>null</code> if the attribute view type is not available
3938
* @see Files#getFileAttributeView(java.nio.file.Path, Class, java.nio.file.LinkOption...)
4039
*/
4140
public <A extends FileAttributeView> A getAttributeView(CryptoPath cleartextPath, Class<A> type, LinkOption... options) {
42-
AttributeViewComponent.Builder builder = attrViewComponentBuilderProvider.get();
43-
Optional<FileAttributeView> view = builder //
44-
.cleartextPath(cleartextPath) //
45-
.viewType(type) //
46-
.linkOptions(options) //
47-
.build() //
48-
.attributeView();
41+
Optional<FileAttributeView> view = attrViewComponentFactory.create(cleartextPath, type, options).attributeView();
4942
if (view.isPresent() && type.isInstance(view.get())) {
5043
return type.cast(view.get());
5144
} else {

src/main/java/org/cryptomator/cryptofs/ch/ChannelComponent.java

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,14 @@ public interface ChannelComponent {
1313

1414
CleartextFileChannel channel();
1515

16-
@Subcomponent.Builder
17-
interface Builder {
18-
19-
@BindsInstance
20-
Builder openOptions(EffectiveOpenOptions options);
21-
22-
@BindsInstance
23-
Builder onClose(ChannelCloseListener listener);
24-
25-
@BindsInstance
26-
Builder ciphertextChannel(FileChannel ciphertextChannel);
27-
28-
@BindsInstance
29-
Builder mustWriteHeader(@MustWriteHeader boolean mustWriteHeader);
30-
31-
@BindsInstance
32-
Builder fileHeader(FileHeader fileHeader);
33-
34-
ChannelComponent build();
16+
@Subcomponent.Factory
17+
interface Factory {
18+
19+
ChannelComponent create(@BindsInstance FileChannel ciphertextChannel, //
20+
@BindsInstance FileHeader fileHeader, //
21+
@BindsInstance @MustWriteHeader boolean mustWriteHeader, //
22+
@BindsInstance EffectiveOpenOptions options, //
23+
@BindsInstance ChannelCloseListener listener); //
3524
}
3625

3726
}

src/main/java/org/cryptomator/cryptofs/dir/DirectoryStreamComponent.java

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,14 @@ public interface DirectoryStreamComponent {
1414

1515
CryptoDirectoryStream directoryStream();
1616

17-
@Subcomponent.Builder
18-
interface Builder {
19-
20-
@BindsInstance
21-
Builder cleartextPath(@Named("cleartextPath") Path cleartextPath);
22-
23-
@BindsInstance
24-
Builder dirId(@Named("dirId") String dirId);
25-
26-
@BindsInstance
27-
Builder ciphertextDirectoryStream(DirectoryStream<Path> ciphertextDirectoryStream);
28-
29-
@BindsInstance
30-
Builder filter(DirectoryStream.Filter<? super Path> filter);
31-
32-
@BindsInstance
33-
Builder onClose(Consumer<CryptoDirectoryStream> onClose);
34-
35-
DirectoryStreamComponent build();
17+
@Subcomponent.Factory
18+
interface Factory {
19+
20+
DirectoryStreamComponent create(@BindsInstance @Named("cleartextPath") Path cleartextPath, //
21+
@BindsInstance @Named("dirId") String dirId, //
22+
@BindsInstance DirectoryStream<Path> ciphertextDirectoryStream, //
23+
@BindsInstance DirectoryStream.Filter<? super Path> filter, //
24+
@BindsInstance Consumer<CryptoDirectoryStream> onClose);
3625
}
3726

3827
}

src/main/java/org/cryptomator/cryptofs/dir/DirectoryStreamFactory.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,25 @@
2020
public class DirectoryStreamFactory {
2121

2222
private final CryptoPathMapper cryptoPathMapper;
23-
private final DirectoryStreamComponent.Builder directoryStreamComponentBuilder; // sharing reusable builder via synchronized
23+
private final DirectoryStreamComponent.Factory directoryStreamComponentFactory;
2424
private final Map<CryptoDirectoryStream, DirectoryStream<Path>> streams = new HashMap<>();
2525

2626
private volatile boolean closed = false;
2727

2828
@Inject
29-
public DirectoryStreamFactory(CryptoPathMapper cryptoPathMapper, DirectoryStreamComponent.Builder directoryStreamComponentBuilder) {
29+
public DirectoryStreamFactory(CryptoPathMapper cryptoPathMapper, DirectoryStreamComponent.Factory directoryStreamComponentFactory) {
3030
this.cryptoPathMapper = cryptoPathMapper;
31-
this.directoryStreamComponentBuilder = directoryStreamComponentBuilder;
31+
this.directoryStreamComponentFactory = directoryStreamComponentFactory;
3232
}
3333

34+
//TODO: is synchronized still needed? One reason was, that a dagger builder was used (replaced by thread safe factory)
3435
public synchronized CryptoDirectoryStream newDirectoryStream(CryptoPath cleartextDir, Filter<? super Path> filter) throws IOException {
3536
if (closed) {
3637
throw new ClosedFileSystemException();
3738
}
3839
CiphertextDirectory ciphertextDir = cryptoPathMapper.getCiphertextDir(cleartextDir);
3940
DirectoryStream<Path> ciphertextDirStream = Files.newDirectoryStream(ciphertextDir.path, this::matchesEncryptedContentPattern);
40-
CryptoDirectoryStream cleartextDirStream = directoryStreamComponentBuilder //
41-
.dirId(ciphertextDir.dirId) //
42-
.ciphertextDirectoryStream(ciphertextDirStream) //
43-
.cleartextPath(cleartextDir) //
44-
.filter(filter) //
45-
.onClose(streams::remove) //
46-
.build() //
47-
.directoryStream();
41+
var cleartextDirStream = directoryStreamComponentFactory.create(cleartextDir, ciphertextDir.dirId, ciphertextDirStream, filter, streams::remove).directoryStream();
4842
streams.put(cleartextDirStream, ciphertextDirStream);
4943
return cleartextDirStream;
5044
}

src/main/java/org/cryptomator/cryptofs/fh/OpenCryptoFile.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
package org.cryptomator.cryptofs.fh;
1010

1111
import org.cryptomator.cryptofs.EffectiveOpenOptions;
12-
import org.cryptomator.cryptofs.ch.ChannelComponent;
1312
import org.cryptomator.cryptofs.ch.CleartextFileChannel;
1413
import org.cryptomator.cryptolib.api.Cryptor;
1514
import org.cryptomator.cryptolib.api.FileHeader;
@@ -87,14 +86,9 @@ public synchronized FileChannel newFileChannel(EffectiveOpenOptions options, Fil
8786
isNewHeader = false;
8887
}
8988
initFileSize(ciphertextFileChannel);
90-
ChannelComponent channelComponent = component.newChannelComponent() //
91-
.ciphertextChannel(ciphertextFileChannel) //
92-
.openOptions(options) //
93-
.onClose(this::channelClosed) //
94-
.mustWriteHeader(isNewHeader) //
95-
.fileHeader(header) //
96-
.build();
97-
cleartextFileChannel = channelComponent.channel();
89+
cleartextFileChannel = component.newChannelComponent() //
90+
.create(ciphertextFileChannel, header, isNewHeader, options, this::channelClosed) //
91+
.channel();
9892
} finally {
9993
if (cleartextFileChannel == null) { // i.e. something didn't work
10094
closeQuietly(ciphertextFileChannel);

0 commit comments

Comments
 (0)