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 <[email protected]>
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;

Reply via email to