Skip to content

Commit e76da82

Browse files
authored
Merge pull request #53 from saalfeldlab/feat/configuration
Introduce `N5FactoryOptions` for configurable `N5Factory` behavior
2 parents 3839216 + bf0f687 commit e76da82

11 files changed

Lines changed: 573 additions & 71 deletions

File tree

src/main/java/org/janelia/saalfeldlab/n5/universe/N5Factory.java

Lines changed: 88 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,16 @@
1010
import org.janelia.saalfeldlab.n5.KeyValueAccess;
1111
import org.janelia.saalfeldlab.n5.N5Exception;
1212
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
13-
import org.janelia.saalfeldlab.n5.N5KeyValueReader;
14-
import org.janelia.saalfeldlab.n5.N5KeyValueWriter;
1513
import org.janelia.saalfeldlab.n5.N5Reader;
1614
import org.janelia.saalfeldlab.n5.N5URI;
1715
import org.janelia.saalfeldlab.n5.N5Writer;
1816
import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Reader;
1917
import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Writer;
2018
import org.janelia.saalfeldlab.n5.s3.AmazonS3Utils;
19+
import org.janelia.saalfeldlab.n5.universe.options.*;
2120
import org.janelia.saalfeldlab.n5.zarr.N5ZarrReader;
2221
import org.janelia.saalfeldlab.n5.zarr.N5ZarrWriter;
2322
import org.janelia.saalfeldlab.n5.zarr.ZarrKeyValueReader;
24-
import org.janelia.saalfeldlab.n5.zarr.ZarrKeyValueWriter;
25-
import org.janelia.saalfeldlab.n5.zarr.v3.ZarrV3KeyValueReader;
26-
import org.janelia.saalfeldlab.n5.zarr.v3.ZarrV3KeyValueWriter;
2723
import software.amazon.awssdk.services.s3.S3Client;
2824
import software.amazon.awssdk.services.s3.S3ClientBuilder;
2925

@@ -50,64 +46,108 @@
5046
* @author John Bogovic
5147
* @author Igor Pisarev
5248
*/
49+
@SuppressWarnings("UnusedReturnValue")
5350
public class N5Factory implements Serializable {
5451

5552
static final N5Factory FACTORY = new N5Factory();
53+
private N5FactoryOptions options = new N5FactoryOptions();
5654

5755
private static final long serialVersionUID = -6823715427289454617L;
5856
final static Pattern HTTPS_SCHEME = Pattern.compile("http(s)?", Pattern.CASE_INSENSITIVE);
5957
final static Pattern FILE_SCHEME = Pattern.compile("file", Pattern.CASE_INSENSITIVE);
60-
private int[] hdf5DefaultBlockSize = {64, 64, 64, 1, 1};
61-
private boolean hdf5OverrideBlockSize = false;
62-
private GsonBuilder gsonBuilder = new GsonBuilder();
63-
private boolean cacheAttributes = true;
64-
private String zarrDimensionSeparator = ".";
65-
private boolean zarrMapN5DatasetAttributes = true;
66-
private boolean zarrMergeAttributes = true;
6758
private String googleCloudProjectId = null;
6859
private StorageFormat preferredStorageFormat = null;
6960
private Consumer<S3ClientBuilder> s3BuilderConfig;
7061
private Consumer<StorageOptions.Builder> gcsBuilderConfig;
7162

63+
public N5FactoryOptions getOptions() {
64+
65+
return options;
66+
}
67+
68+
public N5Factory setOptions(N5FactoryOptions options) {
69+
this.options = options;
70+
return this;
71+
}
72+
73+
public N5Factory options( Consumer<N5FactoryOptions> configureOptions) {
74+
configureOptions.accept(options);
75+
return this;
76+
}
77+
78+
/**
79+
* @deprecated configure with {@link N5Factory#getOptions()} and {@link N5FactoryOptions#hdf5(Consumer)}
80+
*/
7281
public N5Factory hdf5DefaultBlockSize(final int... blockSize) {
7382

74-
hdf5DefaultBlockSize = blockSize;
83+
getOptions().hdf5(opts -> opts.defaultBlockSize(blockSize));
7584
return this;
7685
}
7786

87+
/**
88+
* @deprecated configure with {@link N5Factory#getOptions()} and {@link N5FactoryOptions#hdf5(Consumer)}
89+
*/
7890
public N5Factory hdf5OverrideBlockSize(final boolean override) {
7991

80-
hdf5OverrideBlockSize = override;
92+
getOptions().hdf5(opts -> opts.overrideBlockSize(override));
8193
return this;
8294
}
8395

96+
/**
97+
* @deprecated configure with {@link N5Factory#getOptions()} and {@link N5FactoryOptions#gsonBuilder(GsonBuilder)}
98+
*/
8499
public N5Factory gsonBuilder(final GsonBuilder gsonBuilder) {
85100

86-
this.gsonBuilder = gsonBuilder;
101+
options.gsonBuilder(gsonBuilder);
87102
return this;
88103
}
89104

105+
/**
106+
* @deprecated configure with {@link N5Factory#getOptions()} and {@link N5FactoryOptions#cacheAttributes(boolean)}
107+
*/
90108
public N5Factory cacheAttributes(final boolean cacheAttributes) {
91109

92-
this.cacheAttributes = cacheAttributes;
110+
options.cacheAttributes(cacheAttributes);
93111
return this;
94112
}
95113

114+
115+
/**
116+
* Deprecated method to set dimensions separator for zarr 2 writers.
117+
*
118+
* @param separator to use for Zarr2 dimension separator
119+
* @deprecated configure with {@link N5Factory#getOptions()}, {@link N5FactoryOptions#zarr2(Consumer)}, {@link Zarr2Builder#dimensionSeparator(String)}
120+
*/
96121
public N5Factory zarrDimensionSeparator(final String separator) {
97122

98-
zarrDimensionSeparator = separator;
123+
getOptions().zarr2(options -> options.dimensionSeparator(separator));
99124
return this;
100125
}
101126

127+
/**
128+
* Value to set for the [mapN5DatasetAttributes] parameter of ZarrKeyValueReader.
129+
* NOTE: this is only used for Zarr2 readers, not Zarr3
130+
*
131+
* @param mapAttributes see {@link ZarrKeyValueReader#getAttributes(String)}
132+
* @deprecated configure with {@link N5Factory#getOptions()}, {@link N5FactoryOptions#zarr2(Consumer)}, {@link Zarr2Builder#mapN5DatasetAttributes(boolean)}
133+
*/
102134
public N5Factory zarrMapN5Attributes(final boolean mapAttributes) {
103135

104-
zarrMapN5DatasetAttributes = mapAttributes;
136+
getOptions().zarr2(options -> options.mapN5DatasetAttributes(mapAttributes));
105137
return this;
106138
}
107139

140+
141+
/**
142+
* Value to set for the [mergeAttributes] parameter of ZarrKeyValueReader.
143+
* NOTE: this is only used for Zarr2 readers, not Zarr3
144+
*
145+
* @param mergeAttributes see {@link ZarrKeyValueReader#getAttributes(String)}
146+
* @deprecated configure with {@link N5Factory#getOptions()}, {@link N5FactoryOptions#zarr2(Consumer)}, {@link Zarr2Builder#mergeAttributes(boolean)}
147+
*/
108148
public N5Factory zarrMergeAttributes(final boolean mergeAttributes) {
109149

110-
zarrMergeAttributes = mergeAttributes;
150+
getOptions().zarr2(options -> options.mergeAttributes(mergeAttributes));
111151
return this;
112152
}
113153

@@ -248,12 +288,10 @@ public N5Reader openHDF5Reader(final String path) {
248288
*
249289
* @param uri uri to the google cloud object
250290
* @return the N5Reader
251-
* @throws URISyntaxException if uri is malformed
252-
*
253291
* @deprecated use {@link N5Factory#openReader(KeyValueAccessBackend, URI)} instead
254292
*/
255293
@Deprecated
256-
public N5Reader openGoogleCloudReader(final String uri) throws URISyntaxException {
294+
public N5Reader openGoogleCloudReader(final String uri) {
257295

258296
return openN5ContainerWithBackend(KeyValueAccessBackend.GOOGLE_CLOUD, uri, true, this::openReader);
259297
}
@@ -263,12 +301,10 @@ public N5Reader openGoogleCloudReader(final String uri) throws URISyntaxExceptio
263301
*
264302
* @param uri uri to the amazon s3 object
265303
* @return the N5Reader
266-
* @throws URISyntaxException if uri is malformed
267-
*
268304
* @deprecated use {@link N5Factory#openReader(KeyValueAccessBackend, URI)} instead
269305
*/
270306
@Deprecated
271-
public N5Reader openAWSS3Reader(final String uri) throws URISyntaxException {
307+
public N5Reader openAWSS3Reader(final String uri) {
272308

273309
return openN5ContainerWithBackend(KeyValueAccessBackend.AWS, uri, true, this::openReader);
274310
}
@@ -278,12 +314,10 @@ public N5Reader openAWSS3Reader(final String uri) throws URISyntaxException {
278314
*
279315
* @param uri uri to the N5Reader
280316
* @return the N5Reader
281-
* @throws URISyntaxException if uri is malformed
282-
*
283317
* @deprecated use {@link N5Factory#openReader(KeyValueAccessBackend, URI)} instead
284318
*/
285319
@Deprecated
286-
public N5Reader openFileSystemReader(final String uri) throws URISyntaxException {
320+
public N5Reader openFileSystemReader(final String uri) {
287321

288322
return openN5ContainerWithBackend(KeyValueAccessBackend.FILE, uri, true, this::openReader);
289323
}
@@ -402,19 +436,20 @@ public N5Reader openReader(@Nullable final StorageFormat storage, final KeyValue
402436
} else {
403437

404438
final String containerPath = location.toString();
439+
405440
switch (storage) {
406-
case N5:
407-
return new N5KeyValueReader(access, containerPath, gsonBuilder, cacheAttributes);
408-
case ZARR3:
409-
return new ZarrV3KeyValueReader(access,containerPath, gsonBuilder, cacheAttributes);
410-
case ZARR2:
411-
return new ZarrKeyValueReader(access, containerPath, gsonBuilder, zarrMapN5DatasetAttributes, zarrMergeAttributes, cacheAttributes);
412-
case ZARR:
413-
return newGenericZarrReader(access, location);
414-
case HDF5:
415-
return new N5HDF5Reader(containerPath, hdf5OverrideBlockSize, gsonBuilder, hdf5DefaultBlockSize);
416-
}
417-
return null;
441+
case HDF5:
442+
return getOptions().getHdf5Builder().buildReader(containerPath);
443+
case N5:
444+
return getOptions().getN5Builder().buildReader(access, containerPath);
445+
case ZARR3:
446+
return getOptions().getZarr3Builder().buildReader(access, containerPath);
447+
case ZARR2:
448+
return getOptions().getZarr2Builder().buildReader(access, containerPath);
449+
case ZARR:
450+
return newGenericZarrReader(access, location);
451+
}
452+
return null;
418453
}
419454
}
420455

@@ -497,12 +532,10 @@ public N5Writer openHDF5Writer(final String path) {
497532
*
498533
* @param uri uri to the google cloud object
499534
* @return the N5GoogleCloudStorageWriter
500-
* @throws URISyntaxException if uri is malformed
501-
*
502535
* @deprecated use {@link #openWriter(KeyValueAccessBackend, String)} instead.
503536
*/
504537
@Deprecated
505-
public N5Writer openGoogleCloudWriter(final String uri) throws URISyntaxException {
538+
public N5Writer openGoogleCloudWriter(final String uri) {
506539

507540
return openN5ContainerWithBackend(KeyValueAccessBackend.GOOGLE_CLOUD, uri, false, this::openWriter);
508541
}
@@ -512,13 +545,10 @@ public N5Writer openGoogleCloudWriter(final String uri) throws URISyntaxExceptio
512545
*
513546
* @param uri uri to the s3 object
514547
* @return the N5Writer
515-
* @throws URISyntaxException if the URI is malformed
516-
*
517-
*
518548
* @deprecated use {@link #openWriter(KeyValueAccessBackend, String)} instead.
519549
*/
520550
@Deprecated()
521-
public N5Writer openAWSS3Writer(final String uri) throws URISyntaxException {
551+
public N5Writer openAWSS3Writer(final String uri) {
522552

523553
return openN5ContainerWithBackend(KeyValueAccessBackend.AWS, uri, false, this::openWriter);
524554
}
@@ -631,19 +661,17 @@ public N5Writer openWriter(@Nullable final StorageFormat storage, final KeyValue
631661

632662
final String containerLocation = location.toString();
633663
switch (storage) {
634-
case ZARR3:
635-
final ZarrV3KeyValueWriter writer = new ZarrV3KeyValueWriter(access, containerLocation, gsonBuilder, cacheAttributes);
636-
writer.setDimensionSeparator(zarrDimensionSeparator);
637-
return writer;
638-
case ZARR2:
639-
return new ZarrKeyValueWriter(access, containerLocation, gsonBuilder, zarrMapN5DatasetAttributes, zarrMergeAttributes, zarrDimensionSeparator, cacheAttributes);
640-
case ZARR:
641-
return newGenericZarrWriter(access, location);
642-
case N5:
643-
return new N5KeyValueWriter(access, containerLocation, gsonBuilder, cacheAttributes);
644-
case HDF5:
645-
return new N5HDF5Writer(containerLocation, hdf5OverrideBlockSize, gsonBuilder, hdf5DefaultBlockSize);
646-
}
664+
case HDF5:
665+
return options.getHdf5Builder().buildWriter(containerLocation);
666+
case N5:
667+
return options.getN5Builder().buildWriter(access, containerLocation);
668+
case ZARR3:
669+
return options.getZarr3Builder().buildWriter(access, containerLocation);
670+
case ZARR2:
671+
return options.getZarr2Builder().buildWriter(access, containerLocation);
672+
case ZARR:
673+
return newGenericZarrWriter(access, location);
674+
}
647675
}
648676
return null;
649677
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.janelia.saalfeldlab.n5.universe.options;
2+
3+
import com.google.gson.GsonBuilder;
4+
5+
@SuppressWarnings("UnusedReturnValue")
6+
public abstract class AbstractN5Builder {
7+
8+
protected Boolean cacheAttributes = null;
9+
protected GsonBuilder gsonBuilder = null;
10+
11+
final protected AbstractN5Builder sharedOptions;
12+
13+
AbstractN5Builder(AbstractN5Builder sharedOptions) {
14+
this.sharedOptions = sharedOptions;
15+
}
16+
17+
public abstract AbstractN5Builder cacheAttributes(boolean cacheAttributes);
18+
19+
public abstract AbstractN5Builder gsonBuilder(GsonBuilder gsonBuilder);
20+
21+
public boolean getCacheAttributes() {
22+
return cacheAttributes != null ? cacheAttributes : sharedOptions.getCacheAttributes();
23+
}
24+
25+
public GsonBuilder getGsonBuilder() {
26+
return gsonBuilder != null ? gsonBuilder : sharedOptions.getGsonBuilder();
27+
}
28+
}
29+
30+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package org.janelia.saalfeldlab.n5.universe.options;
2+
3+
import com.google.gson.GsonBuilder;
4+
import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Reader;
5+
import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Writer;
6+
7+
@SuppressWarnings("UnusedReturnValue")
8+
public class HDF5Builder extends AbstractN5Builder {
9+
10+
protected int[] defaultBlockSize = new int[]{64, 64, 64, 1, 1};
11+
protected boolean overrideBlockSize = false;
12+
13+
HDF5Builder(AbstractN5Builder sharedOptions) {
14+
super(sharedOptions);
15+
}
16+
17+
@Override
18+
public HDF5Builder cacheAttributes(boolean cacheAttributes) {
19+
this.cacheAttributes = cacheAttributes;
20+
return this;
21+
}
22+
23+
@Override
24+
public HDF5Builder gsonBuilder(GsonBuilder gsonBuilder) {
25+
this.gsonBuilder = gsonBuilder;
26+
return this;
27+
}
28+
29+
public HDF5Builder defaultBlockSize(int[] defaultBlockSize) {
30+
this.defaultBlockSize = defaultBlockSize.clone();
31+
return this;
32+
}
33+
34+
public HDF5Builder overrideBlockSize(boolean overrideBlockSize) {
35+
this.overrideBlockSize = overrideBlockSize;
36+
return this;
37+
}
38+
39+
public int[] getDefaultBlockSize() {
40+
return defaultBlockSize.clone();
41+
}
42+
43+
public boolean getOverrideBlockSize() {
44+
return overrideBlockSize;
45+
}
46+
47+
public N5HDF5Writer buildWriter(String containerLocation) {
48+
return new N5HDF5Writer(containerLocation, getOverrideBlockSize(), getGsonBuilder(), getDefaultBlockSize());
49+
}
50+
51+
public N5HDF5Reader buildReader(String containerPath) {
52+
return new N5HDF5Reader(containerPath, getOverrideBlockSize(), getGsonBuilder(), getDefaultBlockSize());
53+
}
54+
}

0 commit comments

Comments
 (0)