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

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 623a7f3d2340be0df4c73775dcc0d10275eaa56a
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Mon Apr 11 12:19:41 2022 +0200

    Complete `StorageConnector` with `DataOutput` and `OutputStream` for 
consistency.
---
 .../org/apache/sis/storage/StorageConnector.java   | 70 +++++++++++++++++++++-
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
index a9de16c43f..3fd18f6bed 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
@@ -22,7 +22,9 @@ import java.util.Collections;
 import java.util.IdentityHashMap;
 import java.io.Reader;
 import java.io.DataInput;
+import java.io.DataOutput;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.IOException;
 import java.io.LineNumberReader;
 import java.io.InputStreamReader;
@@ -35,6 +37,7 @@ import java.nio.channels.WritableByteChannel;
 import java.nio.channels.SeekableByteChannel;
 import java.nio.file.NoSuchFileException;
 import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
 import javax.imageio.ImageIO;
 import java.sql.Connection;
 import java.sql.SQLException;
@@ -56,6 +59,7 @@ import org.apache.sis.internal.storage.io.ChannelFactory;
 import org.apache.sis.internal.storage.io.ChannelDataInput;
 import org.apache.sis.internal.storage.io.ChannelDataOutput;
 import org.apache.sis.internal.storage.io.ChannelImageInputStream;
+import org.apache.sis.internal.storage.io.ChannelImageOutputStream;
 import org.apache.sis.internal.storage.io.InputStreamAdapter;
 import org.apache.sis.internal.storage.io.RewindableLineReader;
 import org.apache.sis.internal.storage.io.InternalOptionKey;
@@ -181,13 +185,15 @@ public class StorageConnector implements Serializable {
      * of those types. This map shall contain every types documented in {@link 
#getStorageAs(Class)} javadoc.
      * {@code null} values means to use {@link ObjectConverters} for that 
particular type.
      */
-    private static final Map<Class<?>, Opener<?>> OPENERS = new 
IdentityHashMap<>(13);
+    private static final Map<Class<?>, Opener<?>> OPENERS = new 
IdentityHashMap<>(16);
     static {
         add(String.class,            StorageConnector::createString);
         add(ByteBuffer.class,        StorageConnector::createByteBuffer);
         add(DataInput.class,         StorageConnector::createDataInput);
+        add(DataOutput.class,        StorageConnector::createDataOutput);
         add(ImageInputStream.class,  StorageConnector::createImageInputStream);
         add(InputStream.class,       StorageConnector::createInputStream);
+        add(OutputStream.class,      StorageConnector::createOutputStream);
         add(Reader.class,            StorageConnector::createReader);
         add(Connection.class,        StorageConnector::createConnection);
         add(ChannelDataInput.class,  (s) -> s.createChannelDataInput(false));  
 // Undocumented case (SIS internal)
@@ -994,6 +1000,8 @@ public class StorageConnector implements Serializable {
      * {@code StorageConnector} instance.</p>
      *
      * @throws IOException if an error occurred while opening a stream for the 
input.
+     *
+     * @see #createDataOutput()
      */
     private DataInput createDataInput() throws IOException, DataStoreException 
{
         /*
@@ -1177,11 +1185,13 @@ public class StorageConnector implements Serializable {
     }
 
     /**
-     * Creates an input stream from {@link ReadableByteChannel} if possible, 
or from {@link ImageInputStream}
-     * otherwise.
+     * Creates an input stream from {@link ReadableByteChannel} if possible,
+     * or from {@link ImageInputStream} otherwise.
      *
      * <p>This method is one of the {@link #OPENERS} methods and should be 
invoked at most once per
      * {@code StorageConnector} instance.</p>
+     *
+     * @see #createOutputStream()
      */
     private InputStream createInputStream() throws IOException, 
DataStoreException {
         final Class<DataInput> source = DataInput.class;
@@ -1260,6 +1270,7 @@ public class StorageConnector implements Serializable {
 
     /**
      * Creates a view for the storage as a {@link ChannelDataOutput} if 
possible.
+     * This code is a partial copy of {@link #createDataInput()} adapted for 
output.
      *
      * @throws IOException if an error occurred while opening a channel for 
the output.
      *
@@ -1303,6 +1314,59 @@ public class StorageConnector implements Serializable {
         return asDataOutput;
     }
 
+    /**
+     * Creates a view for the output as a {@link DataOutput} if possible.
+     * This code is a copy of {@link #createDataInput()} adapted for output.
+     *
+     * @throws IOException if an error occurred while opening a stream for the 
output.
+     *
+     * @see #createDataInput()
+     */
+    private DataOutput createDataOutput() throws IOException, 
DataStoreException {
+        Coupled c = getView(ChannelDataOutput.class);
+        final ChannelDataOutput out;
+        if (reset(c)) {
+            out = (ChannelDataOutput) c.view;
+        } else {
+            out = createChannelDataOutput();                        // May be 
null.
+        }
+        final DataOutput asDataOutput;
+        if (out != null) {
+            c = getView(ChannelDataOutput.class);                   // May 
have been added by createChannelDataOutput(…).
+            if (out instanceof DataOutput) {
+                asDataOutput = (DataOutput) out;
+            } else {
+                asDataOutput = new ChannelImageOutputStream(out);   // Upgrade 
existing instance.
+                c.view = asDataOutput;
+            }
+            views.put(DataOutput.class, c);                         // Share 
the same Coupled instance.
+        } else {
+            reset();
+            asDataOutput = ImageIO.createImageOutputStream(storage);
+            addView(DataOutput.class, asDataOutput, null, (byte) 
(CASCADE_ON_RESET | CASCADE_ON_CLOSE));
+        }
+        return asDataOutput;
+    }
+
+    /**
+     * Creates an output stream from {@link WritableByteChannel} if possible,
+     * or from {@link ImageOutputStream} otherwise.
+     * This code is a partial copy of {@link #createInputStream()} adapted for 
output.
+     *
+     * @see #createInputStream()
+     */
+    private OutputStream createOutputStream() throws IOException, 
DataStoreException {
+        final Class<DataOutput> target = DataOutput.class;
+        final DataOutput output = getStorageAs(target);
+        if (output instanceof OutputStream) {
+            views.put(OutputStream.class, views.get(target));                  
 // Share the same Coupled instance.
+            return (OutputStream) output;
+        } else {
+            addView(OutputStream.class, null);                                 
 // Remember that there is no view.
+            return null;
+        }
+    }
+
     /**
      * Adds the given view in the cache together with information about its 
dependency.
      * For example {@link InputStreamReader} is a wrapper for a {@link 
InputStream}: read operations

Reply via email to