diff --git a/pom.xml b/pom.xml index 37bf7fe..e39d49b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,13 +5,13 @@ org.scijava pom-scijava - 38.0.1 + 39.0.0 org.janelia.saalfeldlab n5-universe - 1.6.1-SNAPSHOT + 1.7.0-SNAPSHOT N5-Universe Utilities spanning all of the N5 repositories @@ -110,17 +110,13 @@ sign,deploy-to-scijava - - 3.3.0 - 4.2.1 - 4.1.1 - 1.3.5 - + 1.0.0-preview.20191208 1.4.1 0.2.5 2.2.2 + 1.1.1 @@ -203,7 +199,7 @@ com.googlecode.json-simple json-simple - 1.1.1 + ${json-simple.version} test diff --git a/src/main/java/org/janelia/saalfeldlab/n5/universe/KeyValueAccessBackend.java b/src/main/java/org/janelia/saalfeldlab/n5/universe/KeyValueAccessBackend.java new file mode 100644 index 0000000..3cb61e8 --- /dev/null +++ b/src/main/java/org/janelia/saalfeldlab/n5/universe/KeyValueAccessBackend.java @@ -0,0 +1,116 @@ +package org.janelia.saalfeldlab.n5.universe; + +import com.amazonaws.services.s3.AmazonS3; +import org.janelia.saalfeldlab.googlecloud.GoogleCloudStorageURI; +import org.janelia.saalfeldlab.googlecloud.GoogleCloudUtils; +import org.janelia.saalfeldlab.n5.FileSystemKeyValueAccess; +import org.janelia.saalfeldlab.n5.KeyValueAccess; +import org.janelia.saalfeldlab.n5.N5Reader; +import org.janelia.saalfeldlab.n5.N5Writer; +import org.janelia.saalfeldlab.n5.googlecloud.GoogleCloudStorageKeyValueAccess; +import org.janelia.saalfeldlab.n5.s3.AmazonS3KeyValueAccess; +import org.janelia.saalfeldlab.n5.s3.AmazonS3Utils; + +import javax.annotation.Nullable; +import java.net.URI; +import java.nio.file.FileSystems; +import java.util.function.BiFunction; +import java.util.function.Predicate; +import java.util.regex.Pattern; + +/** + * Enum to discover and provide {@link KeyValueAccess} for {@link N5Reader}s and {@link N5Writer}s. + * IMPORTANT: If ever new {@link KeyValueAccess} backends are adding, they MUST be re-ordered + * such that the earliest predicates are the most restrictive, and the later predicates + * are the least restrictive. This ensures that when iterating through the values of + * {@link KeyValueAccessBackend} you can test them in order, and stop at the first + * {@link KeyValueAccess} that is generated. + */ +public enum KeyValueAccessBackend implements Predicate, BiFunction { + GOOGLE_CLOUD(uri -> { + final String scheme = uri.getScheme(); + final boolean hasScheme = scheme != null; + return hasScheme && GoogleCloudUtils.GS_SCHEME.asPredicate().test(scheme) + || hasScheme && N5Factory.HTTPS_SCHEME.asPredicate().test(scheme) + && uri.getHost() != null && GoogleCloudUtils.GS_HOST.asPredicate().test(uri.getHost()); + }, KeyValueAccessBackend::newGoogleCloudKeyValueAccess), + AWS(uri -> { + final String scheme = uri.getScheme(); + final boolean hasScheme = scheme != null; + return hasScheme && AmazonS3Utils.S3_SCHEME.asPredicate().test(scheme) + || uri.getHost() != null && hasScheme && N5Factory.HTTPS_SCHEME.asPredicate().test(scheme); + }, KeyValueAccessBackend::newAmazonS3KeyValueAccess), + FILE(uri -> { + final String scheme = uri.getScheme(); + final boolean hasScheme = scheme != null; + return !hasScheme || N5Factory.FILE_SCHEME.asPredicate().test(scheme); + }, KeyValueAccessBackend::newFileSystemKeyValueAccess); + + private final Predicate backendTest; + private final BiFunction backendGenerator; + + KeyValueAccessBackend(Predicate test, BiFunction generator) { + + backendTest = test; + backendGenerator = generator; + } + + @Override public KeyValueAccess apply(final URI uri, final N5Factory factory) { + + if (test(uri)) + return backendGenerator.apply(uri, factory); + return null; + } + + @Override public boolean test(URI uri) { + + return backendTest.test(uri); + } + + /** + * Test the provided {@link URI} to and return the appropriate {@link KeyValueAccess}. + * If no appropriate {@link KeyValueAccess} is found, may be null + * + * @param uri to create a {@link KeyValueAccess} from. + * @return the {@link KeyValueAccess} and container path, or null if none are valid + */ + @Nullable + public static KeyValueAccess getKeyValueAccess(final URI uri) { + + return getKeyValueAccess(uri, N5Factory.FACTORY); + } + + @Nullable + static KeyValueAccess getKeyValueAccess(final URI uri, final N5Factory factory) { + + /*NOTE: The order of these tests is very important, as the predicates for each + * backend take into account reasonable defaults when possible. + * Here we test from most to least restrictive. + * See the Javadoc for more details. */ + for (final KeyValueAccessBackend backend : KeyValueAccessBackend.values()) { + final KeyValueAccess kva = backend.apply(uri, factory); + if (kva != null) + return kva; + } + return null; + } + + private static GoogleCloudStorageKeyValueAccess newGoogleCloudKeyValueAccess(final URI uri, final N5Factory factory) { + + final GoogleCloudStorageURI googleCloudUri = new GoogleCloudStorageURI(uri); + return new GoogleCloudStorageKeyValueAccess(factory.createGoogleCloudStorage(), googleCloudUri, true); + } + + private static AmazonS3KeyValueAccess newAmazonS3KeyValueAccess(final URI uri, final N5Factory factory) { + + final String uriString = uri.toString(); + final AmazonS3 s3 = factory.createS3(uriString); + + return new AmazonS3KeyValueAccess(s3, uri, true); + } + + private static FileSystemKeyValueAccess newFileSystemKeyValueAccess(final URI uri, final N5Factory factory) { + + return new FileSystemKeyValueAccess(FileSystems.getDefault()); + } +} diff --git a/src/main/java/org/janelia/saalfeldlab/n5/universe/N5Factory.java b/src/main/java/org/janelia/saalfeldlab/n5/universe/N5Factory.java index a808a95..1250688 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/universe/N5Factory.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/universe/N5Factory.java @@ -26,21 +26,16 @@ */ package org.janelia.saalfeldlab.n5.universe; -import java.io.File; import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; -import java.nio.file.FileSystems; import java.nio.file.Paths; import java.util.function.BiFunction; -import java.util.function.Predicate; -import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Nullable; import org.apache.commons.lang3.function.TriFunction; -import org.janelia.saalfeldlab.googlecloud.GoogleCloudStorageURI; import org.janelia.saalfeldlab.googlecloud.GoogleCloudUtils; import org.janelia.saalfeldlab.n5.FileSystemKeyValueAccess; import org.janelia.saalfeldlab.n5.KeyValueAccess; @@ -50,11 +45,8 @@ import org.janelia.saalfeldlab.n5.N5Reader; import org.janelia.saalfeldlab.n5.N5URI; import org.janelia.saalfeldlab.n5.N5Writer; -import org.janelia.saalfeldlab.n5.googlecloud.GoogleCloudStorageKeyValueAccess; -import org.janelia.saalfeldlab.n5.hdf5.HDF5Utils; import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Reader; import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Writer; -import org.janelia.saalfeldlab.n5.s3.AmazonS3KeyValueAccess; import org.janelia.saalfeldlab.n5.s3.AmazonS3Utils; import org.janelia.saalfeldlab.n5.zarr.N5ZarrReader; import org.janelia.saalfeldlab.n5.zarr.N5ZarrWriter; @@ -69,7 +61,6 @@ import com.google.gson.GsonBuilder; import net.imglib2.util.Pair; -import net.imglib2.util.ValuePair; /** * Factory for various N5 readers and writers. Implementation specific @@ -83,11 +74,11 @@ */ public class N5Factory implements Serializable { - private static final N5Factory FACTORY = new N5Factory(); + static final N5Factory FACTORY = new N5Factory(); private static final long serialVersionUID = -6823715427289454617L; - private final static Pattern HTTPS_SCHEME = Pattern.compile("http(s)?", Pattern.CASE_INSENSITIVE); - private final static Pattern FILE_SCHEME = Pattern.compile("file", Pattern.CASE_INSENSITIVE); + final static Pattern HTTPS_SCHEME = Pattern.compile("http(s)?", Pattern.CASE_INSENSITIVE); + final static Pattern FILE_SCHEME = Pattern.compile("file", Pattern.CASE_INSENSITIVE); private int[] hdf5DefaultBlockSize = {64, 64, 64, 1, 1}; private boolean hdf5OverrideBlockSize = false; private GsonBuilder gsonBuilder = new GsonBuilder(); @@ -102,25 +93,6 @@ public class N5Factory implements Serializable { private boolean s3Anonymous = true; private String s3Endpoint; - private static GoogleCloudStorageKeyValueAccess newGoogleCloudKeyValueAccess(final URI uri, final N5Factory factory) { - - final GoogleCloudStorageURI googleCloudUri = new GoogleCloudStorageURI(uri); - return new GoogleCloudStorageKeyValueAccess(factory.createGoogleCloudStorage(), googleCloudUri, true); - } - - private static AmazonS3KeyValueAccess newAmazonS3KeyValueAccess(final URI uri, final N5Factory factory) { - - final String uriString = uri.toString(); - final AmazonS3 s3 = factory.createS3(uriString); - - return new AmazonS3KeyValueAccess(s3, uri, true); - } - - private static FileSystemKeyValueAccess newFileSystemKeyValueAccess(final URI uri, final N5Factory factory) { - - return new FileSystemKeyValueAccess(FileSystems.getDefault()); - } - public N5Factory hdf5DefaultBlockSize(final int... blockSize) { hdf5DefaultBlockSize = blockSize; @@ -225,26 +197,21 @@ Storage createGoogleCloudStorage() { return GoogleCloudUtils.createGoogleCloudStorage(googleCloudProjectId); } + + /** * Test the provided {@link URI} to and return the appropriate {@link KeyValueAccess}. * If no appropriate {@link KeyValueAccess} is found, may be null + *

+ * This differs subtly from {@link KeyValueAccessBackend#getKeyValueAccess(URI)} in that + * the resulting {@link KeyValueAccess} may use configured fields from this {@link N5Factory}. * * @param uri to create a {@link KeyValueAccess} from. * @return the {@link KeyValueAccess} and container path, or null if none are valid */ @Nullable - KeyValueAccess getKeyValueAccess(final URI uri) { - - /*NOTE: The order of these tests is very important, as the predicates for each - * backend take into account reasonable defaults when possible. - * Here we test from most to least restrictive. - * See the Javadoc for more details. */ - for (final KeyValueAccessBackend backend : KeyValueAccessBackend.values()) { - final KeyValueAccess kva = backend.apply(uri, this); - if (kva != null) - return kva; - } - return null; + public KeyValueAccess getKeyValueAccess(final URI uri) { + return KeyValueAccessBackend.getKeyValueAccess(uri ,this); } /** @@ -536,7 +503,9 @@ private T openN5ContainerWithBackend( final Pair formatAndUri = StorageFormat.parseUri(containerUri); final URI uri = formatAndUri.getB(); final KeyValueAccess kva = backend.apply(uri, this); - return openWithBackend.apply(formatAndUri.getA(), kva, uri.toString()); + StorageFormat format = formatAndUri.getA(); + format = format != null? format : StorageFormat.guessStorageFromKeys(uri, kva); + return openWithBackend.apply(format, kva, uri.toString()); } private T openN5Container( @@ -547,7 +516,8 @@ private T openN5Container( final KeyValueAccess kva = getKeyValueAccess(uri); if (kva == null) throw new N5Exception("Cannot get KeyValueAccess at " + uri); - return openWithKva.apply(storageFormat, kva, uri.toString()); + final StorageFormat format = storageFormat != null ? storageFormat : StorageFormat.guessStorageFromKeys(uri, kva); + return openWithKva.apply(format, kva, uri.toString()); } private T openN5Container( @@ -569,113 +539,6 @@ private T openN5Container( return openN5Container(null, uri, openWithKva); } - /** - * Enum to discover and provide {@link KeyValueAccess} for {@link N5Reader}s and {@link N5Writer}s. - * IMPORTANT: If ever new {@link KeyValueAccess} backends are adding, they MUST be re-ordered - * such that the earliest predicates are the most restrictive, and the later predicates - * are the least restrictive. This ensures that when iterating through the values of - * {@link KeyValueAccessBackend} you can test them in order, and stop at the first - * {@link KeyValueAccess} that is generated. - */ - enum KeyValueAccessBackend implements Predicate, BiFunction { - GOOGLE_CLOUD(uri -> { - final String scheme = uri.getScheme(); - final boolean hasScheme = scheme != null; - return hasScheme && GoogleCloudUtils.GS_SCHEME.asPredicate().test(scheme) - || hasScheme && HTTPS_SCHEME.asPredicate().test(scheme) - && uri.getHost() != null && GoogleCloudUtils.GS_HOST.asPredicate().test(uri.getHost()); - }, N5Factory::newGoogleCloudKeyValueAccess), - AWS(uri -> { - final String scheme = uri.getScheme(); - final boolean hasScheme = scheme != null; - return hasScheme && AmazonS3Utils.S3_SCHEME.asPredicate().test(scheme) - || uri.getHost() != null && hasScheme && HTTPS_SCHEME.asPredicate().test(scheme); - }, N5Factory::newAmazonS3KeyValueAccess), - FILE(uri -> { - final String scheme = uri.getScheme(); - final boolean hasScheme = scheme != null; - return !hasScheme || FILE_SCHEME.asPredicate().test(scheme); - }, N5Factory::newFileSystemKeyValueAccess); - - private final Predicate backendTest; - private final BiFunction backendGenerator; - - KeyValueAccessBackend(Predicate test, BiFunction generator) { - - backendTest = test; - backendGenerator = generator; - } - - @Override public KeyValueAccess apply(final URI uri, final N5Factory factory) { - - if (test(uri)) - return backendGenerator.apply(uri, factory); - return null; - } - - @Override public boolean test(URI uri) { - - return backendTest.test(uri); - } - } - - public enum StorageFormat { - ZARR(Pattern.compile("zarr", Pattern.CASE_INSENSITIVE), uri -> Pattern.compile("\\.zarr$", Pattern.CASE_INSENSITIVE).matcher(new File(uri.getPath()).toString()).find()), - N5(Pattern.compile("n5", Pattern.CASE_INSENSITIVE), uri -> Pattern.compile("\\.n5$", Pattern.CASE_INSENSITIVE).matcher(new File(uri.getPath()).toString()).find()), - HDF5(Pattern.compile("h(df)?5", Pattern.CASE_INSENSITIVE), uri -> { - final boolean hasHdf5Extension = Pattern.compile("\\.h(df)?5$", Pattern.CASE_INSENSITIVE).matcher(uri.getPath()).find(); - return hasHdf5Extension || HDF5Utils.isHDF5(uri.getPath()); - }); - - static final Pattern STORAGE_SCHEME_PATTERN = Pattern.compile("^(\\s*(?(n5|h(df)?5|zarr)):(//)?)?(?.*)$", Pattern.CASE_INSENSITIVE); - private final static String STORAGE_SCHEME_GROUP = "storageScheme"; - private final static String URI_GROUP = "uri"; - - final Pattern schemePattern; - private final Predicate uriTest; - - StorageFormat(final Pattern schemePattern, final Predicate test) { - - this.schemePattern = schemePattern; - this.uriTest = test; - } - - public static StorageFormat guessStorageFromUri(URI uri) { - - for (final StorageFormat format : StorageFormat.values()) { - if (format.uriTest.test(uri)) - return format; - } - return null; - } - - public static Pair parseUri(String uri) throws URISyntaxException { - - final Pair storageFromScheme = getStorageFromNestedScheme(uri); - final URI asUri = parseUriFromString(storageFromScheme.getB()); - if (storageFromScheme.getA() != null) - return new ValuePair<>(storageFromScheme.getA(), asUri); - else - return new ValuePair<>(guessStorageFromUri(asUri), asUri); - - } - - public static Pair getStorageFromNestedScheme(String uri) { - - final Matcher storageSchemeMatcher = StorageFormat.STORAGE_SCHEME_PATTERN.matcher(uri); - storageSchemeMatcher.matches(); - final String storageFormatScheme = storageSchemeMatcher.group(STORAGE_SCHEME_GROUP); - final String uriGroup = storageSchemeMatcher.group(URI_GROUP); - if (storageFormatScheme != null) { - for (final StorageFormat format : StorageFormat.values()) { - if (format.schemePattern.asPredicate().test(storageFormatScheme)) - return new ValuePair<>(format, uriGroup); - } - } - return new ValuePair<>(null, uriGroup); - } - } - /** * Creates an N5 writer for the specified container URI with default N5Factory configuration. * @@ -698,7 +561,7 @@ public static N5Reader createReader(String containerUri) { return FACTORY.openReader(containerUri); } - private static URI parseUriFromString(String uri) { + static URI parseUriFromString(String uri) { try { return URI.create(uri); } catch (final Throwable ignore) {} diff --git a/src/main/java/org/janelia/saalfeldlab/n5/universe/StorageFormat.java b/src/main/java/org/janelia/saalfeldlab/n5/universe/StorageFormat.java new file mode 100644 index 0000000..03d5527 --- /dev/null +++ b/src/main/java/org/janelia/saalfeldlab/n5/universe/StorageFormat.java @@ -0,0 +1,94 @@ +package org.janelia.saalfeldlab.n5.universe; + +import net.imglib2.util.Pair; +import net.imglib2.util.ValuePair; +import org.janelia.saalfeldlab.n5.KeyValueAccess; +import org.janelia.saalfeldlab.n5.hdf5.HDF5Utils; + +import javax.annotation.Nullable; +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public enum StorageFormat { + ZARR(Pattern.compile("zarr", Pattern.CASE_INSENSITIVE), uri -> Pattern.compile("\\.zarr$", Pattern.CASE_INSENSITIVE).matcher(new File(uri.getPath()).toString()).find()), + N5(Pattern.compile("n5", Pattern.CASE_INSENSITIVE), uri -> Pattern.compile("\\.n5$", Pattern.CASE_INSENSITIVE).matcher(new File(uri.getPath()).toString()).find()), + HDF5(Pattern.compile("h(df)?5", Pattern.CASE_INSENSITIVE), uri -> { + final boolean hasHdf5Extension = Pattern.compile("\\.h(df)?5$", Pattern.CASE_INSENSITIVE).matcher(uri.getPath()).find(); + return hasHdf5Extension || HDF5Utils.isHDF5(uri.getPath()); + }); + + static final Pattern STORAGE_SCHEME_PATTERN = Pattern.compile("^(\\s*(?(n5|h(df)?5|zarr)):(//)?)?(?.*)$", Pattern.CASE_INSENSITIVE); + private final static String STORAGE_SCHEME_GROUP = "storageScheme"; + private final static String URI_GROUP = "uri"; + + final Pattern schemePattern; + private final Predicate uriTest; + + StorageFormat(final Pattern schemePattern, final Predicate test) { + + this.schemePattern = schemePattern; + this.uriTest = test; + } + + public static StorageFormat guessStorageFromUri(URI uri) { + + for (final StorageFormat format : StorageFormat.values()) { + if (format.uriTest.test(uri)) + return format; + } + return null; + } + + public static Pair parseUri(String uri) throws URISyntaxException { + + final Pair storageFromScheme = getStorageFromNestedScheme(uri); + final URI asUri = N5Factory.parseUriFromString(storageFromScheme.getB()); + if (storageFromScheme.getA() != null) + return new ValuePair<>(storageFromScheme.getA(), asUri); + else + return new ValuePair<>(guessStorageFromUri(asUri), asUri); + + } + + public static Pair getStorageFromNestedScheme(String uri) { + + final Matcher storageSchemeMatcher = StorageFormat.STORAGE_SCHEME_PATTERN.matcher(uri); + storageSchemeMatcher.matches(); + final String storageFormatScheme = storageSchemeMatcher.group(STORAGE_SCHEME_GROUP); + final String uriGroup = storageSchemeMatcher.group(URI_GROUP); + if (storageFormatScheme != null) { + for (final StorageFormat format : StorageFormat.values()) { + if (format.schemePattern.asPredicate().test(storageFormatScheme)) + return new ValuePair<>(format, uriGroup); + } + } + return new ValuePair<>(null, uriGroup); + } + + private static final String ZARRAY = ".zarray"; + private static final String ZGROUP = ".zgroup"; + private static final String ZATTRS = ".zattrs"; + private static final String[] ZARR2_KEYS = new String[]{ZARRAY, ZGROUP, ZATTRS}; + private static final String Z3ATTRS = ".zattrs"; + private static final String N5_ATTRIBUTES = "attributes.json"; + + public static @Nullable StorageFormat guessStorageFromKeys(final URI root, final KeyValueAccess kva) { + final URI uri; + if (root.isAbsolute()) + uri = root; + else + uri = URI.create("file://" + root); + if (Arrays.stream(ZARR2_KEYS).anyMatch(it -> kva.exists(kva.compose(uri, it)))) + return StorageFormat.ZARR; + else if (kva.exists(kva.compose(uri, N5_ATTRIBUTES))) + return StorageFormat.N5; + else return null; + } +} diff --git a/src/test/java/org/janelia/saalfeldlab/n5/universe/N5FactoryTests.java b/src/test/java/org/janelia/saalfeldlab/n5/universe/N5FactoryTests.java index f84884a..de8ba69 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/universe/N5FactoryTests.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/universe/N5FactoryTests.java @@ -7,7 +7,6 @@ import org.janelia.saalfeldlab.n5.N5Writer; import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Reader; import org.janelia.saalfeldlab.n5.hdf5.N5HDF5Writer; -import org.janelia.saalfeldlab.n5.universe.N5Factory.StorageFormat; import org.janelia.saalfeldlab.n5.zarr.ZarrKeyValueReader; import org.janelia.saalfeldlab.n5.zarr.ZarrKeyValueWriter; import org.junit.Test; @@ -40,39 +39,39 @@ public void testStorageFormatGuesses() throws URISyntaxException { final URI zarrExtSlash = new URI("file:///tmp/a.zarr/"); final URI unknownExt = new URI("file:///tmp/a.abc"); - assertNull("no extension null", N5Factory.StorageFormat.guessStorageFromUri(noExt)); + assertNull("no extension null", StorageFormat.guessStorageFromUri(noExt)); /** * h5 tests fail now because these test whether the file exists. It * should not do that, if, for example, we're making a writer. */ - assertEquals("h5 extension == h5", StorageFormat.HDF5, N5Factory.StorageFormat.guessStorageFromUri(h5Ext)); - assertNotEquals("h5 extension != n5", StorageFormat.N5, N5Factory.StorageFormat.guessStorageFromUri(h5Ext)); - assertNotEquals("h5 extension != zarr", StorageFormat.ZARR, N5Factory.StorageFormat.guessStorageFromUri(h5Ext)); + assertEquals("h5 extension == h5", StorageFormat.HDF5, StorageFormat.guessStorageFromUri(h5Ext)); + assertNotEquals("h5 extension != n5", StorageFormat.N5, StorageFormat.guessStorageFromUri(h5Ext)); + assertNotEquals("h5 extension != zarr", StorageFormat.ZARR, StorageFormat.guessStorageFromUri(h5Ext)); - assertEquals("hdf5 extension == h5", StorageFormat.HDF5, N5Factory.StorageFormat.guessStorageFromUri(hdf5Ext)); - assertNotEquals("hdf5 extension != n5", StorageFormat.N5, N5Factory.StorageFormat.guessStorageFromUri(hdf5Ext)); - assertNotEquals("hdf5 extension != zarr", StorageFormat.ZARR, N5Factory.StorageFormat.guessStorageFromUri(hdf5Ext)); + assertEquals("hdf5 extension == h5", StorageFormat.HDF5, StorageFormat.guessStorageFromUri(hdf5Ext)); + assertNotEquals("hdf5 extension != n5", StorageFormat.N5, StorageFormat.guessStorageFromUri(hdf5Ext)); + assertNotEquals("hdf5 extension != zarr", StorageFormat.ZARR, StorageFormat.guessStorageFromUri(hdf5Ext)); - assertNotEquals("n5 extension != h5", StorageFormat.HDF5, N5Factory.StorageFormat.guessStorageFromUri(n5Ext)); - assertEquals("n5 extension == n5", StorageFormat.N5, N5Factory.StorageFormat.guessStorageFromUri(n5Ext)); - assertNotEquals("n5 extension != zarr", StorageFormat.ZARR, N5Factory.StorageFormat.guessStorageFromUri(n5Ext)); + assertNotEquals("n5 extension != h5", StorageFormat.HDF5, StorageFormat.guessStorageFromUri(n5Ext)); + assertEquals("n5 extension == n5", StorageFormat.N5, StorageFormat.guessStorageFromUri(n5Ext)); + assertNotEquals("n5 extension != zarr", StorageFormat.ZARR, StorageFormat.guessStorageFromUri(n5Ext)); - assertNotEquals("n5 extension slash != h5", StorageFormat.HDF5, N5Factory.StorageFormat.guessStorageFromUri(n5ExtSlash)); - assertEquals("n5 extension slash == n5", StorageFormat.N5, N5Factory.StorageFormat.guessStorageFromUri(n5ExtSlash)); - assertNotEquals("n5 extension slash != zarr", StorageFormat.ZARR, N5Factory.StorageFormat.guessStorageFromUri(n5ExtSlash)); + assertNotEquals("n5 extension slash != h5", StorageFormat.HDF5, StorageFormat.guessStorageFromUri(n5ExtSlash)); + assertEquals("n5 extension slash == n5", StorageFormat.N5, StorageFormat.guessStorageFromUri(n5ExtSlash)); + assertNotEquals("n5 extension slash != zarr", StorageFormat.ZARR, StorageFormat.guessStorageFromUri(n5ExtSlash)); - assertNotEquals("zarr extension != h5", StorageFormat.HDF5, N5Factory.StorageFormat.guessStorageFromUri(zarrExt)); - assertNotEquals("zarr extension != n5", StorageFormat.N5, N5Factory.StorageFormat.guessStorageFromUri(zarrExt)); - assertEquals("zarr extension == zarr", StorageFormat.ZARR, N5Factory.StorageFormat.guessStorageFromUri(zarrExt)); + assertNotEquals("zarr extension != h5", StorageFormat.HDF5, StorageFormat.guessStorageFromUri(zarrExt)); + assertNotEquals("zarr extension != n5", StorageFormat.N5, StorageFormat.guessStorageFromUri(zarrExt)); + assertEquals("zarr extension == zarr", StorageFormat.ZARR, StorageFormat.guessStorageFromUri(zarrExt)); - assertNotEquals("zarr extension slash != h5", StorageFormat.HDF5, N5Factory.StorageFormat.guessStorageFromUri(zarrExtSlash)); - assertNotEquals("zarr extension slash != n5", StorageFormat.N5, N5Factory.StorageFormat.guessStorageFromUri(zarrExtSlash)); - assertEquals("zarr extension slash == zarr", StorageFormat.ZARR, N5Factory.StorageFormat.guessStorageFromUri(zarrExtSlash)); + assertNotEquals("zarr extension slash != h5", StorageFormat.HDF5, StorageFormat.guessStorageFromUri(zarrExtSlash)); + assertNotEquals("zarr extension slash != n5", StorageFormat.N5, StorageFormat.guessStorageFromUri(zarrExtSlash)); + assertEquals("zarr extension slash == zarr", StorageFormat.ZARR, StorageFormat.guessStorageFromUri(zarrExtSlash)); - assertNull("unknown extension != h5", N5Factory.StorageFormat.guessStorageFromUri(unknownExt)); - assertNull("unknown extension != n5", N5Factory.StorageFormat.guessStorageFromUri(unknownExt)); - assertNull("unknown extension != zarr", N5Factory.StorageFormat.guessStorageFromUri(unknownExt)); + assertNull("unknown extension != h5", StorageFormat.guessStorageFromUri(unknownExt)); + assertNull("unknown extension != n5", StorageFormat.guessStorageFromUri(unknownExt)); + assertNull("unknown extension != zarr", StorageFormat.guessStorageFromUri(unknownExt)); } @Test @@ -192,10 +191,10 @@ public void testDefaultForAmbiguousWriters() throws IOException { final Class[] writerTypes = new Class[]{ null, N5HDF5Writer.class, - ZarrKeyValueWriter.class, - ZarrKeyValueWriter.class, - ZarrKeyValueWriter.class, - ZarrKeyValueWriter.class + ZarrKeyValueWriter.class, //valid zarr, correct by key match + N5KeyValueWriter.class, //valid n5, correct by key match + ZarrKeyValueWriter.class, // empty directory, create new zarr + ZarrKeyValueWriter.class //directory doesn't exist, create new zarr }; for (int i = 0; i < paths.length; i++) { diff --git a/src/test/java/org/janelia/saalfeldlab/n5/universe/N5StorageTests.java b/src/test/java/org/janelia/saalfeldlab/n5/universe/N5StorageTests.java index 33cb6e7..a143b56 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/universe/N5StorageTests.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/universe/N5StorageTests.java @@ -1,7 +1,6 @@ package org.janelia.saalfeldlab.n5.universe; import com.amazonaws.services.s3.AmazonS3; -import com.google.cloud.storage.Bucket; import com.google.cloud.storage.Storage; import com.google.gson.GsonBuilder; import org.janelia.saalfeldlab.n5.AbstractN5Test; @@ -58,9 +57,9 @@ public N5FactoryTest() { return factory; } - @Override public N5Factory.StorageFormat getStorageFormat() { + @Override public StorageFormat getStorageFormat() { - return N5Factory.StorageFormat.N5; + return StorageFormat.N5; } @Override protected N5Reader createN5Reader(String location, GsonBuilder gson) { diff --git a/src/test/java/org/janelia/saalfeldlab/n5/universe/StorageSchemeWrappedN5Test.java b/src/test/java/org/janelia/saalfeldlab/n5/universe/StorageSchemeWrappedN5Test.java index 0336647..9e8a38a 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/universe/StorageSchemeWrappedN5Test.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/universe/StorageSchemeWrappedN5Test.java @@ -17,7 +17,7 @@ public interface StorageSchemeWrappedN5Test { N5Factory getFactory(); - N5Factory.StorageFormat getStorageFormat(); + StorageFormat getStorageFormat(); Class getBackendTargetClass(); diff --git a/src/test/java/org/janelia/saalfeldlab/n5/universe/ZarrStorageTests.java b/src/test/java/org/janelia/saalfeldlab/n5/universe/ZarrStorageTests.java index 3f7f9a1..e35d105 100644 --- a/src/test/java/org/janelia/saalfeldlab/n5/universe/ZarrStorageTests.java +++ b/src/test/java/org/janelia/saalfeldlab/n5/universe/ZarrStorageTests.java @@ -1,7 +1,6 @@ package org.janelia.saalfeldlab.n5.universe; import com.amazonaws.services.s3.AmazonS3; -import com.google.cloud.storage.Bucket; import com.google.cloud.storage.Storage; import com.google.gson.GsonBuilder; import org.janelia.saalfeldlab.n5.FileSystemKeyValueAccess; @@ -55,9 +54,9 @@ public ZarrFactoryTest() { return factory; } - @Override public N5Factory.StorageFormat getStorageFormat() { + @Override public StorageFormat getStorageFormat() { - return N5Factory.StorageFormat.ZARR; + return StorageFormat.ZARR; } @Override protected N5Writer createN5Writer() {