sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1737107 [6/6] - in /sis/trunk: ./ application/sis-console/src/main/artifact/conf/ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ core/sis-metadata/src...
Date Wed, 30 Mar 2016 12:35:11 GMT
Modified: sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -27,9 +27,8 @@ import org.apache.sis.util.Debug;
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.7
  * @module
- *
  */
 final class Dimension {
     /**
@@ -38,12 +37,15 @@ final class Dimension {
     final String name;
 
     /**
-     * The number of grid cell value along that dimension, as an unsigned number.
+     * The number of grid cell value along this dimension, as an unsigned number.
      */
     final int length;
 
     /**
      * Creates a new dimension of the given name and length.
+     *
+     * @param name   The dimension name.
+     * @param length The number of grid cell value along this dimension, as an unsigned number.
      */
     Dimension(final String name, final int length) {
         this.name   = name;
@@ -51,11 +53,18 @@ final class Dimension {
     }
 
     /**
+     * Returns the number of grid cell value along this dimension.
+     */
+    final long length() {
+        return length & 0xFFFFFFFFL;
+    }
+
+    /**
      * A string representation of this dimension for debugging purpose only.
      */
     @Debug
     @Override
     public String toString() {
-        return name + '[' + (length & 0xFFFFFFFFL) + ']';
+        return name + '[' + length() + ']';
     }
 }

Modified: sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -23,8 +23,11 @@ import ucar.nc2.constants.CDM;
 import ucar.nc2.constants._Coordinate;
 import org.apache.sis.internal.netcdf.Variable;
 import org.apache.sis.internal.storage.ChannelDataInput;
+import org.apache.sis.internal.storage.HyperRectangleReader;
+import org.apache.sis.internal.storage.Region;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.Numbers;
 
 
 /**
@@ -33,7 +36,7 @@ import org.apache.sis.util.resources.Err
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.7
  * @module
  */
 final class VariableInfo extends Variable {
@@ -49,19 +52,31 @@ final class VariableInfo extends Variabl
     };
 
     /**
-     * The type of data. Number of bits and endianness are same as in the Java language
-     * except {@code CHAR}, which is defined as an unsigned 8-bits value.
+     * The NetCDF type of data. Number of bits and endianness are same as in the Java language except {@code CHAR},
+     * which is defined as an unsigned 8-bits value.
      */
     static final int BYTE=1, CHAR=2, SHORT=3, INT=4, FLOAT=5, DOUBLE=6;
 
     /**
+     * Mapping from the NetCDF data type to the enumeration used by our {@link Numbers} class.
+     */
+    private static final byte[] NUMBER_TYPES = new byte[] {
+        Numbers.BYTE,
+        Numbers.BYTE,       // NOT Numbers.CHARACTER
+        Numbers.SHORT,
+        Numbers.INTEGER,
+        Numbers.FLOAT,
+        Numbers.DOUBLE,
+    };
+
+    /**
      * The size in bytes of the above constants.
      *
      * @see #sizeOf(int)
      */
-    private static final int[] SIZES = new int[] {
+    private static final byte[] SIZES = new byte[] {
         Byte   .SIZE / Byte.SIZE,
-        Byte   .SIZE / Byte.SIZE, // NOT Java char
+        Byte   .SIZE / Byte.SIZE,      // NOT Character.BYTES
         Short  .SIZE / Byte.SIZE,
         Integer.SIZE / Byte.SIZE,
         Float  .SIZE / Byte.SIZE,
@@ -83,11 +98,10 @@ final class VariableInfo extends Variabl
     };
 
     /**
-     * The channel together with a buffer for reading the variable data.
-     *
-     * @see #read()
+     * Helper class for reading a sub-area with a sub-sampling,
+     * or {@code null} if {@code dataType} is not a supported type.
      */
-    private final ChannelDataInput input;
+    private final HyperRectangleReader reader;
 
     /**
      * The variable name.
@@ -95,7 +109,7 @@ final class VariableInfo extends Variabl
     private final String name;
 
     /**
-     * The dimensions of that variable.
+     * The dimensions of this variable.
      */
     final Dimension[] dimensions;
 
@@ -110,15 +124,9 @@ final class VariableInfo extends Variabl
     private final Map<String,Attribute> attributes;
 
     /**
-     * The type of data, as one of the {@code BYTE}, {@code SHORT} and similar constants defined
-     * in {@link ChannelDecoder}.
+     * The type of data, as one of the {@code BYTE}, {@code SHORT} and similar constants defined in this class.
      */
-    private final int datatype;
-
-    /**
-     * The offset where the variable data begins in the NetCDF file.
-     */
-    private final long offset;
+    private final int dataType;
 
     /**
      * The grid geometry associated to this variable,
@@ -128,22 +136,35 @@ final class VariableInfo extends Variabl
 
     /**
      * Creates a new variable.
+     *
+     * @param input         The channel together with a buffer for reading the variable data.
+     * @param name          The variable name.
+     * @param dimensions    The dimensions of this variable.
+     * @param allDimensions All dimensions in the NetCDF files.
+     * @param attributes    The attributes associates to the variable, or an empty map if none.
+     * @param dataType      The type of data, as one of the {@code BYTE} and similar constants defined in this class.
+     * @param size          The variable size, used for verification purpose only.
+     * @param offset        The offset where the variable data begins in the NetCDF file.
      */
     VariableInfo(final ChannelDataInput input, final String name,
             final Dimension[] dimensions, final Dimension[] allDimensions,
-            final Map<String,Attribute> attributes, final int datatype, final int size, final long offset)
+            final Map<String,Attribute> attributes, int dataType, final int size, final long offset)
+            throws DataStoreException
     {
-        this.input         = input;
         this.name          = name;
         this.dimensions    = dimensions;
         this.allDimensions = allDimensions;
         this.attributes    = attributes;
-        this.datatype      = datatype;
-        this.offset        = offset;
+        this.dataType      = dataType;
         /*
          * The 'size' value is provided in the NetCDF files, but doesn't need to be stored since it
          * is redundant with the dimension lengths and is not large enough for big variables anyway.
          */
+        if (--dataType >= 0 && dataType < NUMBER_TYPES.length) {
+            reader = new HyperRectangleReader(NUMBER_TYPES[dataType], input, offset);
+        } else {
+            reader = null;
+        }
     }
 
     /**
@@ -188,7 +209,7 @@ final class VariableInfo extends Variabl
      */
     @Override
     public Class<?> getDataType() {
-        final int i = datatype - 1;
+        final int i = dataType - 1;
         return (i >= 0 && i < TYPES.length) ? TYPES[i] : null;
     }
 
@@ -256,6 +277,8 @@ final class VariableInfo extends Variabl
     /**
      * Returns the length (number of cells) of each grid dimension. In ISO 19123 terminology, this method
      * returns the upper corner of the grid envelope plus one. The lower corner is always (0,0,…,0).
+     *
+     * @return The number of grid cells for each dimension, as unsigned integers.
      */
     @Override
     public int[] getGridEnvelope() {
@@ -285,6 +308,9 @@ final class VariableInfo extends Variabl
      */
     @Override
     public Object read() throws IOException, DataStoreException {
+        if (reader == null) {
+            throw new DataStoreException(unknownType());
+        }
         long length = 1;
         for (final Dimension dimension : dimensions) {
             length *= dimension.length;
@@ -292,14 +318,67 @@ final class VariableInfo extends Variabl
         if (length > Integer.MAX_VALUE) {
             throw new DataStoreException(Errors.format(Errors.Keys.ExcessiveListSize_2, name, length));
         }
-        input.seek(offset);
-        switch (datatype) {
-            case BYTE:   return input.readBytes  ((int) length);
-            case SHORT:  return input.readShorts ((int) length);
-            case INT:    return input.readInts   ((int) length);
-            case FLOAT:  return input.readFloats ((int) length);
-            case DOUBLE: return input.readDoubles((int) length);
-            default: throw new DataStoreException(Errors.format(Errors.Keys.UnknownType_1, datatype));
+        final int dimension = dimensions.length;
+        final long[] size  = new long[dimension];
+        final int [] sub   = new int [dimension];
+        for (int i=0; i<dimension; i++) {
+            sub [i] = 1;
+            size[i] = dimensions[(dimension - 1) - i].length();
+        }
+        return reader.read(new Region(size, new long[dimension], size, sub));
+    }
+
+    /**
+     * Reads a sub-sampled sub-area of the variable.
+     *
+     * @param  areaLower   Index of the first value to read along each dimension, as unsigned integers.
+     * @param  areaUpper   Index after the last value to read along each dimension, as unsigned integers.
+     * @param  subsampling Sub-sampling along each dimension. 1 means no sub-sampling.
+     * @return The data as an array of a Java primitive type.
+     */
+    @Override
+    public Object read(int[] areaLower, int[] areaUpper, int[] subsampling) throws IOException, DataStoreException {
+        if (reader == null) {
+            throw new DataStoreException(unknownType());
         }
+        /*
+         * NetCDF sorts datas in reverse dimension order. Example:
+         *
+         * DIMENSIONS:
+         *   time: 3
+         *   lat : 2
+         *   lon : 4
+         *
+         * VARIABLES:
+         *   temperature (time,lat,lon)
+         *
+         * DATA INDICES:
+         *   (0,0,0) (0,0,1) (0,0,2) (0,0,3)
+         *   (0,1,0) (0,1,1) (0,1,2) (0,1,3)
+         *   (1,0,0) (1,0,1) (1,0,2) (1,0,3)
+         *   (1,1,0) (1,1,1) (1,1,2) (1,1,3)
+         *   (2,0,0) (2,0,1) (2,0,2) (2,0,3)
+         *   (2,1,0) (2,1,1) (2,1,2) (2,1,3)
+         */
+        final int dimension = dimensions.length;
+        final long[] size  = new long[dimension];
+        final long[] lower = new long[dimension];
+        final long[] upper = new long[dimension];
+        final int [] sub   = new int [dimension];
+        for (int i=0; i<dimension; i++) {
+            final int j = (dimension - 1) - i;
+            lower[i] = areaLower[j] & 0xFFFFFFFFL;
+            upper[i] = areaUpper[j] & 0xFFFFFFFFL;
+            sub  [i] = subsampling[j];
+            size [i] = dimensions[j].length();
+        }
+        return reader.read(new Region(size, lower, upper, sub));
+    }
+
+    /**
+     * Returns the error message for an unknown data type.
+     */
+    private String unknownType() {
+        return Errors.format(Errors.Keys.UnknownType_1, "NetCDF:" + dataType);
     }
 }

Modified: sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -19,18 +19,22 @@ package org.apache.sis.internal.netcdf.u
 import java.util.List;
 import java.io.IOException;
 import ucar.ma2.Array;
+import ucar.ma2.Section;
+import ucar.ma2.InvalidRangeException;
 import ucar.nc2.Attribute;
 import ucar.nc2.Dimension;
 import ucar.nc2.VariableIF;
 import org.apache.sis.internal.netcdf.Variable;
+import org.apache.sis.storage.DataStoreException;
 
 
 /**
  * A {@link Variable} backed by the UCAR NetCDF library.
  *
  * @author  Martin Desruisseaux (Geomatys)
+ * @author  Johann Sorel (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.7
  * @module
  */
 final class VariableWrapper extends Variable {
@@ -181,4 +185,29 @@ final class VariableWrapper extends Vari
         final Array array = variable.read();
         return array.get1DJavaArray(array.getElementType());
     }
+
+    /**
+     * Reads a sub-sampled sub-area of the variable.
+     *
+     * @param  areaLower   Index of the first value to read along each dimension.
+     * @param  areaUpper   Index after the last value to read along each dimension.
+     * @param  subsampling Sub-sampling along each dimension. 1 means no sub-sampling.
+     * @return The data as an array of a Java primitive type.
+     */
+    @Override
+    public Object read(final int[] areaLower, final int[] areaUpper, final int[] subsampling)
+            throws IOException, DataStoreException
+    {
+        final int[] size = new int[areaUpper.length];
+        for (int i=0; i<size.length; i++) {
+            size[i] = areaUpper[i] - areaLower[i];
+        }
+        final Array array;
+        try {
+            array = variable.read(new Section(areaLower, size, subsampling));
+        } catch (InvalidRangeException e) {
+            throw new DataStoreException(e);
+        }
+        return array.get1DJavaArray(array.getElementType());
+    }
 }

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -18,6 +18,7 @@ package org.apache.sis.internal.netcdf;
 
 import java.util.Date;
 import java.io.IOException;
+import org.apache.sis.storage.DataStoreException;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
@@ -40,10 +41,11 @@ public strictfp class DecoderTest extend
     /**
      * Tests {@link Decoder#stringValue(String)} with global attributes.
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testStringValue() throws IOException {
+    public void testStringValue() throws IOException, DataStoreException {
         selectDataset(NCEP);
         assertAttributeEquals("Sea Surface Temperature Analysis Model",      TITLE);
         assertAttributeEquals("NCEP SST Global 5.0 x 2.5 degree model data", SUMMARY);
@@ -63,10 +65,11 @@ public strictfp class DecoderTest extend
     /**
      * Tests {@link Decoder#numericValue(String)} with global attributes.
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testNumericValue() throws IOException {
+    public void testNumericValue() throws IOException, DataStoreException {
         selectDataset(NCEP);
         assertAttributeEquals(Double.valueOf( -90), LATITUDE .MINIMUM);
         assertAttributeEquals(Double.valueOf( +90), LATITUDE .MAXIMUM);
@@ -80,10 +83,11 @@ public strictfp class DecoderTest extend
     /**
      * Tests {@link Decoder#dateValue(String)} with global attributes.
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testDateValue() throws IOException {
+    public void testDateValue() throws IOException, DataStoreException {
         selectDataset(NCEP);
         assertAttributeEquals(date("2005-09-22 00:00:00"), DATE_CREATED);
         assertAttributeEquals((Date) null,                 DATE_MODIFIED);
@@ -92,10 +96,11 @@ public strictfp class DecoderTest extend
     /**
      * Tests {@link Decoder#numberToDate(String, Number[])}.
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testNumberToDate() throws IOException {
+    public void testNumberToDate() throws IOException, DataStoreException {
         final Decoder decoder = selectDataset(NCEP);
         assertArrayEquals(new Date[] {
             date("2005-09-22 00:00:00")

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.netcdf;
 
 import java.io.IOException;
+import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.netcdf.AttributeNames;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.DependsOnMethod;
@@ -55,10 +56,11 @@ public strictfp class GridGeometryTest e
     /**
      * Tests {@link GridGeometry#getSourceDimensions()} and {@link GridGeometry#getTargetDimensions()}.
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testDimensions() throws IOException {
+    public void testDimensions() throws IOException, DataStoreException {
         final GridGeometry geometry = getSingleton(filter(selectDataset(NCEP).getGridGeometries()));
         assertEquals("getSourceDimensions()", 3, geometry.getSourceDimensions());
         assertEquals("getTargetDimensions()", 3, geometry.getTargetDimensions());
@@ -67,11 +69,12 @@ public strictfp class GridGeometryTest e
     /**
      * Tests {@link GridGeometry#getAxes()}.
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
     @DependsOnMethod("testDimensions")
-    public void testAxes() throws IOException {
+    public void testAxes() throws IOException, DataStoreException {
         final Axis[] axes = getSingleton(filter(selectDataset(NCEP).getGridGeometries())).getAxes();
         assertEquals(3, axes.length);
         final Axis x = axes[2];

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -22,6 +22,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.io.IOException;
 import java.lang.reflect.UndeclaredThrowableException;
+import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.util.logging.EmptyWarningListeners;
 import org.apache.sis.internal.netcdf.ucar.DecoderWrapper;
 import org.apache.sis.internal.system.Modules;
@@ -101,9 +102,10 @@ public abstract strictfp class TestCase
      *
      * @param  name The file name as one of the above-cited constants.
      * @return The decoder for the given name.
-     * @throws IOException If an error occurred while opening the file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
-    protected Decoder createDecoder(final String name) throws IOException {
+    protected Decoder createDecoder(final String name) throws IOException, DataStoreException {
         return new DecoderWrapper(LISTENERS, new NetcdfDataset(open(name)));
     }
 
@@ -117,9 +119,10 @@ public abstract strictfp class TestCase
      *
      * @param  name The file name as one of the constants enumerated in the {@link #createDecoder(String)} method.
      * @return The decoder for the given name.
-     * @throws IOException If an error occurred while opening the file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
-    protected final Decoder selectDataset(final String name) throws IOException {
+    protected final Decoder selectDataset(final String name) throws IOException, DataStoreException {
         synchronized (DECODERS) { // Paranoiac safety, but should not be used in multi-threads environment.
             decoder = DECODERS.get(name);
             if (decoder == null) {
@@ -136,7 +139,7 @@ public abstract strictfp class TestCase
      * Invoked after all tests in a class have been executed.
      * This method closes all NetCDF files.
      *
-     * @throws IOException If an error occurred while closing a file.
+     * @throws IOException if an error occurred while closing a file.
      */
     @AfterClass
     public static void closeAllDecoders() throws IOException {
@@ -182,7 +185,7 @@ public abstract strictfp class TestCase
      *
      * @param  expected      The expected attribute value.
      * @param  attributeName The name of the attribute to test.
-     * @throws IOException   If an error occurred while reading the NetCDF file.
+     * @throws IOException   if an error occurred while reading the NetCDF file.
      */
     protected final void assertAttributeEquals(final String expected, final String attributeName) throws IOException {
         assertEquals(attributeName, expected, decoder.stringValue(attributeName));

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -57,10 +57,11 @@ public strictfp class VariableTest exten
      *   <li>{@link Variable#isUnsigned()}</li>
      * </ul>
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testBasicProperties() throws IOException {
+    public void testBasicProperties() throws IOException, DataStoreException {
         assertBasicPropertiesEqual(new Object[] {
         // __name______________description_________________________________datatype____dim__axis?__raster?
             "reftime",        "reference time",                            double.class, 1, false, false,
@@ -122,10 +123,11 @@ public strictfp class VariableTest exten
      * Tests {@link Variable#getGridDimensionNames()} and {@link Variable#getGridEnvelope()}.
      * Current implementation tests on the {@code "SST"} variable.
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testGridDimensions() throws IOException {
+    public void testGridDimensions() throws IOException, DataStoreException {
         final Variable variable = selectDataset(NCEP).getVariables()[21];
         assertEquals("SST", variable.getName());
 
@@ -141,10 +143,11 @@ public strictfp class VariableTest exten
     /**
      * Tests {@link Variable#getAttributeValues(String, boolean)}.
      *
-     * @throws IOException If an error occurred while reading the NetCDF file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testGetAttributes() throws IOException {
+    public void testGetAttributes() throws IOException, DataStoreException {
         final Variable[] variables = selectDataset(NCEP).getVariables();
         Variable variable = variables[9];
         assertEquals("grid_number", variable.getName());

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -46,10 +46,11 @@ public final strictfp class ChannelDecod
      * Creates a new decoder for dataset of the given name.
      *
      * @return The decoder for the given name.
-     * @throws IOException If an error occurred while opening the file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Override
-    protected Decoder createDecoder(final String name) throws IOException {
+    protected Decoder createDecoder(final String name) throws IOException, DataStoreException {
         return createChannelDecoder(name);
     }
 
@@ -66,18 +67,15 @@ public final strictfp class ChannelDecod
      *
      * @param  name The file name as one of the above-cited constants.
      * @return The decoder for the given name.
-     * @throws IOException If an error occurred while opening the file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
-    public static Decoder createChannelDecoder(final String name) throws IOException {
+    public static Decoder createChannelDecoder(final String name) throws IOException, DataStoreException {
         final InputStream in = IOTestCase.class.getResourceAsStream(name);
         assumeNotNull(name, in);
         final ChannelDataInput input = new ChannelDataInput(name,
                 Channels.newChannel(in), ByteBuffer.allocate(4096), false);
-        try {
-            return new ChannelDecoder(LISTENERS, input);
-        } catch (DataStoreException e) {
-            throw new AssertionError(e);
-        }
+        return new ChannelDecoder(LISTENERS, input);
     }
 
     /**

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -20,6 +20,7 @@ import java.io.IOException;
 import org.apache.sis.internal.netcdf.Decoder;
 import org.apache.sis.internal.netcdf.GridGeometry;
 import org.apache.sis.internal.netcdf.GridGeometryTest;
+import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.test.DependsOn;
 
@@ -40,10 +41,11 @@ public final strictfp class GridGeometry
      * Creates a new decoder for dataset of the given name.
      *
      * @return The decoder for the given name.
-     * @throws IOException If an error occurred while opening the file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Override
-    protected Decoder createDecoder(final String name) throws IOException {
+    protected Decoder createDecoder(final String name) throws IOException, DataStoreException {
         return ChannelDecoderTest.createChannelDecoder(name);
     }
 

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -19,6 +19,7 @@ package org.apache.sis.internal.netcdf.i
 import java.io.IOException;
 import org.apache.sis.internal.netcdf.Decoder;
 import org.apache.sis.internal.netcdf.VariableTest;
+import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.test.DependsOn;
 
 
@@ -38,10 +39,11 @@ public final strictfp class VariableInfo
      * Creates a new decoder for dataset of the given name.
      *
      * @return The decoder for the given dataset.
-     * @throws IOException If an error occurred while opening the file.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Override
-    protected Decoder createDecoder(final String name) throws IOException {
+    protected Decoder createDecoder(final String name) throws IOException, DataStoreException {
         return ChannelDecoderTest.createChannelDecoder(name);
     }
 

Modified: sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -25,6 +25,7 @@ import org.apache.sis.internal.netcdf.IO
 import org.apache.sis.internal.netcdf.ucar.DecoderWrapper;
 import org.apache.sis.internal.netcdf.impl.ChannelDecoderTest;
 import org.apache.sis.metadata.iso.DefaultMetadata;
+import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
@@ -50,10 +51,11 @@ public final strictfp class MetadataRead
      * Reads the metadata using the NetCDF decoder embedded with SIS,
      * and compares its string representation with the expected one.
      *
-     * @throws IOException Should never happen.
+     * @throws IOException if an I/O error occurred while opening the file.
+     * @throws DataStoreException if a logical error occurred.
      */
     @Test
-    public void testEmbedded() throws IOException {
+    public void testEmbedded() throws IOException, DataStoreException {
         final Metadata metadata;
         final Decoder input = ChannelDecoderTest.createChannelDecoder(NCEP);
         try {

Modified: sis/trunk/storage/sis-storage/pom.xml
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/pom.xml?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/pom.xml (original)
+++ sis/trunk/storage/sis-storage/pom.xml Wed Mar 30 12:35:10 2016
@@ -121,6 +121,12 @@ Provides the interfaces and base classes
            Dependencies
        =========================================================== -->
   <dependencies>
+    <dependency>
+      <groupId>org.apache.sis.core</groupId>
+      <artifactId>sis-feature</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
     <!-- Test dependencies -->
     <dependency>
       <groupId>org.apache.sis.core</groupId>

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -222,7 +222,7 @@ public abstract class ChannelData {
         final int n = (int) (position - bufferOffset);
         final int p = buffer.position() - n;
         final int r = buffer.limit() - n;
-        flushAndSetPosition(n); // Number of bytes to forget.
+        flushAndSetPosition(n);                             // Number of bytes to forget.
         buffer.compact().position(p).limit(r);
         /*
          * Discard trailing obsolete marks. Note that obsolete marks between valid marks
@@ -242,7 +242,7 @@ public abstract class ChannelData {
     }
 
     /**
-     * Writes (if applicable) the buffer content up to the given position, then set the buffer position
+     * Writes (if applicable) the buffer content up to the given position, then sets the buffer position
      * to the given value. The {@linkplain ByteBuffer#limit() buffer limit} is unchanged, and the buffer
      * offset is incremented by the given value.
      */
@@ -327,6 +327,9 @@ public abstract class ChannelData {
     @Debug
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[“" + filename + "” at " + getStreamPosition() + ']';
+        final StringBuilder b = new StringBuilder().append(getClass().getSimpleName()).append("[“").append(filename).append('”');
+        // Even if the buffer should not be null, it is useful to keep the toString() method robust.
+        if (buffer != null) b.append(" at ").append(getStreamPosition());
+        return b.append(']').toString();
     }
 }

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -28,6 +28,7 @@ import java.nio.FloatBuffer;
 import java.nio.DoubleBuffer;
 import java.nio.channels.ReadableByteChannel;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.Debug;
 
 import static org.apache.sis.util.ArgumentChecks.ensureBetween;
 
@@ -60,7 +61,7 @@ import java.nio.channels.FileChannel;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.7
  * @module
  */
 public class ChannelDataInput extends ChannelData {
@@ -265,7 +266,7 @@ public class ChannelDataInput extends Ch
      * The implementation is as below:
      *
      * {@preformat java
-     *     return readByte() & 0xFF;
+     *     return Byte.toUnsignedInt(readByte());
      * }
      *
      * @return The value of the next unsigned byte from the stream.
@@ -293,7 +294,7 @@ public class ChannelDataInput extends Ch
      * The implementation is as below:
      *
      * {@preformat java
-     *     return readShort() & 0xFFFF;
+     *     return Short.toUnsignedInt(readShort());
      * }
      *
      * @return The value of the next unsigned short from the stream.
@@ -334,7 +335,7 @@ public class ChannelDataInput extends Ch
      * The implementation is as below:
      *
      * {@preformat java
-     *     return readInt() & 0xFFFFFFFFL;
+     *     return Integer.toUnsignedLong(readInt());
      * }
      *
      * @return The value of the next unsigned integer from the stream.
@@ -519,13 +520,21 @@ public class ChannelDataInput extends Ch
      * Helper class for the {@code readFully(…)} methods,
      * in order to avoid duplicating almost identical code many times.
      */
-    private abstract class ArrayReader {
+    abstract class ArrayReader implements DataTransfer {
         /**
-         * Creates a new buffer of the type required by the array to fill.
-         * This method is guaranteed to be invoked exactly once, after the
-         * {@link ChannelDataInput#buffer} contains enough data.
+         * For subclass constructors only.
          */
-        abstract Buffer createView();
+        ArrayReader() {
+        }
+
+        /**
+         * Returns a file identifier for error messages or debugging purpose.
+         */
+        @Debug
+        @Override
+        public final String filename() {
+            return filename;
+        }
 
         /**
          * Transfers the data from the buffer created by {@link #createView()} to array
@@ -543,31 +552,186 @@ public class ChannelDataInput extends Ch
         }
 
         /**
-         * Reads {@code length} characters from the stream, and stores them into the array
-         * known to subclass, starting at index {@code offset}.
+         * Moves to the given position in the stream.
+         */
+        @Override
+        public final void seek(long n) throws IOException {
+            ChannelDataInput.this.seek(n);
+        }
+
+        /**
+         * Reads {@code length} values from the stream, and stores them into the array known to subclass,
+         * starting at index {@code offset}.
          *
-         * @param  dataSize The size of the Java primitive type which is the element of the array.
+         * <p>If a non-null {@code Buffer} is given in argument to this method, then it must be a view over
+         * the full content of {@link ChannelDataInput#buffer} (i.e. the view element at index 0 shall be
+         * defined by the buffer elements starting at index 0).</p>
+         *
+         * @param  view     Existing buffer to use as a view over {@link ChannelDataInput#buffer}, or {@code null}.
          * @param  offset   The starting position within {@code dest} to write.
-         * @param  length   The number of characters to read.
-         * @throws IOException If an error (including EOF) occurred while reading the stream.
+         * @param  length   The number of values to read.
+         * @throws IOException if an error (including EOF) occurred while reading the stream.
          */
-        final void readFully(final int dataSize, int offset, int length) throws IOException {
-            ensureBufferContains(Math.min(length * dataSize, buffer.capacity()));
-            final Buffer view = createView(); // Must be after ensureBufferContains
+        @Override
+        public void readFully(Buffer view, int offset, int length) throws IOException {
+            final int dataSizeShift = dataSizeShift();
+            ensureBufferContains(Math.min(length << dataSizeShift, buffer.capacity()));
+            if (view == null) {
+                view = createView();                                    // Must be after ensureBufferContains(int).
+            } else {
+                // Buffer position must be a multiple of the data size.
+                // If not, fix that by shifting the content to index 0.
+                if ((buffer.position() & ((1 << dataSizeShift) - 1)) != 0) {
+                    bufferOffset += buffer.position();
+                    buffer.compact().flip();
+                }
+                view.limit   (buffer.limit()    >> dataSizeShift)
+                    .position(buffer.position() >> dataSizeShift);      // See assumption documented in Javadoc.
+            }
             int n = Math.min(view.remaining(), length);
             transfer(offset, n);
-            skipInBuffer(n * dataSize);
+            skipInBuffer(n << dataSizeShift);
             while ((length -= n) != 0) {
                 offset += n;
-                ensureBufferContains(dataSize); // Actually read as much data as possible.
-                view.rewind().limit(buffer.remaining() / dataSize);
+                ensureBufferContains(1 << dataSizeShift);               // Actually read as much data as possible.
+                view.rewind().limit(buffer.remaining() >> dataSizeShift);
                 transfer(offset, n = Math.min(view.remaining(), length));
-                skipInBuffer(n * dataSize);
+                skipInBuffer(n << dataSizeShift);
             }
         }
     }
 
     /**
+     * Reads bytes from the enclosing stream and stores them into the given destination array. This implementation
+     * actually redirects the reading process to {@link ChannelDataInput#readFully(byte[], int, int)} because this
+     * specialization does not need a view. This implementation is useless for {@code ChannelDataInput}, but avoid
+     * the need to implement special cases in other classes like {@link HyperRectangleReader}.
+     */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final class BytesReader extends ArrayReader {
+        /** The array where to store the values. */      private byte[] dest;
+        BytesReader(final byte[] dest)                  {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 0;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return buffer;}
+        @Override public Buffer createView()            {return buffer;}
+        @Override public void   createDataArray(int n)  {dest = new byte[n];}
+        @Override        void   transfer(int p, int n)  {buffer.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (byte[]) array;};
+        @Override public void readFully(Buffer view, int offset, int length) throws IOException {
+            ChannelDataInput.this.readFully(dest, offset, length);
+        }
+    };
+
+    /**
+     * Reads characters from the enclosing stream and stores them into the given destination array.
+     */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final class CharsReader extends ArrayReader {
+        /** A view over the enclosing byte buffer. */    private CharBuffer view;
+        /** The array where to store the values.   */    private char[] dest;
+        CharsReader(final CharBuffer source)            {this.view = source;}
+        CharsReader(final char[] dest)                  {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 1;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asCharBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new char[n];}
+        @Override        void   transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (char[]) array;};
+    };
+
+    /**
+     * Reads short integers from the enclosing stream and stores them into the given destination array.
+     */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final class ShortsReader extends ArrayReader {
+        /** A view over the enclosing byte buffer. */    private ShortBuffer view;
+        /** The array where to store the values.   */    private short[] dest;
+        ShortsReader(final ShortBuffer source)          {this.view = source;}
+        ShortsReader(final short[] dest)                {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 1;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asShortBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new short[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (short[]) array;};
+    };
+
+    /**
+     * Reads integers from the enclosing stream and stores them into the given destination array.
+     */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final class IntsReader extends ArrayReader {
+        /** A view over the enclosing byte buffer. */    private IntBuffer view;
+        /** The array where to store the values.   */    private int[] dest;
+        IntsReader(final IntBuffer source)              {this.view = source;}
+        IntsReader(final int[] dest)                    {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 2;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asIntBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new int[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (int[]) array;};
+    };
+
+    /**
+     * Reads long integers from the enclosing stream and stores them into the given destination array.
+     */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final class LongsReader extends ArrayReader {
+        /** A view over the enclosing byte buffer. */    private LongBuffer view;
+        /** The array where to store the values.   */    private long[] dest;
+        LongsReader(final LongBuffer source)            {this.view = source;}
+        LongsReader(final long[] dest)                  {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 3;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asLongBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new long[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (long[]) array;};
+    };
+
+    /**
+     * Reads float values from the enclosing stream and stores them into the given destination array.
+     */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final class FloatsReader extends ArrayReader {
+        /** A view over the enclosing byte buffer. */    private FloatBuffer view;
+        /** The array where to store the values.   */    private float[] dest;
+        FloatsReader(final FloatBuffer source)          {this.view = source;}
+        FloatsReader(final float[] dest)                {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 2;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asFloatBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new float[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (float[]) array;};
+    };
+
+    /**
+     * Reads double values from the enclosing stream and stores them into the given destination array.
+     */
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
+    final class DoublesReader extends ArrayReader {
+        /** A view over the enclosing byte buffer. */    private DoubleBuffer view;
+        /** The array where to store the values.   */    private double[] dest;
+        DoublesReader(final DoubleBuffer source)        {this.view = source;}
+        DoublesReader(final double[] dest)              {this.dest = dest;}
+        @Override public int    dataSizeShift()         {return 3;}
+        @Override public Object dataArray()             {return dest;}
+        @Override public Buffer view()                  {return view;}
+        @Override public Buffer createView()            {return view = buffer.asDoubleBuffer();}
+        @Override public void   createDataArray(int n)  {dest = new double[n];}
+        @Override void          transfer(int p, int n)  {view.get(dest, p, n);}
+        @Override public void   setDest(Object array)   {dest = (double[]) array;};
+    };
+
+    /**
      * Reads {@code length} characters from the stream, and stores them into
      * {@code dest} starting at index {@code offset}.
      *
@@ -577,11 +741,7 @@ public class ChannelDataInput extends Ch
      * @throws IOException If an error (including EOF) occurred while reading the stream.
      */
     public final void readFully(final char[] dest, final int offset, final int length) throws IOException {
-        new ArrayReader() {
-            private CharBuffer view;
-            @Override Buffer createView() {return view = buffer.asCharBuffer();}
-            @Override void transfer(int offset, int n) {view.get(dest, offset, n);}
-        }.readFully(Character.SIZE / Byte.SIZE, offset, length);
+        new CharsReader(dest).readFully(null, offset, length);
     }
 
     /**
@@ -594,11 +754,7 @@ public class ChannelDataInput extends Ch
      * @throws IOException If an error (including EOF) occurred while reading the stream.
      */
     public final void readFully(final short[] dest, final int offset, final int length) throws IOException {
-        new ArrayReader() {
-            private ShortBuffer view;
-            @Override Buffer createView() {return view = buffer.asShortBuffer();}
-            @Override void transfer(int offset, int n) {view.get(dest, offset, n);}
-        }.readFully(Short.SIZE / Byte.SIZE, offset, length);
+        new ShortsReader(dest).readFully(null, offset, length);
     }
 
     /**
@@ -611,11 +767,7 @@ public class ChannelDataInput extends Ch
      * @throws IOException If an error (including EOF) occurred while reading the stream.
      */
     public final void readFully(final int[] dest, final int offset, final int length) throws IOException {
-        new ArrayReader() {
-            private IntBuffer view;
-            @Override Buffer createView() {return view = buffer.asIntBuffer();}
-            @Override void transfer(int offset, int n) {view.get(dest, offset, n);}
-        }.readFully(Integer.SIZE / Byte.SIZE, offset, length);
+        new IntsReader(dest).readFully(null, offset, length);
     }
 
     /**
@@ -628,11 +780,7 @@ public class ChannelDataInput extends Ch
      * @throws IOException If an error (including EOF) occurred while reading the stream.
      */
     public final void readFully(final long[] dest, final int offset, final int length) throws IOException {
-        new ArrayReader() {
-            private LongBuffer view;
-            @Override Buffer createView() {return view = buffer.asLongBuffer();}
-            @Override void transfer(int offset, int n) {view.get(dest, offset, n);}
-        }.readFully(Long.SIZE / Byte.SIZE, offset, length);
+        new LongsReader(dest).readFully(null, offset, length);
     }
 
     /**
@@ -645,11 +793,7 @@ public class ChannelDataInput extends Ch
      * @throws IOException If an error (including EOF) occurred while reading the stream.
      */
     public final void readFully(final float[] dest, final int offset, final int length) throws IOException {
-        new ArrayReader() {
-            private FloatBuffer view;
-            @Override Buffer createView() {return view = buffer.asFloatBuffer();}
-            @Override void transfer(int offset, int n) {view.get(dest, offset, n);}
-        }.readFully(Float.SIZE / Byte.SIZE, offset, length);
+        new FloatsReader(dest).readFully(null, offset, length);
     }
 
     /**
@@ -662,11 +806,7 @@ public class ChannelDataInput extends Ch
      * @throws IOException If an error (including EOF) occurred while reading the stream.
      */
     public final void readFully(final double[] dest, final int offset, final int length) throws IOException {
-        new ArrayReader() {
-            private DoubleBuffer view;
-            @Override Buffer createView() {return view = buffer.asDoubleBuffer();}
-            @Override void transfer(int offset, int n) {view.get(dest, offset, n);}
-        }.readFully(Double.SIZE / Byte.SIZE, offset, length);
+        new DoublesReader(dest).readFully(null, offset, length);
     }
 
     /**

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java?rev=1737107&r1=1737105&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -33,10 +33,6 @@ import javax.measure.unit.Unit;
 import javax.measure.unit.SI;
 import javax.measure.unit.NonSI;
 import javax.measure.quantity.Duration;
-import org.opengis.feature.Feature;
-import org.opengis.feature.FeatureType;
-import org.opengis.feature.PropertyType;
-import org.opengis.feature.AttributeType;
 import org.opengis.metadata.Metadata;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -62,6 +58,8 @@ import org.apache.sis.util.resources.Ind
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk8.Instant;
+import org.apache.sis.feature.AbstractFeature;
+import org.apache.sis.feature.AbstractIdentifiedType;
 
 
 /**
@@ -135,14 +133,14 @@ public final class Store extends DataSto
      *
      * @see #parseFeatureType(List)
      */
-    private final FeatureType featureType;
+    private final DefaultFeatureType featureType;
 
     /**
      * The features created while parsing the CSV file.
      *
      * @todo We should not keep them in memory, but instead use some kind of iterator or stream.
      */
-    private final List<Feature> features;
+    private final List<AbstractFeature> features;
 
     /**
      * {@code true} if {@link #featureType} contains a trajectory column.
@@ -178,9 +176,9 @@ public final class Store extends DataSto
             throw new DataStoreException(Errors.format(Errors.Keys.CanNotOpen_1, name));
         }
         source = (r instanceof BufferedReader) ? (BufferedReader) r : new LineNumberReader(r);
-        GeneralEnvelope envelope    = null;
-        FeatureType     featureType = null;
-        Foliation       foliation   = null;
+        GeneralEnvelope envelope = null;
+        DefaultFeatureType featureType = null;
+        Foliation foliation = null;
         try {
             final List<String> elements = new ArrayList<String>();
             source.mark(1024);
@@ -234,7 +232,7 @@ public final class Store extends DataSto
         this.featureType = featureType;
         this.foliation   = foliation;
         this.metadata    = MetadataHelper.createForTextFile(connector);
-        this.features    = new ArrayList<Feature>();
+        this.features    = new ArrayList<AbstractFeature>();
     }
 
     /**
@@ -370,9 +368,9 @@ public final class Store extends DataSto
      * @param  elements The line elements. The first elements should be {@code "@columns"}.
      * @return The column metadata, or {@code null} if the given list does not contain enough elements.
      */
-    private FeatureType parseFeatureType(final List<String> elements) throws DataStoreException {
+    private DefaultFeatureType parseFeatureType(final List<String> elements) throws DataStoreException {
         final int size = elements.size();
-        final List<PropertyType> properties = new ArrayList<PropertyType>();
+        final List<AbstractIdentifiedType> properties = new ArrayList<AbstractIdentifiedType>();
         for (int i=1; i<size; i++) {
             final String name = elements.get(i);
             Class<?> type = null;
@@ -432,13 +430,13 @@ public final class Store extends DataSto
             properties.add(createProperty(name, type, minOccurrence));
         }
         return new DefaultFeatureType(Collections.singletonMap(DefaultFeatureType.NAME_KEY, name),
-                false, null, properties.toArray(new PropertyType[properties.size()]));
+                false, null, properties.toArray(new AbstractIdentifiedType[properties.size()]));
     }
 
     /**
      * Creates a property type for the given name and type.
      */
-    private static PropertyType createProperty(final String name, final Class<?> type, final int minOccurrence) {
+    private static AbstractIdentifiedType createProperty(final String name, final Class<?> type, final int minOccurrence) {
         return new DefaultAttributeType(Collections.singletonMap(DefaultAttributeType.NAME_KEY, name), type, minOccurrence, 1, null);
     }
 
@@ -490,23 +488,23 @@ public final class Store extends DataSto
      * @throws DataStoreException if an error occurred while creating the iterator.
      */
     @SuppressWarnings({"unchecked", "rawtypes", "fallthrough"})
-    public Iterator<Feature> getFeatures() throws DataStoreException {
+    public Iterator<AbstractFeature> getFeatures() throws DataStoreException {
         if (features.isEmpty()) try {
-            final Collection<? extends PropertyType> properties = featureType.getProperties(false);
+            final Collection<? extends AbstractIdentifiedType> properties = featureType.getProperties(false);
             final ObjectConverter<String,?>[] converters = new ObjectConverter[properties.size()];
             final String[]     propertyNames   = new String[converters.length];
             final boolean      hasTrajectories = this.hasTrajectories;
             final TimeEncoding timeEncoding    = this.timeEncoding;
             final List<String> values          = new ArrayList<String>();
             int i = -1;
-            for (final PropertyType p : properties) {
+            for (final AbstractIdentifiedType p : properties) {
                 propertyNames[++i] = p.getName().tip().toString();
                 switch (i) {    // This switch shall follow the same cases than the swith in the loop.
                     case 1:
                     case 2: if (timeEncoding != null) continue;     // else fall through
                     case 3: if (hasTrajectories) continue;
                 }
-                converters[i] = ObjectConverters.find(String.class, ((AttributeType) p).getValueClass());
+                converters[i] = ObjectConverters.find(String.class, ((DefaultAttributeType) p).getValueClass());
             }
             /*
              * Above lines prepared the constants. Now parse all lines.
@@ -517,7 +515,7 @@ public final class Store extends DataSto
                 split(line, values);
                 final int length = Math.min(propertyNames.length, values.size());
                 if (length != 0) {
-                    final Feature feature = featureType.newInstance();
+                    final AbstractFeature feature = featureType.newInstance();
                     for (i=0; i<length; i++) {
                         final String text = values.get(i);
                         final String name = propertyNames[i];

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -144,14 +144,14 @@ final class Store extends DataStore {
     public Metadata getMetadata() throws DataStoreException {
         if (metadata == null) {
             parse();
-            DefaultMetadata d = null;
+            DefaultMetadata md = null;
             for (final Object object : objects) {
                 if (object instanceof ReferenceSystem) {
-                    if (d == null) d = new DefaultMetadata();
-                    d.getReferenceSystemInfo().add((ReferenceSystem) object);
+                    if (md == null) md = new DefaultMetadata();
+                    md.getReferenceSystemInfo().add((ReferenceSystem) object);
                 }
             }
-            metadata = d;
+            metadata = md;
         }
         return metadata;
     }

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -180,9 +180,9 @@ final class Store extends DataStore {
             if (object instanceof Metadata) {
                 metadata = (Metadata) object;
             } else if (object instanceof ReferenceSystem) {
-                final DefaultMetadata d = new DefaultMetadata();
-                d.setReferenceSystemInfo(singleton((ReferenceSystem) object));
-                metadata = d;
+                final DefaultMetadata md = new DefaultMetadata();
+                md.setReferenceSystemInfo(singleton((ReferenceSystem) object));
+                metadata = md;
             }
         }
         return metadata;

Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -39,6 +39,7 @@ import javax.sql.DataSource;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.ObjectConverters;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.storage.IOUtilities;
 import org.apache.sis.internal.storage.ChannelDataInput;
@@ -361,8 +362,8 @@ public class StorageConnector implements
      * @param  type The desired type as one of {@code ByteBuffer}, {@code DataInput}, {@code Connection}
      *         class or other type supported by {@code StorageConnector} subclasses.
      * @return The storage as a view of the given type, or {@code null} if no view can be created for the given type.
-     * @throws IllegalArgumentException If the given {@code type} argument is not a known type.
-     * @throws DataStoreException If an error occurred while opening a stream or database connection.
+     * @throws IllegalArgumentException if the given {@code type} argument is not a supported type.
+     * @throws DataStoreException if an error occurred while opening a stream or database connection.
      *
      * @see #getStorage()
      * @see #closeAllExcept(Object)
@@ -441,7 +442,7 @@ public class StorageConnector implements
      * If the view can not be created, remember that fact in order to avoid new attempts.
      *
      * @param  asImageInputStream If the {@code ChannelDataInput} needs to be {@link ChannelImageInputStream} subclass.
-     * @throws IOException If an error occurred while opening a channel for the input.
+     * @throws IOException if an error occurred while opening a channel for the input.
      */
     private void createChannelDataInput(final boolean asImageInputStream) throws IOException {
         /*
@@ -486,7 +487,7 @@ public class StorageConnector implements
      * 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.
+     * @throws IOException if an error occurred while opening a stream for the input.
      */
     private void createDataInput() throws IOException {
         final DataInput asDataInput;
@@ -525,7 +526,7 @@ public class StorageConnector implements
      * of bytes read from the input. This amount is not sufficient, it can be increased by a call
      * to {@link #prefetch()}.
      *
-     * @throws IOException If an error occurred while opening a stream for the input.
+     * @throws IOException if an error occurred while opening a stream for the input.
      */
     private void createByteBuffer() throws IOException, DataStoreException {
         /*
@@ -571,7 +572,7 @@ public class StorageConnector implements
      * for {@link DataStoreProvider#probeContent(StorageConnector)} purpose.</p>
      *
      * @return {@code true} on success.
-     * @throws DataStoreException If an error occurred while reading more bytes.
+     * @throws DataStoreException if an error occurred while reading more bytes.
      */
     final boolean prefetch() throws DataStoreException {
         try {
@@ -608,8 +609,8 @@ public class StorageConnector implements
      *
      * @param  type The type of the view to create.
      * @return The storage as a view of the given type, or {@code null} if no view can be created for the given type.
-     * @throws IllegalArgumentException If the given {@code type} argument is not a known type.
-     * @throws Exception If an error occurred while opening a stream or database connection.
+     * @throws IllegalArgumentException if the given {@code type} argument is not a supported type.
+     * @throws Exception if an error occurred while opening a stream or database connection.
      */
     private Object createView(final Class<?> type) throws IllegalArgumentException, Exception {
         if (type == String.class) {
@@ -676,7 +677,7 @@ public class StorageConnector implements
             }
             return null;
         }
-        throw new IllegalArgumentException(Errors.format(Errors.Keys.UnknownType_1, type));
+        return ObjectConverters.convert(storage, type);
     }
 
     /**
@@ -734,7 +735,7 @@ public class StorageConnector implements
      * <p>This {@code StorageConnector} instance shall not be used anymore after invocation of this method.</p>
      *
      * @param  view The view to leave open, or {@code null} if none.
-     * @throws DataStoreException If an error occurred while closing the stream or database connection.
+     * @throws DataStoreException if an error occurred while closing the stream or database connection.
      *
      * @see #getStorageAs(Class)
      * @see DataStoreProvider#open(StorageConnector)

Modified: sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -32,7 +32,7 @@ import java.nio.channels.ByteChannel;
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.7
  * @module
  *
  * @see ChannelDataOutputTest
@@ -64,9 +64,14 @@ final strictfp class ByteArrayChannel im
      * Creates a channel which will store all written data in the given array.
      *
      * @param data Bytes array where to write the data. The length of this array is the capacity.
+     * @param isContentValid {@code true} if the channel should be initialized with all the {@code data} elements,
+     *        or {@code false} if the channel should be considered initially empty.
      */
-    ByteArrayChannel(final byte[] data) {
+    ByteArrayChannel(final byte[] data, final boolean isDataValid) {
         this.data = data;
+        if (isDataValid) {
+            limit = data.length;
+        }
     }
 
     /**
@@ -80,6 +85,7 @@ final strictfp class ByteArrayChannel im
         }
         final int length = StrictMath.min(dst.remaining(), limit - position);
         dst.put(data, position, length);
+        position += length;
         return length;
     }
 

Modified: sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -82,7 +82,7 @@ public strictfp class ChannelDataOutputT
         referenceStream          = new DataOutputStream(expectedData);
         testedStreamBackingArray = new byte[streamLength];
         testedStream             = new ChannelDataOutput(testName,
-                new ByteArrayChannel(testedStreamBackingArray), ByteBuffer.allocate(bufferLength));
+                new ByteArrayChannel(testedStreamBackingArray, false), ByteBuffer.allocate(bufferLength));
     }
 
     /**

Modified: sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -48,7 +48,7 @@ public final strictfp class ChannelImage
         referenceStream          = new MemoryCacheImageOutputStream(expectedData);
         testedStreamBackingArray = new byte[streamLength];
         testedStream             = new ChannelImageOutputStream(fileName,
-                new ByteArrayChannel(testedStreamBackingArray), ByteBuffer.allocate(bufferLength));
+                new ByteArrayChannel(testedStreamBackingArray, false), ByteBuffer.allocate(bufferLength));
     }
 
     /**

Modified: sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java?rev=1737107&r1=1737105&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -18,7 +18,6 @@ package org.apache.sis.internal.storage.
 
 import java.util.Iterator;
 import java.io.StringReader;
-import org.opengis.feature.Feature;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.metadata.extent.SpatialTemporalExtent;
@@ -30,6 +29,11 @@ import org.junit.Test;
 import static org.junit.Assert.*;
 import static org.apache.sis.test.TestUtilities.getSingleton;
 
+// Branch-dependent imports
+import org.apache.sis.feature.AbstractFeature;
+import org.apache.sis.metadata.iso.extent.DefaultSpatialTemporalExtent;
+import org.apache.sis.metadata.iso.identification.AbstractIdentification;
+
 
 /**
  * Tests {@link Store}.
@@ -67,14 +71,14 @@ public final class StoreTest extends Tes
         } finally {
             store.close();
         }
-        final SpatialTemporalExtent extent = (SpatialTemporalExtent) getSingleton(getSingleton(getSingleton(
-                metadata.getIdentificationInfo()).getExtents()).getTemporalElements());
+        final AbstractIdentification id = (AbstractIdentification) getSingleton(metadata.getIdentificationInfo());
+        final SpatialTemporalExtent extent = (SpatialTemporalExtent) getSingleton(getSingleton(id.getExtents()).getTemporalElements());
         final GeographicBoundingBox bbox = (GeographicBoundingBox) getSingleton(extent.getSpatialExtent());
         assertEquals("westBoundLongitude", 50.23, bbox.getWestBoundLongitude(), STRICT);
         assertEquals("eastBoundLongitude", 50.31, bbox.getEastBoundLongitude(), STRICT);
         assertEquals("southBoundLatitude",  9.23, bbox.getSouthBoundLatitude(), STRICT);
         assertEquals("northBoundLatitude",  9.27, bbox.getNorthBoundLatitude(), STRICT);
-        assertNull("Should not have a vertical extent.", extent.getVerticalExtent());
+        assertNull("Should not have a vertical extent.", ((DefaultSpatialTemporalExtent) extent).getVerticalExtent());
         assertNotNull("Should have a temporal extent", extent.getExtent());
     }
 
@@ -87,7 +91,7 @@ public final class StoreTest extends Tes
     public void testGetFeatures() throws DataStoreException {
         Store store = new Store(new StorageConnector(new StringReader(TEST_DATA)));
         try {
-            final Iterator<Feature> it = store.getFeatures();
+            final Iterator<AbstractFeature> it = store.getFeatures();
             assertFeatureEquals(it.next(), "a", new double[] {11, 2, 12, 3},        "walking", 1);
             assertFeatureEquals(it.next(), "b", new double[] {10, 2, 11, 3},        "walking", 2);
             assertFeatureEquals(it.next(), "a", new double[] {12, 3, 10, 3},        "walking", 2);
@@ -101,7 +105,7 @@ public final class StoreTest extends Tes
     /**
      * Asserts that the given feature has the given properties.
      */
-    private static void assertFeatureEquals(final Feature f, final String mfidref,
+    private static void assertFeatureEquals(final AbstractFeature f, final String mfidref,
             final double[] trajectory, final String state, final int typeCode)
     {
         assertEquals     ("mfidref",    mfidref,  f.getPropertyValue("mfidref"));

Modified: sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java?rev=1737107&r1=1737106&r2=1737107&view=diff
==============================================================================
--- sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java [UTF-8] (original)
+++ sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java [UTF-8] Wed Mar 30 12:35:10 2016
@@ -35,6 +35,7 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.storage.ChannelDataOutputTest.class,
     org.apache.sis.internal.storage.ChannelImageInputStreamTest.class,
     org.apache.sis.internal.storage.ChannelImageOutputStreamTest.class,
+    org.apache.sis.internal.storage.HyperRectangleReaderTest.class,
     org.apache.sis.storage.ProbeResultTest.class,
     org.apache.sis.storage.StorageConnectorTest.class,
     org.apache.sis.internal.storage.xml.MimeTypeDetectorTest.class,
@@ -42,6 +43,7 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.storage.xml.StoreTest.class,
     org.apache.sis.internal.storage.wkt.StoreProviderTest.class,
     org.apache.sis.internal.storage.wkt.StoreTest.class,
+    org.apache.sis.internal.storage.csv.StoreTest.class,
     org.apache.sis.storage.DataStoresTest.class,
     org.apache.sis.index.GeoHashCoderTest.class
 })



Mime
View raw message