You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by am...@apache.org on 2021/03/11 14:37:34 UTC

[sis] 01/03: refactor(Storage): change NetCDF content probing to use strict storage connector.

This is an automated email from the ASF dual-hosted git repository.

amanin pushed a commit to branch refactor/strict_storage_connector
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 5aec53e8ddcf8b7f8f94a6c842f7b0203cca13d2
Author: Alexis Manin <al...@geomatys.com>
AuthorDate: Thu Mar 11 09:54:40 2021 +0100

    refactor(Storage): change NetCDF content probing to use strict storage connector.
---
 .../sis/storage/netcdf/NetcdfStoreProvider.java    | 33 ++++++++++++++++------
 .../apache/sis/storage/StrictStorageConnector.java |  9 ++++++
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
index 5c8a60a..e954c0b 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
@@ -26,6 +26,8 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.UndeclaredThrowableException;
+import org.apache.sis.storage.StrictStorageConnector;
+import org.apache.sis.storage.UnsupportedStorageException;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.apache.sis.internal.netcdf.Decoder;
 import org.apache.sis.internal.netcdf.Resources;
@@ -179,21 +181,33 @@ public class NetcdfStoreProvider extends DataStoreProvider {
      */
     @Override
     public ProbeResult probeContent(final StorageConnector connector) throws DataStoreException {
+        return probeContentStrict(new StrictStorageConnector(connector));
+    }
+
+    private ProbeResult probeContentStrict(final StrictStorageConnector connector) throws DataStoreException {
         int     version     = 0;
         boolean hasVersion  = false;
         boolean isSupported = false;
-        final ByteBuffer buffer = connector.getStorageAs(ByteBuffer.class);
-        if (buffer != null) {
-            if (buffer.remaining() < Integer.BYTES) {
-                return ProbeResult.INSUFFICIENT_BYTES;
-            }
-            final int header = buffer.getInt(buffer.position());
-            if ((header & 0xFFFFFF00) == ChannelDecoder.MAGIC_NUMBER) {
+        try {
+            Integer header = connector.useAsBuffer(buffer -> {
+                if (buffer.remaining() < Integer.BYTES) {
+                    return null;
+                }
+                return buffer.getInt(buffer.position());
+            });
+
+            if (header == null)  return ProbeResult.INSUFFICIENT_BYTES;
+            else if ((header & 0xFFFFFF00) == ChannelDecoder.MAGIC_NUMBER) {
                 hasVersion  = true;
                 version     = header & 0xFF;
                 isSupported = (version >= 1 && version <= ChannelDecoder.MAX_VERSION);
             }
+        } catch (UnsupportedStorageException e) {
+            // Can happen on special inputs, in which case we'll fallback on UCAR driver
+        } catch (IOException e) {
+            throw new DataStoreException("Storage usage error", e);
         }
+
         /*
          * If we failed to check using the embedded decoder, tries using the UCAR library.
          * The UCAR library is an optional dependency. If that library is present and the
@@ -204,7 +218,7 @@ public class NetcdfStoreProvider extends DataStoreProvider {
          * has special cases for "file:", "http:", "nodods:" and "slurp:" protocols.
          */
         if (!isSupported) {
-            final String path = connector.getStorageAs(String.class);
+            final String path = connector.getPathAsString().orElse(null);
             if (path != null) {
                 ensureInitialized(false);
                 final Method method = canOpenFromPath;
@@ -235,7 +249,8 @@ public class NetcdfStoreProvider extends DataStoreProvider {
                  * We check classnames instead of netcdfFileClass.isInstance(storage)
                  * in order to avoid loading the UCAR library if not needed.
                  */
-                for (Class<?> type = connector.getStorage().getClass(); type != null; type = type.getSuperclass()) {
+                final Class<?> baseStorageType = connector.unsafe().getStorage().getClass();
+                for (Class<?> type = baseStorageType; type != null; type = type.getSuperclass()) {
                     if (UCAR_CLASSNAME.equals(type.getName())) {
                         isSupported = true;
                         break;
diff --git a/storage/sis-storage/src/main/java/org/apache/sis/storage/StrictStorageConnector.java b/storage/sis-storage/src/main/java/org/apache/sis/storage/StrictStorageConnector.java
index 34f4e8e..906c0f7 100644
--- a/storage/sis-storage/src/main/java/org/apache/sis/storage/StrictStorageConnector.java
+++ b/storage/sis-storage/src/main/java/org/apache/sis/storage/StrictStorageConnector.java
@@ -252,6 +252,15 @@ public class StrictStorageConnector implements AutoCloseable {
         storage.closeAllExcept(committedStorage);
     }
 
+    /**
+     *
+     * @return A connector that does not provides control over resource usage. It does not automatically rewind
+     * automatically used resources. That means that resource lifecycle becomes <em>entirely</em> caller responsability.
+     */
+    public StorageConnector unsafe() {
+        return storage;
+    }
+
     private interface StorageCallable<V> extends Callable<V> {
         @Override
         V call() throws IOException, DataStoreException;