sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1737101 [6/7] - in /sis/branches/JDK6: ./ 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-meta...
Date Wed, 30 Mar 2016 11:25:07 GMT
Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/XMLTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/XMLTestCase.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/XMLTestCase.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/XMLTestCase.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -161,15 +161,22 @@ public abstract strictfp class XMLTestCa
 
     /**
      * Returns the URL to the XML file of the given name.
-     * The file shall be in the same package than the final subclass of {@code this}.
+     * The file shall be in the same package than a subclass of {@code this}.
+     * This method begins the search in the package of {@link #getClass()}.
+     * If the resource is not found in that package, then this method searches in the parent classes.
+     * The intend is to allow some test classes to be overridden in different modules.
      *
      * @param  filename The name of the XML file.
      * @return The URL to the given XML file.
      */
     private URL getResource(final String filename) {
-        final URL resource = getClass().getResource(filename);
-        assertNotNull(filename, resource);
-        return resource;
+        Class<?> c = getClass();
+        do {
+            final URL resource = c.getResource(filename);
+            if (resource != null) return resource;
+            c = c.getSuperclass();
+        } while (!c.equals(XMLTestCase.class));
+        throw new AssertionError("Test resource not found: " + filename);
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/ExceptionsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/ExceptionsTest.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/ExceptionsTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/util/ExceptionsTest.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -17,6 +17,7 @@
 package org.apache.sis.util;
 
 import java.util.Locale;
+import java.io.IOException;
 import java.io.FileNotFoundException;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -32,7 +33,7 @@ import org.apache.sis.internal.jdk7.JDK7
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 public final strictfp class ExceptionsTest extends TestCase {
@@ -43,7 +44,7 @@ public final strictfp class ExceptionsTe
     public void testFormatChainedMessages() {
         final String lineSeparator = JDK7.lineSeparator();
         final FileNotFoundException cause = new FileNotFoundException("MisingFile.txt");
-        cause.initCause(new Exception("Disk is not mounted."));
+        cause.initCause(new IOException("Disk is not mounted."));
         final Exception e = new Exception("Can not find “MisingFile.txt”.", cause);
         /*
          * The actual sequence of messages (with their cause is):
@@ -54,15 +55,17 @@ public final strictfp class ExceptionsTe
          *
          * But the second line shall be omitted because it duplicates the first line.
          */
+        String message = Exceptions.formatChainedMessages(Locale.ENGLISH, null, e);
         assertEquals("Can not find “MisingFile.txt”." + lineSeparator +
-                     "Disk is not mounted.",
-                     Exceptions.formatChainedMessages(Locale.ENGLISH, null, e));
+                     "Caused by IOException: Disk is not mounted.",
+                     message);
         /*
          * Test again with a header.
          */
+        message = Exceptions.formatChainedMessages(Locale.ENGLISH, "Error while creating the data store.", e);
         assertEquals("Error while creating the data store." + lineSeparator +
-                     "Can not find “MisingFile.txt”." + lineSeparator +
-                     "Disk is not mounted.",
-                     Exceptions.formatChainedMessages(Locale.ENGLISH, "Error while creating the data store.", e));
+                     "Caused by Exception: Can not find “MisingFile.txt”." + lineSeparator +
+                     "Caused by IOException: Disk is not mounted.",
+                     message);
     }
 }

Modified: sis/branches/JDK6/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/pom.xml?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/pom.xml (original)
+++ sis/branches/JDK6/pom.xml Wed Mar 30 11:25:06 2016
@@ -574,7 +574,7 @@ Apache SIS is a free software, Java lang
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
-        <version>2.5.4</version>
+        <version>2.5.4</version>                                <!-- Last version compatible with JDK6. -->
         <extensions>true</extensions>
         <configuration>
           <excludeDependencies>true</excludeDependencies>
@@ -693,7 +693,7 @@ Apache SIS is a free software, Java lang
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>findbugs-maven-plugin</artifactId>
-        <version>2.5.3</version>
+        <version>3.0.3</version>
         <dependencies>
           <dependency>
             <groupId>org.apache.sis.core</groupId>
@@ -710,12 +710,12 @@ Apache SIS is a free software, Java lang
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
-          <version>1.9.1</version>
+          <version>1.9.1</version>                              <!-- Last version compatible with JDK6. -->
         </plugin>
         <plugin>
           <groupId>org.mortbay.jetty</groupId>
           <artifactId>jetty-maven-plugin</artifactId>
-          <version>8.1.16.v20140903</version>           <!-- Versions 9.0.* require JDK 7 -->
+          <version>8.1.16.v20140903</version>                   <!-- Versions 9.0.* require JDK 7 -->
         </plugin>
       </plugins>
     </pluginManagement>

Modified: sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -27,8 +27,9 @@ import org.apache.sis.util.Debug;
  * A NetCDF variable created by {@link Decoder}.
  *
  * @author  Martin Desruisseaux (Geomatys)
+ * @author  Johann Sorel (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.7
  * @module
  */
 public abstract class Variable {
@@ -151,7 +152,7 @@ public abstract class Variable {
      * @return {@code true} if the variable can be considered a coverage.
      */
     public final boolean isCoverage(final int minSpan) {
-        int numVectors = 0; // Number of dimension having more than 1 value.
+        int numVectors = 0;                                     // Number of dimension having more than 1 value.
         for (final int length : getGridEnvelope()) {
             if ((length & 0xFFFFFFFFL) >= minSpan) {
                 numVectors++;
@@ -164,9 +165,8 @@ public abstract class Variable {
     }
 
     /**
-     * Returns {@code true} if this variable seems to be a coordinate system axis instead than
-     * the actual data. By NetCDF convention, coordinate system axes have the name of one of the
-     * dimensions defined in the NetCDF header.
+     * Returns {@code true} if this variable seems to be a coordinate system axis instead than the actual data.
+     * By NetCDF convention, coordinate system axes have the name of one of the dimensions defined in the NetCDF header.
      *
      * @return {@code true} if this variable seems to be a coordinate system axis.
      */
@@ -206,12 +206,31 @@ public abstract class Variable {
      * Reads all the data for this variable and returns them as an array of a Java primitive type.
      *
      * @return The data as an array of a Java primitive type.
-     * @throws IOException If an error occurred while reading the data.
-     * @throws DataStoreException If a logical error occurred.
+     * @throws IOException if an error occurred while reading the data.
+     * @throws DataStoreException if a logical error occurred.
      */
     public abstract Object read() throws IOException, DataStoreException;
 
     /**
+     * Reads a sub-sampled sub-area of the variable.
+     * Constraints on the argument values are:
+     *
+     * <ul>
+     *   <li>All arrays length shall be equal to the length of the {@link #getGridEnvelope()} array.</li>
+     *   <li>For each index <var>i</var>, value of {@code area[i]} shall be in the range from 0 inclusive
+     *       to {@code Integer.toUnsignedLong(getGridEnvelope()[i])} exclusive.</li>
+     * </ul>
+     *
+     * @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.
+     * @throws IOException if an error occurred while reading the data.
+     * @throws DataStoreException if a logical error occurred.
+     */
+    public abstract Object read(int[] areaLower, int[] areaUpper, int[] subsampling) throws IOException, DataStoreException;
+
+    /**
      * Returns a string representation of this variable for debugging purpose.
      *
      * @return A string representation of this variable.

Modified: sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -683,6 +683,7 @@ public final class ChannelDecoder extend
      * @throws IOException {@inheritDoc}
      */
     @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
     public Variable[] getVariables() throws IOException {
         return variables;
     }
@@ -695,6 +696,7 @@ public final class ChannelDecoder extend
      * @throws IOException {@inheritDoc}
      */
     @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
     public GridGeometry[] getGridGeometries() throws IOException {
         if (gridGeometries == null) {
             /*

Modified: sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java [UTF-8] Wed Mar 30 11:25:06 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;
@@ -102,9 +103,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)));
     }
 
@@ -118,9 +120,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) {
@@ -137,7 +140,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 {
@@ -183,7 +186,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/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java [UTF-8] Wed Mar 30 11:25:06 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);
         assertNotNull(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/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -25,6 +25,7 @@ import org.apache.sis.internal.netcdf.De
 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/branches/JDK6/storage/sis-storage/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-storage/pom.xml?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-storage/pom.xml (original)
+++ sis/branches/JDK6/storage/sis-storage/pom.xml Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelData.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java?rev=1737101&r1=1737089&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -62,7 +62,6 @@ import org.apache.sis.util.resources.Ind
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk8.Instant;
-import org.apache.sis.internal.jdk8.DateTimeException;
 
 
 /**
@@ -183,7 +182,7 @@ public final class Store extends DataSto
         FeatureType     featureType = null;
         Foliation       foliation   = null;
         try {
-            final List<String> elements = new ArrayList<>();
+            final List<String> elements = new ArrayList<String>();
             source.mark(1024);
             String line;
             while ((line = source.readLine()) != null) {
@@ -194,15 +193,15 @@ public final class Store extends DataSto
                 if (c != METADATA) break;
                 split(line, elements);
                 final String keyword = elements.get(0);
-                switch (keyword.toLowerCase(Locale.US)) {
-                    case "@stboundedby": {
+                /*switch (k)*/ {
+                    final String k = keyword.toLowerCase(Locale.US);
+                    if (k.equals("@stboundedby")) {
                         if (envelope != null) {
                             throw new DataStoreException(duplicated("@stboundedby"));
                         }
                         envelope = parseEnvelope(elements);
-                        break;
                     }
-                    case "@columns": {
+                    else if (k.equals("@columns")) {
                         if (featureType != null) {
                             throw new DataStoreException(duplicated("@columns"));
                         }
@@ -210,35 +209,32 @@ public final class Store extends DataSto
                         if (foliation == null) {
                             foliation = Foliation.TIME;
                         }
-                        break;
                     }
-                    case "@foliation": {
+                    else if (k.equals("@foliation")) {
                         if (foliation != null) {
                             throw new DataStoreException(duplicated("@foliation"));
                         }
                         foliation = parseFoliation(elements);
-                        break;
                     }
-                    default: {
+                    else {
                         final LogRecord record = errors().getLogRecord(Level.WARNING, Errors.Keys.UnknownKeyword_1, keyword);
                         record.setSourceClassName(Store.class.getName());
                         record.setSourceMethodName("parseHeader");
                         listeners.warning(record);
-                        break;
                     }
                 }
                 elements.clear();
                 source.mark(1024);
             }
             source.reset();
-        } catch (IOException | FactoryException | IllegalArgumentException | DateTimeException e) {
+        } catch (Exception e) {     // This is a multi-catch on the JDK7 branch.
             throw new DataStoreException(errors().getString(Errors.Keys.CanNotParseFile_2, "CSV", name), e);
         }
         this.envelope    = envelope;
         this.featureType = featureType;
         this.foliation   = foliation;
         this.metadata    = MetadataHelper.createForTextFile(connector);
-        this.features    = new ArrayList<>();
+        this.features    = new ArrayList<Feature>();
     }
 
     /**
@@ -266,15 +262,21 @@ public final class Store extends DataSto
         GeneralEnvelope envelope      = null;
         switch (elements.size()) {
             default:final String unit = elements.get(7);
-                    switch (unit.toLowerCase(Locale.US)) {
-                        case "":
-                        case "sec":
-                        case "second":   /* Already SI.SECOND. */ break;
-                        case "minute":   timeUnit = NonSI.MINUTE; break;
-                        case "hour":     timeUnit = NonSI.HOUR;   break;
-                        case "day":      timeUnit = NonSI.DAY;    break;
-                        case "absolute": isTimeAbsolute = true;   break;
-                        default: throw new DataStoreException(errors().getString(Errors.Keys.UnknownUnit_1, unit));
+                    /*switch (k)*/ {
+                        final String k = unit.toLowerCase(Locale.US);
+                        if (k.isEmpty() || k.equals("sec") || k.equals("second")) {
+                            /* Already SI.SECOND. */
+                        } else if (k.equals("minute")) {
+                            timeUnit = NonSI.MINUTE;
+                        } else if (k.equals("hour")) {
+                            timeUnit = NonSI.HOUR;
+                        } else if (k.equals("day")) {
+                            timeUnit = NonSI.DAY;
+                        } else if (k.equals("absolute")) {
+                            isTimeAbsolute = true;
+                        } else {
+                            throw new DataStoreException(errors().getString(Errors.Keys.UnknownUnit_1, unit));
+                        }
                     }
                     // Fall through
             case 7: endTime     = Instant      .parse(       elements.get(6));
@@ -282,12 +284,16 @@ public final class Store extends DataSto
             case 5: upperCorner = CharSequences.parseDoubles(elements.get(4), ORDINATE_SEPARATOR);
             case 4: lowerCorner = CharSequences.parseDoubles(elements.get(3), ORDINATE_SEPARATOR);
             case 3: final String dimension = elements.get(2);
-                    switch (dimension.toUpperCase(Locale.US)) {
-                        case "":   // Default to 2D.
-                        case "2D": break;
-                        case "3D": is3D = true; break;
-                        default: throw new DataStoreException(errors().getString(
+                    /* switch (k)*/ {
+                        final String k = dimension.toUpperCase(Locale.US);
+                        if (k.isEmpty() || k.equals("2D")) {
+                            // Default to 2D.
+                        } else if (k.equals("3D")) {
+                            is3D = true;
+                        } else {
+                            throw new DataStoreException(errors().getString(
                                         Errors.Keys.IllegalCoordinateSystem_1, dimension));
+                        }
                     }
                     // Fall through
             case 2: crs = CRS.forCode(elements.get(1));
@@ -366,7 +372,7 @@ public final class Store extends DataSto
      */
     private FeatureType parseFeatureType(final List<String> elements) throws DataStoreException {
         final int size = elements.size();
-        final List<PropertyType> properties = new ArrayList<>();
+        final List<PropertyType> properties = new ArrayList<PropertyType>();
         for (int i=1; i<size; i++) {
             final String name = elements.get(i);
             Class<?> type = null;
@@ -374,14 +380,22 @@ public final class Store extends DataSto
                 String tn = elements.get(i);
                 if (!tn.isEmpty() && tn.regionMatches(true, 0, TYPE_PREFIX, 0, TYPE_PREFIX.length())) {
                     String st = tn.substring(TYPE_PREFIX.length()).toLowerCase(Locale.US);
-                    switch (st) {
-                        case "boolean":  type = Boolean.class; break;
-                        case "decimal":  type = Double .class; break;
-                        case "integer":  type = Integer.class; break;
-                        case "string":   type = String .class; break;
-                        case "datetime": type = Instant.class; break;
-                        case "anyuri":   type = URI    .class; break;
-                        default: throw new DataStoreException(errors().getString(Errors.Keys.UnknownType_1, tn));
+                    /*switch (st)*/ {
+                        if (st.equals("boolean")) {
+                            type = Boolean.class;
+                        } else if (st.equals("decimal")) {
+                            type = Double.class;
+                        } else if (st.equals("integer")) {
+                            type = Integer.class;
+                        } else if (st.equals("string")) {
+                            type = String.class;
+                        } else if (st.equals("datetime")) {
+                            type = Instant.class;
+                        } else if (st.equals("anyuri")) {
+                            type = URI.class;
+                        } else {
+                            throw new DataStoreException(errors().getString(Errors.Keys.UnknownType_1, tn));
+                        }
                     }
                 }
             }
@@ -425,7 +439,7 @@ public final class Store extends DataSto
      * Creates a property type for the given name and type.
      */
     private static PropertyType createProperty(final String name, final Class<?> type, final int minOccurrence) {
-        return new DefaultAttributeType<>(Collections.singletonMap(DefaultAttributeType.NAME_KEY, name), type, minOccurrence, 1, null);
+        return new DefaultAttributeType(Collections.singletonMap(DefaultAttributeType.NAME_KEY, name), type, minOccurrence, 1, null);
     }
 
     /**
@@ -483,7 +497,7 @@ public final class Store extends DataSto
             final String[]     propertyNames   = new String[converters.length];
             final boolean      hasTrajectories = this.hasTrajectories;
             final TimeEncoding timeEncoding    = this.timeEncoding;
-            final List<String> values          = new ArrayList<>();
+            final List<String> values          = new ArrayList<String>();
             int i = -1;
             for (final PropertyType p : properties) {
                 propertyNames[++i] = p.getName().tip().toString();
@@ -558,7 +572,7 @@ public final class Store extends DataSto
                 }
                 values.clear();
             }
-        } catch (IOException | IllegalArgumentException | DateTimeException e) {
+        } catch (Exception e) {     // Multi-catch on the JDK7 branch.
             throw new DataStoreException(errors().getString(Errors.Keys.CanNotParseFile_2, "CSV", name), e);
         }
         return features.iterator();

Modified: sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java [UTF-8] Wed Mar 30 11:25:06 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/branches/JDK6/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java [UTF-8] (original)
+++ sis/branches/JDK6/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java [UTF-8] Wed Mar 30 11:25:06 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;
     }
 




Mime
View raw message