sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1734399 [1/2] - in /sis/branches/JDK7: ./ core/sis-metadata/src/main/java/org/apache/sis/metadata/ core/sis-referencing/src/main/java/org/apache/sis/geometry/ core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ core/sis...
Date Thu, 10 Mar 2016 12:42:30 GMT
Author: desruisseaux
Date: Thu Mar 10 12:42:29 2016
New Revision: 1734399

URL: http://svn.apache.org/viewvc?rev=1734399&view=rev
Log:
Merge from the JDK8 branch.

Added:
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DateTimeException.java   (with props)
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Instant.java   (with props)
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
      - copied unchanged from r1734383, sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataHelper.java
      - copied unchanged from r1734383, sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataHelper.java
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java
      - copied, changed from r1734383, sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/
      - copied from r1734383, sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/
    sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
      - copied, changed from r1734383, sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
    sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/
      - copied from r1734383, sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/
Modified:
    sis/branches/JDK7/   (props changed)
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
    sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties
    sis/branches/JDK7/pom.xml
    sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java
    sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
    sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java
    sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
    sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
    sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java
    sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/GridGeometryTest.java
    sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/TestCase.java
    sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
    sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/ChannelDecoderTest.java
    sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/GridGeometryInfoTest.java
    sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/impl/VariableInfoTest.java
    sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
    sis/branches/JDK7/storage/sis-storage/pom.xml
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/wkt/Store.java
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/xml/Store.java
    sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java
    sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
    sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java
    sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java
    sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java

Propchange: sis/branches/JDK7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Mar 10 12:42:29 2016
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
 /sis/branches/JDK6:1394913-1508480
-/sis/branches/JDK8:1584960-1733370
+/sis/branches/JDK8:1584960-1734395
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -968,7 +968,7 @@ public class MetadataStandard implements
     }
 
     /**
-     * Assigns an {@link ConcurrentMap} instance to the given field.
+     * Assigns a {@link ConcurrentMap} instance to the given field.
      * Used on deserialization only.
      */
     final void setMapForField(final Class<?> classe, final String name) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -269,7 +269,7 @@ public final class Envelopes extends Sta
          * ordinate values. This coordinate will be updated in the 'switch' statement inside
          * the 'while' loop.
          */
-        if (sourceDim >= 20) { // Maximal value supported by Formulas.pow3(int) is 19.
+        if (sourceDim >= 20) {          // Maximal value supported by Formulas.pow3(int) is 19.
             throw new IllegalArgumentException(Errors.format(Errors.Keys.ExcessiveNumberOfDimensions_1));
         }
         int             pointIndex            = 0;
@@ -395,12 +395,12 @@ public final class Envelopes extends Sta
                                             for (int ib3 = pointIndex, dim = sourceDim; --dim >= 0; ib3 /= 3) {
                                                 final double ordinate;
                                                 if (dim == i) {
-                                                    ordinate = x; // Position of the extremum.
+                                                    ordinate = x;                         // Position of the extremum.
                                                 } else switch (ib3 % 3) {
                                                     case 0:  ordinate = envelope.getMinimum(dim); break;
                                                     case 1:  ordinate = envelope.getMaximum(dim); break;
                                                     case 2:  ordinate = envelope.getMedian (dim); break;
-                                                    default: throw new AssertionError(ib3); // Should never happen
+                                                    default: throw new AssertionError(ib3);     // Should never happen
                                                 }
                                                 sourcePt[dim] = ordinate;
                                             }
@@ -413,7 +413,7 @@ public final class Envelopes extends Sta
                         }
                     }
                 }
-                derivatives[pointIndex] = null; // Let GC do its job earlier.
+                derivatives[pointIndex] = null;                 // Let GC do its job earlier.
             }
         }
         if (targetPt != null) {
@@ -491,13 +491,13 @@ public final class Envelopes extends Sta
          */
         if (sourceCRS != null) {
             final CoordinateSystem cs = sourceCRS.getCoordinateSystem();
-            if (cs != null) { // Should never be null, but check as a paranoiac safety.
+            if (cs != null) {                           // Should never be null, but check as a paranoiac safety.
                 DirectPosition sourcePt = null;
                 DirectPosition targetPt = null;
                 final int dimension = cs.getDimension();
                 for (int i=0; i<dimension; i++) {
                     final CoordinateSystemAxis axis = cs.getAxis(i);
-                    if (axis == null) { // Should never be null, but check as a paranoiac safety.
+                    if (axis == null) {                 // Should never be null, but check as a paranoiac safety.
                         continue;
                     }
                     final double min = envelope.getMinimum(i);
@@ -579,17 +579,17 @@ public final class Envelopes extends Sta
         AbstractEnvelope generalEnvelope = null;
         DirectPosition sourcePt = null;
         DirectPosition targetPt = null;
-        long includedMinValue = 0; // A bitmask for each dimension.
+        long includedMinValue = 0;              // A bitmask for each dimension.
         long includedMaxValue = 0;
         long isWrapAroundAxis = 0;
         long dimensionBitMask = 1;
         final int dimension = targetCS.getDimension();
         for (int i=0; i<dimension; i++, dimensionBitMask <<= 1) {
             final CoordinateSystemAxis axis = targetCS.getAxis(i);
-            if (axis == null) { // Should never be null, but check as a paranoiac safety.
+            if (axis == null) {                 // Should never be null, but check as a paranoiac safety.
                 continue;
             }
-            boolean testMax = false; // Tells if we are testing the minimal or maximal value.
+            boolean testMax = false;            // Tells if we are testing the minimal or maximal value.
             do {
                 final double extremum = testMax ? axis.getMaximumValue() : axis.getMinimumValue();
                 if (Double.isInfinite(extremum) || Double.isNaN(extremum)) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -24,6 +24,8 @@ package org.apache.sis.geometry;
 import java.util.Arrays;
 import java.io.Serializable;
 import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -65,6 +67,12 @@ public class GeneralDirectPosition exten
     private static final long serialVersionUID = -5524426558018300122L;
 
     /**
+     * Used for setting the {@link #ordinates} field during a {@link #clone()} operation only.
+     * Will be fetch when first needed.
+     */
+    private static volatile Field ordinatesField;
+
+    /**
      * The ordinates of the direct position. The length of this array is the
      * {@linkplain #getDimension() dimension} of this direct position.
      */
@@ -273,6 +281,21 @@ public class GeneralDirectPosition exten
     }
 
     /**
+     * Returns the {@code "ordinates"} field of the given class and gives write permission to it.
+     * This method should be invoked only from {@link #clone()} method.
+     */
+    static Field getOrdinatesField(final Class<?> type) throws NoSuchFieldException {
+        final Field field = type.getDeclaredField("ordinates");
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override public Void run() {
+                field.setAccessible(true);
+                return null;
+            }
+        });
+        return field;
+    }
+
+    /**
      * Returns a deep copy of this position.
      *
      * @return A copy of this direct position.
@@ -280,9 +303,11 @@ public class GeneralDirectPosition exten
     @Override
     public GeneralDirectPosition clone() {
         try {
+            Field field = ordinatesField;
+            if (field == null) {
+                ordinatesField = field = getOrdinatesField(GeneralDirectPosition.class);
+            }
             GeneralDirectPosition e = (GeneralDirectPosition) super.clone();
-            final Field field = GeneralDirectPosition.class.getDeclaredField("ordinates");
-            field.setAccessible(true);
             field.set(e, ordinates.clone());
             return e;
         } catch (ReflectiveOperationException | CloneNotSupportedException exception) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -1034,9 +1034,7 @@ public class GeneralEnvelope extends Arr
         try {
             Field field = ordinatesField;
             if (field == null) {
-                field = ArrayEnvelope.class.getDeclaredField("ordinates");
-                field.setAccessible(true);
-                ordinatesField = field;
+                ordinatesField = field = GeneralDirectPosition.getOrdinatesField(ArrayEnvelope.class);
             }
             GeneralEnvelope e = (GeneralEnvelope) super.clone();
             field.set(e, ordinates.clone());

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -16,24 +16,38 @@
  */
 package org.apache.sis.internal.referencing;
 
+import java.util.Map;
+import java.util.Date;
+import java.util.Collections;
 import javax.measure.unit.Unit;
+import javax.measure.quantity.Duration;
 import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterNotFoundException;
 import org.opengis.parameter.InvalidParameterValueException;
+import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.crs.CRSFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.crs.TemporalCRS;
+import org.opengis.referencing.cs.AxisDirection;
+import org.opengis.referencing.cs.CSFactory;
 import org.opengis.referencing.cs.CartesianCS;
+import org.opengis.referencing.cs.TimeCS;
+import org.opengis.referencing.datum.DatumFactory;
+import org.opengis.referencing.datum.TemporalDatum;
 import org.opengis.referencing.operation.CoordinateOperationFactory;
 import org.opengis.referencing.operation.OperationMethod;
 import org.opengis.referencing.operation.Conversion;
+import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.referencing.provider.TransverseMercator;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.referencing.Builder;
+import org.apache.sis.referencing.CommonCRS;
 
 
 /**
@@ -69,12 +83,22 @@ public class GeodeticObjectBuilder exten
     private ParameterValueGroup parameters;
 
     /**
-     * The factor for Coordinate Reference System objects, fetched when first needed.
+     * The factory for Coordinate Reference System objects, fetched when first needed.
      */
     private CRSFactory crsFactory;
 
     /**
-     * The factor for Coordinate Operation objects, fetched when first needed.
+     * The factory for Coordinate System objects, fetched when first needed.
+     */
+    private CSFactory csFactory;
+
+    /**
+     * The factory for Datum objects, fetched when first needed.
+     */
+    private DatumFactory datumFactory;
+
+    /**
+     * The factory for Coordinate Operation objects, fetched when first needed.
      */
     private CoordinateOperationFactory copFactory;
 
@@ -95,6 +119,26 @@ public class GeodeticObjectBuilder exten
     }
 
     /**
+     * Returns the factory for Coordinate System objects. This method fetches the factory when first needed.
+     */
+    private CSFactory getCSFactory() {
+        if (csFactory == null) {
+            csFactory = DefaultFactories.forBuildin(CSFactory.class);
+        }
+        return csFactory;
+    }
+
+    /**
+     * Returns the factory for Datum objects. This method fetches the factory when first needed.
+     */
+    private DatumFactory getDatumFactory() {
+        if (datumFactory == null) {
+            datumFactory = DefaultFactories.forBuildin(DatumFactory.class);
+        }
+        return datumFactory;
+    }
+
+    /**
      * Returns the factory for Coordinate Operation objects. This method fetches the factory when first needed.
      */
     private CoordinateOperationFactory getCoordinateOperationFactory() {
@@ -264,4 +308,87 @@ public class GeodeticObjectBuilder exten
             onCreate(true);
         }
     }
+
+    /**
+     * Creates a temporal CRS from the given origin and temporal unit. For this method, the CRS name is optional:
+     * if no {@code addName(…)} method has been invoked, then a default name will be used.
+     *
+     * @param  origin The epoch in milliseconds since January 1st, 1970 at midnight UTC.
+     * @param  unit The unit of measurement.
+     * @return A temporal CRS using the given origin and units.
+     * @throws FactoryException if an error occurred while building the temporal CRS.
+     */
+    public TemporalCRS createTemporalCRS(final Date origin, final Unit<Duration> unit) throws FactoryException {
+        /*
+         * Try to use one of the pre-defined datum and coordinate system if possible.
+         * This not only saves a little bit of memory, but also provides better names.
+         */
+        TimeCS cs = null;
+        TemporalDatum datum = null;
+        for (final CommonCRS.Temporal c : CommonCRS.Temporal.values()) {
+            if (datum == null) {
+                final TemporalDatum candidate = c.datum();
+                if (origin.equals(candidate.getOrigin())) {
+                    datum = candidate;
+                }
+            }
+            if (cs == null) {
+                final TemporalCRS crs = c.crs();
+                final TimeCS candidate = crs.getCoordinateSystem();
+                if (unit.equals(candidate.getAxis(0).getUnit())) {
+                    if (datum == candidate && properties.isEmpty()) {
+                        return crs;
+                    }
+                    cs = candidate;
+                }
+            }
+        }
+        /*
+         * Create the datum and coordinate system before the CRS if we were not able to use a pre-defined object.
+         * In the datum case, we will use the same metadata than the CRS (domain of validity, scope, etc.) except
+         * the identifier and the remark.
+         */
+        onCreate(false);
+        try {
+            if (cs == null) {
+                final CSFactory csFactory = getCSFactory();
+                cs = CommonCRS.Temporal.JAVA.crs().getCoordinateSystem();   // To be used as a template, except for units.
+                cs = csFactory.createTimeCS(name(cs),
+                     csFactory.createCoordinateSystemAxis(name(cs.getAxis(0)), "t", AxisDirection.FUTURE, unit));
+            }
+            if (properties.get(TemporalCRS.NAME_KEY) == null) {
+                properties.putAll(name(cs));
+            }
+            if (datum == null) {
+                final Object remarks    = properties.remove(TemporalCRS.REMARKS_KEY);
+                final Object identifier = properties.remove(TemporalCRS.IDENTIFIERS_KEY);
+                datum = getDatumFactory().createTemporalDatum(properties, origin);
+                properties.put(TemporalCRS.IDENTIFIERS_KEY, identifier);
+                properties.put(TemporalCRS.REMARKS_KEY,     remarks);
+                properties.put(TemporalCRS.NAME_KEY, datum.getName());      // Share the Identifier instance.
+            }
+            return getCRSFactory().createTemporalCRS(properties, datum, cs);
+        } finally {
+            onCreate(true);
+        }
+    }
+
+    /**
+     * Creates a compound CRS, but we special processing for (two-dimensional Geographic + ellipsoidal heights) tupples.
+     * If any such tupple is found, a three-dimensional geographic CRS is created instead than the compound CRS.
+     *
+     * @param  components ordered array of {@code CoordinateReferenceSystem} objects.
+     * @return The coordinate reference system for the given properties.
+     * @throws FactoryException if the object creation failed.
+     */
+    public CoordinateReferenceSystem createCompoundCRS(final CoordinateReferenceSystem... components) throws FactoryException {
+        return ReferencingServices.getInstance().createCompoundCRS(getCRSFactory(), getCSFactory(), properties, components);
+    }
+
+    /**
+     * Creates a map of properties containing only the name of the given object.
+     */
+    private static Map<String,Object> name(final IdentifiedObject template) {
+        return Collections.<String,Object>singletonMap(IdentifiedObject.NAME_KEY, template.getName());
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -26,6 +26,8 @@ import java.util.logging.Logger;
 import java.util.logging.LogRecord;
 import java.util.concurrent.atomic.AtomicReference;
 import java.lang.reflect.Constructor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Angle;
 import javax.measure.quantity.Length;
@@ -186,8 +188,9 @@ import org.apache.sis.xml.XML;
  * since localizations are applied by the {@link InternationalString#toString(Locale)} method.</p>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @author  Guilhem Legal (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  */
 public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory, DatumFactory, Parser {
@@ -1524,7 +1527,13 @@ public class GeodeticObjectFactory exten
             if (c == null) {
                 c = Class.forName("org.apache.sis.io.wkt.GeodeticObjectParser").asSubclass(Parser.class)
                          .getConstructor(Map.class, ObjectFactory.class, MathTransformFactory.class);
-                c.setAccessible(true);
+                final Constructor<?> cp = c;     // For allowing use in inner class or lambda expression.
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    @Override public Void run() {
+                        cp.setAccessible(true);
+                        return null;
+                    }
+                });
                 parserConstructor = c;
             }
             p = c.newInstance(defaultProperties, this, getMathTransformFactory());

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -40,7 +40,6 @@ import java.sql.ResultSetMetaData;
 import java.sql.Statement;
 import java.sql.SQLException;
 import java.text.DateFormat;
-import java.text.SimpleDateFormat;
 import java.text.ParseException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -107,6 +106,7 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Localized;
 import org.apache.sis.util.Version;
+import org.apache.sis.util.Workaround;
 import org.apache.sis.util.collection.Containers;
 import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.measure.NumberRange;
@@ -116,6 +116,7 @@ import static org.apache.sis.internal.re
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk8.JDK8;
+import org.apache.sis.internal.util.StandardDateFormat;
 
 
 /**
@@ -173,6 +174,7 @@ public class EPSGDataAccess extends Geod
      *
      * @see #replaceDeprecatedCS
      */
+    @Workaround(library = "EPSG:6401-6420", version = "8.9")        // Deprecated in 2002 but still present in 2016.
     private static final Map<Integer,Integer> DEPRECATED_CS = deprecatedCS();
     static Map<Integer,Integer> deprecatedCS() {
         final Map<Integer,Integer> m = new HashMap<>(24);
@@ -1645,7 +1647,7 @@ addURIs:    for (int i=0; ; i++) {
                             throw new FactoryDataException(error().getString(Errors.Keys.DatumOriginShallBeDate));
                         }
                         if (dateFormat == null) {
-                            dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.CANADA);
+                            dateFormat = new StandardDateFormat();
                             dateFormat.setCalendar(getCalendar());          // Use UTC timezone.
                         }
                         try {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -350,8 +350,9 @@ public class EPSGFactory extends Concurr
      *     If no provider is specified, then this method will search on the classpath (with {@link java.util.ServiceLoader})
      *     for user-provided implementations of {@code InstallationScriptProvider}.
      *     If no user-specified provider is found, then this method will search for
-     *     {@code "EPSG_Tables.sql"}, {@code "EPSG_Data.sql"} and {@code "EPSG_FKeys.sql"} files in the
-     *     {@code $SIS_DATA/Databases/ExternalSources} directory.</li>
+     *     {@code "EPSG_*Tables.sql"}, {@code "EPSG_*Data.sql"} and {@code "EPSG_*FKeys.sql"} files in the
+     *     {@code $SIS_DATA/Databases/ExternalSources} directory where {@code *} stands for any characters
+     *     provided that there is no ambiguity.</li>
      * </ul>
      *
      * <p><b>Legal constraint:</b>
@@ -381,7 +382,7 @@ public class EPSGFactory extends Concurr
                         installer.prependNamespace(catalog);
                     }
                 }
-                installer.run(scriptProvider);
+                installer.run(scriptProvider, locale);
                 success = true;
             } finally {
                 if (ac) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -32,11 +32,9 @@ import java.io.BufferedReader;
 import org.apache.sis.util.StringBuilders;
 import org.apache.sis.internal.metadata.sql.ScriptRunner;
 import org.apache.sis.internal.metadata.sql.SQLUtilities;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Fallback;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Messages;
-import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.logging.PerformanceLevel;
 import org.apache.sis.setup.InstallationResources;
 
@@ -251,12 +249,12 @@ final class EPSGInstaller extends Script
      * @throws IOException if an error occurred while reading an input.
      * @throws SQLException if an error occurred while executing a SQL statement.
      */
-    public void run(InstallationResources scriptProvider) throws SQLException, IOException {
+    public void run(InstallationResources scriptProvider, final Locale locale) throws SQLException, IOException {
         long time = System.nanoTime();
-        log(Messages.getResources(null).getLogRecord(Level.INFO, Messages.Keys.CreatingSchema_2, EPSG,
-                SQLUtilities.getSimplifiedURL(getConnection().getMetaData())));
+        InstallationScriptProvider.log(Messages.getResources(locale).getLogRecord(Level.INFO,
+                Messages.Keys.CreatingSchema_2, EPSG, SQLUtilities.getSimplifiedURL(getConnection().getMetaData())));
         if (scriptProvider == null) {
-            scriptProvider = lookupProvider();
+            scriptProvider = lookupProvider(locale);
         }
         final String[] scripts = scriptProvider.getResourceNames(EPSG);
         int numRows = 0;
@@ -266,7 +264,7 @@ final class EPSGInstaller extends Script
             }
         }
         time = System.nanoTime() - time;
-        log(Messages.getResources(null).getLogRecord(
+        InstallationScriptProvider.log(Messages.getResources(locale).getLogRecord(
                 PerformanceLevel.forDuration(time, TimeUnit.NANOSECONDS),
                 Messages.Keys.InsertDuration_2, numRows, time / 1E9f));
     }
@@ -274,7 +272,7 @@ final class EPSGInstaller extends Script
     /**
      * Searches for a SQL script provider on the classpath before to fallback on the default provider.
      */
-    private static InstallationResources lookupProvider() {
+    private static InstallationResources lookupProvider(final Locale locale) throws IOException {
         InstallationResources fallback = null;
         for (final InstallationResources provider : ServiceLoader.load(InstallationResources.class)) {
             if (provider.getAuthorities().contains(EPSG)) {
@@ -284,7 +282,7 @@ final class EPSGInstaller extends Script
                 fallback = provider;
             }
         }
-        return (fallback != null) ? fallback : new InstallationScriptProvider.Default();
+        return (fallback != null) ? fallback : new InstallationScriptProvider.Default(locale);
     }
 
     /**
@@ -299,15 +297,6 @@ final class EPSGInstaller extends Script
         if (status != null) {
             message = message + ' ' + status;
         }
-        log(new LogRecord(Level.WARNING, message));
-    }
-
-    /**
-     * Logs the given record. This method pretend that the record has been logged by
-     * {@code EPSGFactory.install(…)} because it is the public API using this class.
-     */
-    private static void log(final LogRecord record) {
-        record.setLoggerName(Loggers.CRS_FACTORY);
-        Logging.log(EPSGFactory.class, "install", record);
+        InstallationScriptProvider.log(new LogRecord(Level.WARNING, message));
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -19,6 +19,8 @@ package org.apache.sis.referencing.facto
 import java.util.Set;
 import java.util.Locale;
 import java.util.Collections;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
 import java.sql.Connection;
 import java.io.BufferedReader;
 import java.io.LineNumberReader;
@@ -28,14 +30,17 @@ import java.io.IOException;
 import java.io.FileNotFoundException;
 import java.nio.charset.Charset;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.setup.InstallationResources;
 import org.apache.sis.internal.system.DataDirectory;
+import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.Constants;
 
 // Branch-dependent imports
 import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 
@@ -261,17 +266,27 @@ public abstract class InstallationScript
      */
     protected abstract InputStream openStream(final String name) throws IOException;
 
+    /**
+     * Logs the given record. This method pretend that the record has been logged by
+     * {@code EPSGFactory.install(…)} because it is the public API using this class.
+     */
+    static void log(final LogRecord record) {
+        record.setLoggerName(Loggers.CRS_FACTORY);
+        Logging.log(EPSGFactory.class, "install", record);
+    }
+
 
 
 
     /**
      * The default implementation which use the scripts in the {@code $SIS_DATA/Databases/ExternalSources}
-     * directory, if present. This class expects the files to have those exact names:
+     * directory, if present. This class expects the files to have those exact names where {@code *} stands
+     * for any characters provided that there is no ambiguity:
      *
      * <ul>
-     *   <li>{@code EPSG_Tables.sql}</li>
-     *   <li>{@code EPSG_Data.sql}</li>
-     *   <li>{@code EPSG_FKeys.sql}</li>
+     *   <li>{@code EPSG_*Tables.sql}</li>
+     *   <li>{@code EPSG_*Data.sql}</li>
+     *   <li>{@code EPSG_*FKeys.sql}</li>
      * </ul>
      *
      * @author  Martin Desruisseaux (Geomatys)
@@ -283,27 +298,58 @@ public abstract class InstallationScript
         /**
          * The directory containing the scripts, or {@code null} if it does not exist.
          */
-        private final Path directory;
+        private Path directory;
+
+        /**
+         * Index of the first real file in the array given to the constructor.
+         * We set the value to 1 for skipping the {@code PREPARE} pseudo-file.
+         */
+        private static final int FIRST_FILE = 1;
 
         /**
          * Creates a default provider.
          */
-        Default() {
+        Default(final Locale locale) throws IOException {
             super(Constants.EPSG,
                     PREPARE,
-                    "EPSG_Tables.sql",
-                    "EPSG_Data.sql",
-                    "EPSG_FKeys.sql",
+                    "Tables",
+                    "Data",
+                    "FKeys",
                     FINISH);
 
             Path dir = DataDirectory.DATABASES.getDirectory();
             if (dir != null) {
                 dir = dir.resolve("ExternalSources");
-                if (!Files.isRegularFile(dir.resolve("EPSG_Tables.sql"))) {
-                    dir = null;
+                if (Files.isDirectory(dir)) {
+                    final String[] resources = super.resources;
+                    final String[] found = new String[resources.length - FIRST_FILE - 1];
+                    try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "EPSG_*.sql")) {
+                        for (final Path path : stream) {
+                            final String name = path.getFileName().toString();
+                            for (int i=0; i<found.length; i++) {
+                                final String part = resources[FIRST_FILE + i];
+                                if (name.contains(part)) {
+                                    if (found[i] != null) {
+                                        log(Errors.getResources(locale)
+                                                  .getLogRecord(Level.WARNING, Errors.Keys.DuplicatedElement_1, part));
+                                        return;                         // Stop the search because of duplicated file.
+                                    }
+                                    found[i] = name;
+                                }
+                            }
+                        }
+                    }
+                    for (int i=0; i<found.length; i++) {
+                        final String file = found[i];
+                        if (file != null) {
+                            resources[FIRST_FILE + i] = file;
+                        } else {
+                            dir = null;
+                        }
+                    }
+                    directory = dir;
                 }
             }
-            directory = dir;
         }
 
         /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -26,6 +26,8 @@ import java.util.concurrent.atomic.Atomi
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.lang.reflect.Constructor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.io.Serializable;
 import javax.measure.quantity.Length;
 import javax.measure.unit.SI;
@@ -1233,7 +1235,7 @@ public class DefaultMathTransformFactory
      *
      * @param  text Math transform encoded in Well-Known Text format.
      * @return The math transform (never {@code null}).
-     * @throws FactoryException if the Well-Known Text can't be parsed,
+     * @throws FactoryException if the Well-Known Text can not be parsed,
      *         or if the math transform creation failed from some other reason.
      */
     @Override
@@ -1245,7 +1247,13 @@ public class DefaultMathTransformFactory
             if (c == null) {
                 c = Class.forName("org.apache.sis.io.wkt.MathTransformParser").asSubclass(Parser.class)
                          .getConstructor(MathTransformFactory.class);
-                c.setAccessible(true);
+                final Constructor<?> cp = c;     // For allowing use in inner class or lambda expression.
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    @Override public Void run() {
+                        cp.setAccessible(true);
+                        return null;
+                    }
+                });
                 parserConstructor = c;
             }
             p = c.newInstance(this);

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -21,6 +21,7 @@ import java.util.Set;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.regex.Pattern;
+import java.io.IOException;
 import javax.sql.DataSource;
 import java.sql.Connection;
 import java.sql.Statement;
@@ -112,8 +113,8 @@ public final strictfp class EPSGInstalle
      * Returns the SQL scripts needed for testing the database creation,
      * or skip the JUnit test if those scripts are not found.
      */
-    private static InstallationScriptProvider getScripts() {
-        final InstallationScriptProvider scripts = new InstallationScriptProvider.Default();
+    private static InstallationScriptProvider getScripts() throws IOException {
+        final InstallationScriptProvider scripts = new InstallationScriptProvider.Default(null);
         assumeTrue("EPSG scripts not found in Databases/ExternalSources directory.",
                 scripts.getAuthorities().contains(Constants.EPSG));
         return scripts;

Added: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DateTimeException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DateTimeException.java?rev=1734399&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DateTimeException.java (added)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DateTimeException.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.jdk8;
+
+
+/**
+ * Placeholder for the {@link java.time.DateTimeException} class.
+ */
+@SuppressWarnings("serial")
+public final class DateTimeException extends RuntimeException {
+    /**
+     * Constructs a new exception with the specified message.
+     *
+     * @param message the message to be returned by {@link #getMessage()}, or null.
+     */
+    public DateTimeException(String message) {
+        super(message);
+    }
+}

Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DateTimeException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DateTimeException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Instant.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Instant.java?rev=1734399&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Instant.java (added)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Instant.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.jdk8;
+
+import java.util.Date;
+import java.text.ParseException;
+import org.apache.sis.internal.util.StandardDateFormat;
+
+
+/**
+ * Placeholder for the {@link java.time.Instant} class.
+ */
+public final class Instant {
+    /**
+     * The parser to use for the {@link #parse(CharSequence)} method.
+     */
+    private static final StandardDateFormat parser = new StandardDateFormat();
+
+    /**
+     * Number of milliseconds since January 1st, 1970 midnight UTC.
+     */
+    private final long millis;
+
+    /**
+     * Creates a new instant.
+     *
+     * @param millis Number of milliseconds since January 1st, 1970 midnight UTC.
+     */
+    private Instant(final long millis) {
+        this.millis = millis;
+    }
+
+    /**
+     * Parses the given text.
+     *
+     * @param  text the text to parse.
+     * @return the instant.
+     * @throws DateTimeException if the text can not be parsed.
+     */
+    public static Instant parse(final CharSequence text) {
+        final Date time;
+        try {
+            synchronized (parser) {
+                time = parser.parse(text.toString());
+            }
+        } catch (ParseException e) {
+            throw new DateTimeException(e.getMessage());
+        }
+        return new Instant(time.getTime());
+    }
+
+    /**
+     * Creates a new instant for the given time in milliseconds.
+     *
+     * @param  millis number of milliseconds since January 1st, 1970 midnight UTC.
+     * @return the instant for the given time.
+     */
+    public static Instant ofEpochMilli(final long millis) {
+        return new Instant(millis);
+    }
+
+    /**
+     * Returns the number of milliseconds since January 1st, 1970 midnight UTC.
+     *
+     * @return Number of milliseconds since January 1st, 1970 midnight UTC.
+     */
+    public long toEpochMilli() {
+        return millis;
+    }
+
+    /**
+     * Not a JDK method - used as a replacement of {@code Date.from(Instant)}.
+     *
+     * @return This instant as a legacy date object.
+     */
+    public Date toDate() {
+        return new Date(millis);
+    }
+}

Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Instant.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Instant.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -19,6 +19,8 @@ package org.apache.sis.internal.system;
 import java.io.IOException;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.resources.Messages;
 
@@ -113,7 +115,11 @@ public enum DataDirectory {
      */
     public static synchronized Path getRootDirectory() {
         if (rootDirectory == null) try {
-            final String dir = System.getenv(ENV);
+            final String dir = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                @Override public String run() {
+                    return System.getenv(ENV);
+                }
+            });
             if (dir == null || dir.isEmpty()) {
                 warning("getRootDirectory", null, Messages.Keys.DataDirectoryNotSpecified_1, ENV);
             } else try {

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -20,6 +20,8 @@ import java.util.Map;
 import java.util.IdentityHashMap;
 import java.util.ServiceLoader;
 import java.util.ServiceConfigurationError;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import org.apache.sis.internal.util.Utilities;
 
 
@@ -29,8 +31,9 @@ import org.apache.sis.internal.util.Util
  * A candidate replacement is JSR-330.
  *
  * @author  Martin Desruisseaux (Geomatys)
+ * @author  Guilhem Legal (Geomatys)
  * @since   0.3
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see <a href="https://jcp.org/en/jsr/detail?id=330">JSR-330</a>
@@ -85,20 +88,22 @@ public final class DefaultFactories exte
     public static synchronized <T> T forClass(final Class<T> type) {
         T factory = type.cast(FACTORIES.get(type));
         if (factory == null && !FACTORIES.containsKey(type)) {
-            T fallback = null;
-            for (final T candidate : ServiceLoader.load(type)) {
-                if (Utilities.isSIS(candidate.getClass())) {
-                    if (factory != null) {
-                        throw new ServiceConfigurationError("Found two implementations of " + type);
+            factory = AccessController.doPrivileged(new PrivilegedAction<T>() {
+            @Override public T run() {  // No indentation for easier merges from the JDK8 branch (which use lambda).
+                T prefered = null;
+                T fallback = null;
+                for (final T candidate : ServiceLoader.load(type)) {
+                    if (Utilities.isSIS(candidate.getClass())) {
+                        if (prefered != null) {
+                            throw new ServiceConfigurationError("Found two implementations of " + type);
+                        }
+                        prefered = candidate;
+                    } else if (fallback == null) {
+                        fallback = candidate;
                     }
-                    factory = candidate;
-                } else if (fallback == null) {
-                    fallback = candidate;
                 }
-            }
-            if (factory == null) {
-                factory = fallback;
-            }
+                return (prefered != null) ? prefered : fallback;
+            }});
             /*
              * Verifies if the factory that we just selected is the same implementation than an existing instance.
              * The main case for this test is org.apache.sis.referencing.factory.GeodeticObjectFactory, where the

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.internal.system;
 
+import org.apache.sis.util.Workaround;
+
 
 /**
  * Thread-local booleans that need to be shared across different packages. Each thread has its own set of booleans.
@@ -60,6 +62,7 @@ public final class Semaphores {
      *
      * <p><b>Example:</b> EPSG:3752 was a Mercator (variant A) projection but set the latitude of origin to 41°S.</p>
      */
+    @Workaround(library = "EPSG:3752", version = "8.9")        // Deprecated in 2007 but still present in 2016.
     public static final byte SUSPEND_PARAMETER_CHECK = 8;
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/Shutdown.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -19,6 +19,8 @@ package org.apache.sis.internal.system;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.concurrent.Callable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import org.apache.sis.util.logging.Logging;
 
 // Branch-dependent imports
@@ -29,6 +31,7 @@ import java.util.Objects;
  * A central place where to manage SIS shutdown process.
  *
  * @author  Martin Desruisseaux (Geomatys)
+ * @author  Guilhem Legal (Geomatys)
  * @since   0.3
  * @version 0.7
  * @module
@@ -115,7 +118,12 @@ public final class Shutdown extends Thre
             resources.add(resource);
             if (hook == null && container == null) {
                 hook = new Shutdown();
-                Runtime.getRuntime().addShutdownHook(hook);
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    @Override public Void run() {
+                        Runtime.getRuntime().addShutdownHook(hook);
+                        return null;
+                    }
+                });
             }
         }
     }
@@ -126,7 +134,12 @@ public final class Shutdown extends Thre
     private static void removeShutdownHook() {
         assert Thread.holdsLock(resources);
         if (hook != null) {
-            Runtime.getRuntime().removeShutdownHook(hook);
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                @Override public Void run() {
+                    Runtime.getRuntime().removeShutdownHook(hook);
+                    return null;
+                }
+            });
             hook = null;
         }
     }

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -58,6 +58,13 @@ public final class StandardDateFormat ex
     public static final String SHORT_PATTERN = "yyyy-MM-dd";
 
     /**
+     * Creates a new format for a default locale in the UTC timezone.
+     */
+    public StandardDateFormat() {
+        this(Locale.CANADA);        // Canada locale symbols are close to the ISO ones.
+    }
+
+    /**
      * Creates a new format for the given locale in the UTC timezone.
      *
      * @param locale The locale of the format to create.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -38,6 +38,8 @@ import java.text.Format;
 import java.text.DateFormat;
 import java.text.FieldPosition;
 import java.nio.charset.Charset;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Version;
@@ -352,7 +354,15 @@ fill:   for (int i=0; ; i++) {
                 case 13: {
                     if (sections.contains(PATHS)) {
                         nameKey = Vocabulary.Keys.DataDirectory;
-                        value = System.getenv(DataDirectory.ENV);
+                        try {
+                            value = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                                @Override public String run() {
+                                    return System.getenv(DataDirectory.ENV);
+                                }
+                            });
+                        } catch (SecurityException e) {
+                            value = e.toString();
+                        }
                         if (value == null) {
                             value = Messages.getResources(locale).getString(Messages.Keys.DataDirectoryNotSpecified_1, DataDirectory.ENV);
                         } else {

Modified: sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] Thu Mar 10 12:42:29 2016
@@ -87,7 +87,7 @@ jdom1.version        = 1.0
 jdom2.version        = 2.0.4
 jee.version          = 6.0
 osgi.version         = 6.0.0
-netcdf.version       = 4.6.3
+netcdf.version       = 4.6.4
 joda-time.version    = 2.2
 httpclient.version   = 4.3.6
 slf4j.version        = 1.7.7

Modified: sis/branches/JDK7/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/pom.xml?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/pom.xml (original)
+++ sis/branches/JDK7/pom.xml Thu Mar 10 12:42:29 2016
@@ -416,7 +416,7 @@ Apache SIS is a free software, Java lang
          The last properties in this list depend on the Apache SIS branch.
        =================================================================== -->
   <properties>
-    <netcdf.version>4.6.3</netcdf.version>
+    <netcdf.version>4.6.4</netcdf.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <website.encoding>UTF-8</website.encoding>
     <website.locale>en</website.locale>
@@ -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>3.0.1</version>
         <extensions>true</extensions>
         <configuration>
           <excludeDependencies>true</excludeDependencies>
@@ -723,7 +723,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>
@@ -740,7 +740,7 @@ 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.10</version>
         </plugin>
         <plugin>
           <groupId>org.eclipse.jetty</groupId>

Modified: sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java [UTF-8] Thu Mar 10 12:42:29 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/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java [UTF-8] Thu Mar 10 12:42:29 2016
@@ -681,6 +681,7 @@ public final class ChannelDecoder extend
      * @throws IOException {@inheritDoc}
      */
     @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
     public Variable[] getVariables() throws IOException {
         return variables;
     }
@@ -693,6 +694,7 @@ public final class ChannelDecoder extend
      * @throws IOException {@inheritDoc}
      */
     @Override
+    @SuppressWarnings("ReturnOfCollectionOrArrayField")
     public GridGeometry[] getGridGeometries() throws IOException {
         if (gridGeometries == null) {
             /*

Modified: sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/Dimension.java [UTF-8] Thu Mar 10 12:42:29 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/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java [UTF-8] Thu Mar 10 12:42:29 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/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java [UTF-8] Thu Mar 10 12:42:29 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/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java?rev=1734399&r1=1734398&r2=1734399&view=diff
==============================================================================
--- sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java [UTF-8] (original)
+++ sis/branches/JDK7/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/DecoderTest.java [UTF-8] Thu Mar 10 12:42:29 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")




Mime
View raw message