sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1488774 - in /sis/branches/JDK7/storage/sis-storage/src: main/java/org/apache/sis/storage/DataStoreConnection.java test/java/org/apache/sis/storage/DataStoreConnectionTest.java
Date Sun, 02 Jun 2013 19:35:55 GMT
Author: desruisseaux
Date: Sun Jun  2 19:35:55 2013
New Revision: 1488774

URL: http://svn.apache.org/r1488774
Log:
More systematic creation of ByteBuffer, and leave the "rewind" operation to callers.

Modified:
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java
    sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreConnectionTest.java

Modified: sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java?rev=1488774&r1=1488773&r2=1488774&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java
[UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/DataStoreConnection.java
[UTF-8] Sun Jun  2 19:35:55 2013
@@ -30,6 +30,7 @@ import javax.imageio.stream.ImageInputSt
 import java.sql.Connection;
 import javax.sql.DataSource;
 import org.apache.sis.util.Classes;
+import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.storage.IOUtilities;
@@ -118,13 +119,6 @@ public class DataStoreConnection impleme
     private transient Map<Class<?>, Object> views;
 
     /**
-     * If an {@link ImageInputStream} vie exists, then the stream position at the time the
view has been initialized.
-     * This is usually zero, but could be different if the {@link #storage} provided by the
users is already an instance
-     * of {@code ImageInputStream}.
-     */
-    private transient long streamOrigin;
-
-    /**
      * The options, created only when first needed.
      *
      * @see #getOption(OptionKey)
@@ -234,11 +228,11 @@ public class DataStoreConnection impleme
      * The default implementation accepts the following types:
      *
      * <ul>
-     *   <li><p>{@link ByteBuffer}:
+     *   <li><p>{@link ByteBuffer} -
      *       A read-only view of the first bytes of the input stream, or {@code null} if
unavailable.
      *       If non-null, then the buffer can be used for a quick check of file magic number.</p></li>
      *
-     *   <li><p>{@link DataInput}:
+     *   <li><p>{@link DataInput} -
      *       Performs the following choice based on the type of the {@linkplain #getStorage()
storage} object:
      *       <ul>
      *         <li>If the storage is already an instance of {@link DataInput} (including
the {@link ImageInputStream}
@@ -255,7 +249,7 @@ public class DataStoreConnection impleme
      *         <li>Otherwise this method returns {@code null}.</li>
      *       </ul></p></li>
      *
-     *   <li><p>{@link Connection}:
+     *   <li><p>{@link Connection} -
      *       Performs the following choice based on the type of the {@linkplain #getStorage()
storage} object:
      *       <ul>
      *         <li>If the storage is already an instance of {@link Connection}, then
it is returned unchanged.</li>
@@ -267,9 +261,11 @@ public class DataStoreConnection impleme
      *       </ul></p></li>
      * </ul>
      *
-     * Callers shall not close the stream or database connection returned by this method.
Multiple invocations
-     * of this method on the same {@code DataStoreConnection} instance will try to return
the same instance on
-     * a <cite>best effort</cite> basis.
+     * Multiple invocations of this method on the same {@code DataStoreConnection} instance
will try
+     * to return the same instance on a <cite>best effort</cite> basis. Consequently,
implementations
+     * of {@link DataStoreProvider#canOpen(DataStoreConnection)} methods shall not close
the stream or
+     * database connection returned by this method. In addition, those {@code canOpen(DataStoreConnection)}
+     * methods are responsible for restoring the stream or byte buffer to its original position
on return.
      *
      * @param  <T>  The compile-time type of the {@code type} argument.
      * @param  type The desired type as one of {@code ByteBuffer}, {@code DataInput}, {@code
Connection}
@@ -320,8 +316,9 @@ public class DataStoreConnection impleme
 
     /**
      * Creates a view for the input as a {@link DataInput} if possible. This method performs
the choice
-     * documented in the {@link #openAs(Class)} method for the {@code DataInput} case, and
create the
-     * {@code ByteBuffer} in same time if possible.
+     * documented in the {@link #openAs(Class)} method for the {@code DataInput} case. Opening
the data
+     * input may imply creating a {@link ByteBuffer}, in which case the buffer will be stored
under the
+     * {@code ByteBuffer.class} key together with the {@code DataInput.class} case.
      *
      * @throws IOException If an error occurred while opening a stream for the input.
      */
@@ -338,12 +335,11 @@ public class DataStoreConnection impleme
              */
             final ReadableByteChannel channel = IOUtilities.open(storage, getOption(OptionKey.URL_ENCODING));
             if (channel != null) {
-                ByteBuffer buffer = getView(ByteBuffer.class);
+                ByteBuffer buffer = getOption(OptionKey.BYTE_BUFFER);
                 if (buffer == null) {
-                    buffer = getOption(OptionKey.BYTE_BUFFER);
-                    if (buffer == null) {
-                        buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
-                    }
+                    buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
+                    // TODO: we do not create direct buffer yet, but this is something
+                    // we may want to consider in a future SIS version.
                 }
                 asDataInput = new ChannelImageInputStream(getStorageName(), channel, buffer,
false);
                 asByteBuffer = buffer.asReadOnlyBuffer();
@@ -351,8 +347,24 @@ public class DataStoreConnection impleme
                 asDataInput = ImageIO.createImageInputStream(storage);
             }
         }
-        if (asDataInput instanceof ImageInputStream) {
-            streamOrigin = ((ImageInputStream) asDataInput).getStreamPosition();
+        /*
+         * If an ImageInputStream has been created without buffer, read an arbitrary amount
of bytes now
+         * so we can provide a ByteBuffer in case some user wants it. This may be a unnecessary
overhead
+         * since maybe no user will want to look at a ByteBuffer,  but this case is presumed
rare enough
+         * for not being worth a more complex "lazy instantiation" mechanism. We read only
a small amount
+         * of bytes because, at the contrary of the buffer created in the above block, the
buffer created
+         * here is unlikely to be used for the reading process after the recognition of the
file format.
+         */
+        if (asByteBuffer == null && asDataInput instanceof ImageInputStream) {
+            final ImageInputStream in = (ImageInputStream) asDataInput;
+            in.mark();
+            final byte[] buffer = new byte[256];
+            final int n = in.read(buffer);
+            in.reset();
+            if (n >= 1) {
+                asByteBuffer = ByteBuffer.wrap(ArraysExt.resize(buffer, n))
+                        .asReadOnlyBuffer().order(in.getByteOrder());
+            }
         }
         addView(ByteBuffer.class, asByteBuffer);
         addView(DataInput.class,  asDataInput);
@@ -405,38 +417,6 @@ public class DataStoreConnection impleme
     }
 
     /**
-     * Rewinds the {@link DataInput} and {@link ByteBuffer} to the beginning of the stream.
-     * This method is invoked when more than one {@link DataStore} instance is tried in search
-     * for a data store that accept this {@code DataStoreInput} instance.
-     *
-     * @throws DataStoreException If the stream is open but can not be rewinded.
-     */
-    public void rewind() throws DataStoreException {
-        if (views != null) {
-            /*
-             * Restores the ImageInputStream to its original position if possible. Note that
in
-             * the ChannelImageInputStream, this may reload the buffer content if necessary.
-             */
-            final DataInput asDataInput = getView(DataInput.class);
-            if (asDataInput instanceof ImageInputStream) try {
-                ((ImageInputStream) asDataInput).seek(streamOrigin);
-            } catch (IOException | IndexOutOfBoundsException e) {
-                throw new DataStoreException(Errors.format(Errors.Keys.StreamIsForwardOnly_1,
getStorageName()), e);
-            }
-            /*
-             * Copy the position and limits from the buffer. Note that this copy must be
performed after the
-             * above 'seek', because the seek operation may have modified the buffer position
and limit.
-             */
-            final ByteBuffer asByteBuffer = getView(ByteBuffer.class);
-            if (asByteBuffer != null && asDataInput instanceof ChannelImageInputStream)
{
-                final ByteBuffer buffer = ((ChannelImageInputStream) asDataInput).buffer;
-                asByteBuffer.clear().limit(buffer.limit()).position(buffer.position());
-                asByteBuffer.order(buffer.order());
-            }
-        }
-    }
-
-    /**
      * Closes all streams and connections created by this {@code DataStoreConnection} except
the given view.
      * This method closes all objects created by the {@link #openAs(Class)} method, leaving
only {@code view} open.
      * If {@code view} is {@code null}, then this method closes everything including the
{@linkplain #getStorage()

Modified: sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreConnectionTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreConnectionTest.java?rev=1488774&r1=1488773&r2=1488774&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreConnectionTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/DataStoreConnectionTest.java
[UTF-8] Sun Jun  2 19:35:55 2013
@@ -20,6 +20,7 @@ import java.io.DataInput;
 import java.io.IOException;
 import java.nio.channels.ReadableByteChannel;
 import org.apache.sis.internal.storage.ChannelImageInputStream;
+import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -34,6 +35,7 @@ import static org.opengis.test.Assert.*;
  * @version 0.3
  * @module
  */
+@DependsOn(org.apache.sis.internal.storage.ChannelImageInputStreamTest.class)
 public final strictfp class DataStoreConnectionTest extends TestCase {
     /**
      * The magic number of Java class files, used for verifying the content of our test file.



Mime
View raw message