You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/12/07 11:01:29 UTC

svn commit: r1718278 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ sis-referencing/src/main/java/org/apache/sis/parameter/ sis-referencing/src/test/java/org/apache/sis/internal/referencing/pro...

Author: desruisseaux
Date: Mon Dec  7 10:01:29 2015
New Revision: 1718278

URL: http://svn.apache.org/viewvc?rev=1718278&view=rev
Log:
Use the SIS_DATA environment variable for the directory where to search for datum grid files.

Added:
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DatumShiftTest.java   (with props)
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java   (with props)
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java   (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NADCON.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/package-info.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -69,7 +69,7 @@ public abstract class DatumShiftGridFile
      * data exceed 32768 (about 128 kilobytes if the values use the {@code float} type). in which case
      * the oldest grids will be replaced by weak references.
      */
-    static final Cache<Path, DatumShiftGridFile<?,?>> CACHE = new Cache<Path, DatumShiftGridFile<?,?>>(4, 32*1024, true) {
+    static final Cache<Object, DatumShiftGridFile<?,?>> CACHE = new Cache<Object, DatumShiftGridFile<?,?>>(4, 32*1024, true) {
         @Override protected int cost(final DatumShiftGridFile<?,?> grid) {
             int p = 1;
             for (final Object array : grid.getData()) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridLoader.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -16,11 +16,16 @@
  */
 package org.apache.sis.internal.referencing.provider;
 
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
 import java.io.EOFException;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ReadableByteChannel;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.resources.Messages;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.internal.system.Loggers;
 
 // Branch-dependent imports
 import java.nio.file.Path;
@@ -128,4 +133,17 @@ class DatumShiftGridLoader {
         }
         buffer.position(p);
     }
+
+    /**
+     * Logs a message about a grid which is about to be loaded.
+     *
+     * @param caller The provider to logs as the source class.
+     *               The source method will be set to {@code "createMathTransform"}.
+     * @param file   The grid file, as a {@link String} or a {@link Path}.
+     */
+    static void log(final Class<?> caller, final Object file) {
+        final LogRecord record = Messages.getResources(null).getLogRecord(Level.FINE, Messages.Keys.LoadingDatumShiftFile_1, file);
+        record.setLoggerName(Loggers.COORDINATE_OPERATION);
+        Logging.log(caller, "createMathTransform", record);
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -43,6 +43,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.opengis.util.FactoryException;
 import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.system.DataDirectory;
 import org.apache.sis.internal.referencing.NilReferencingObject;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.parameter.Parameters;
@@ -308,7 +309,7 @@ public final class FranceGeocentricInter
             case 3:  withHeights = true; break;
             default: throw new InvalidParameterValueException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "dim", dim), "dim", dim);
         }
-        final Path file = pg.getValue(FILE);
+        final Path file = pg.getMandatoryValue(FILE);
         final DatumShiftGridFile<Angle,Length> grid = getOrLoad(file, !isRecognized(file) ? null : new double[] {TX, TY, TZ}, PRECISION);
         MathTransform tr = InterpolatedGeocentricTransform.createGeodeticTransformation(factory,
                 createEllipsoid(pg, Molodensky.TGT_SEMI_MAJOR,
@@ -335,13 +336,15 @@ public final class FranceGeocentricInter
     static DatumShiftGridFile<Angle,Length> getOrLoad(final Path file, final double[] averages, final double scale)
             throws FactoryException
     {
-        DatumShiftGridFile<?,?> grid = DatumShiftGridFile.CACHE.peek(file);
+        final Path resolved = DataDirectory.DATUM_CHANGES.resolve(file).toAbsolutePath();
+        DatumShiftGridFile<?,?> grid = DatumShiftGridFile.CACHE.peek(resolved);
         if (grid == null) {
-            final Cache.Handler<DatumShiftGridFile<?,?>> handler = DatumShiftGridFile.CACHE.lock(file);
+            final Cache.Handler<DatumShiftGridFile<?,?>> handler = DatumShiftGridFile.CACHE.lock(resolved);
             try {
                 grid = handler.peek();
                 if (grid == null) {
-                    try (final BufferedReader in = Files.newBufferedReader(file)) {
+                    try (final BufferedReader in = Files.newBufferedReader(resolved)) {
+                        DatumShiftGridLoader.log(FranceGeocentricInterpolation.class, file);
                         final DatumShiftGridFile.Float<Angle,Length> g = load(in, file);
                         grid = DatumShiftGridCompressed.compress(g, averages, scale);
                     } catch (IOException | NoninvertibleTransformException | RuntimeException e) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NADCON.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NADCON.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NADCON.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NADCON.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.referencing.provider;
 
+import java.util.AbstractMap;
 import java.io.IOException;
 import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
@@ -36,8 +37,10 @@ import org.opengis.referencing.operation
 import org.apache.sis.referencing.operation.transform.InterpolatedTransform;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.parameter.Parameters;
+import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.collection.Cache;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.system.DataDirectory;
 
 // Branch-dependent imports
 import java.nio.file.Path;
@@ -132,37 +135,43 @@ public final class NADCON extends Abstra
     {
         final Parameters pg  = Parameters.castOrWrap(values);
         return InterpolatedTransform.createGeodeticTransformation(factory,
-                getOrLoad(pg.getValue(LATITUDE), pg.getValue(LONGITUDE)));
+                getOrLoad(pg.getMandatoryValue(LATITUDE), pg.getMandatoryValue(LONGITUDE)));
     }
 
     /**
      * Returns the grid of the given name. This method returns the cached instance if it still exists,
      * or load the grid otherwise.
      *
-     * @param latitude   Name of the grid file for latitude shifts.
-     * @param longitude  Name of the grid file for longitude shifts.
+     * @param latitudeShifts   Name of the grid file for latitude shifts.
+     * @param longitudeShifts  Name of the grid file for longitude shifts.
      */
-    static DatumShiftGridFile<Angle,Angle> getOrLoad(final Path latitude, final Path longitude)
+    static DatumShiftGridFile<Angle,Angle> getOrLoad(final Path latitudeShifts, final Path longitudeShifts)
             throws FactoryException
     {
-        DatumShiftGridFile<?,?> grid = DatumShiftGridFile.CACHE.peek(latitude);
+        final Path rlat = DataDirectory.DATUM_CHANGES.resolve(latitudeShifts).toAbsolutePath();
+        final Path rlon = DataDirectory.DATUM_CHANGES.resolve(longitudeShifts).toAbsolutePath();
+        final Object key = new AbstractMap.SimpleImmutableEntry<>(rlat, rlon);
+        DatumShiftGridFile<?,?> grid = DatumShiftGridFile.CACHE.peek(key);
         if (grid == null) {
-            final Cache.Handler<DatumShiftGridFile<?,?>> handler = DatumShiftGridFile.CACHE.lock(latitude);
+            final Cache.Handler<DatumShiftGridFile<?,?>> handler = DatumShiftGridFile.CACHE.lock(key);
             try {
                 grid = handler.peek();
                 if (grid == null) {
                     final Loader loader;
-                    Path file = null;
+                    Path file = latitudeShifts;
                     try {
                         // Note: buffer size must be divisible by the size of 'float' data type.
                         final ByteBuffer buffer = ByteBuffer.allocate(4096).order(ByteOrder.LITTLE_ENDIAN);
                         final FloatBuffer fb = buffer.asFloatBuffer();
-                        try (final ReadableByteChannel in = Files.newByteChannel(file = latitude)) {
+                        try (final ReadableByteChannel in = Files.newByteChannel(rlat)) {
+                            DatumShiftGridLoader.log(NADCON.class, CharSequences.commonPrefix(
+                                    latitudeShifts.toString(), longitudeShifts.toString()).toString() + '…');
                             loader = new Loader(in, buffer, file);
-                            loader.readGrid(fb, null, longitude);
+                            loader.readGrid(fb, null, longitudeShifts);
                         }
                         buffer.clear();
-                        try (final ReadableByteChannel in = Files.newByteChannel(file = longitude)) {
+                        file = longitudeShifts;
+                        try (final ReadableByteChannel in = Files.newByteChannel(rlon)) {
                             new Loader(in, buffer, file).readGrid(fb, loader, null);
                         }
                     } catch (IOException | NoninvertibleTransformException | RuntimeException e) {
@@ -194,6 +203,11 @@ public final class NADCON extends Abstra
      * with values ordered from West to East. Each value is a {@code float} encoded in little endian byte order.
      * Each record ends with a 4 byte separator.</p>
      *
+     * <p>Record data use a different convention than the record header. The header uses degrees of angle with
+     * positive values East. But the offset values after the header are in seconds of angle with positive values
+     * West. The {@code DatumShiftGrid} returned by this loader uses the header convention, which also matches
+     * the order in which offset values appear in each row.</p>
+     *
      * @author  Martin Desruisseaux (Geomatys)
      * @author  Rueben Schulz (UBC)
      * @since   0.7
@@ -360,31 +374,31 @@ public final class NADCON extends Abstra
          *
          * The result is stored in the {@link #grid} field.
          *
-         * @param fb        A {@code FloatBuffer} view over the full {@link #buffer} range.
-         * @param latitude  The previously loaded latitude shifts, or {@code null} if not yet loaded.
-         * @param longitude The file for the longitude grid, or {@code null} if identical to {@link #file}.
+         * @param fb              A {@code FloatBuffer} view over the full {@link #buffer} range.
+         * @param latitudeShifts  The previously loaded latitude shifts, or {@code null} if not yet loaded.
+         * @param longitudeShifts The file for the longitude grid, or {@code null} if identical to {@link #file}.
          */
-        final void readGrid(final FloatBuffer fb, final Loader latitude, final Path longitude)
+        final void readGrid(final FloatBuffer fb, final Loader latitudeShifts, final Path longitudeShifts)
                 throws IOException, FactoryException, NoninvertibleTransformException
         {
             final int dim;
             final double scale;
-            if (latitude == null) {
+            if (latitudeShifts == null) {
                 dim   = 1;                          // Dimension of latitudes.
                 scale = DEGREES_TO_SECONDS * Δy;    // NADCON shifts are positive north.
                 grid  = new DatumShiftGridFile.Float<>(2, NonSI.DEGREE_ANGLE, NonSI.DEGREE_ANGLE,
-                        true, x0, y0, Δx, Δy, nx, ny, PARAMETERS, file, longitude);
+                        true, x0, y0, Δx, Δy, nx, ny, PARAMETERS, file, longitudeShifts);
                 grid.accuracy = SECOND_PRECISION / DEGREES_TO_SECONDS;
             } else {
-                if (x0 != latitude.x0 || Δx != latitude.Δx || nx != latitude.nx ||
-                    y0 != latitude.y0 || Δy != latitude.Δy || ny != latitude.ny || nz != latitude.nz)
+                if (x0 != latitudeShifts.x0 || Δx != latitudeShifts.Δx || nx != latitudeShifts.nx ||
+                    y0 != latitudeShifts.y0 || Δy != latitudeShifts.Δy || ny != latitudeShifts.ny || nz != latitudeShifts.nz)
                 {
                     throw new FactoryException(Errors.format(Errors.Keys.MismatchedGridGeometry_2,
-                            latitude.file.getFileName(), file.getFileName()));
+                            latitudeShifts.file.getFileName(), file.getFileName()));
                 }
                 dim   = 0;                          // Dimension of longitudes
                 scale = -DEGREES_TO_SECONDS * Δx;   // NADCON shifts are positive west.
-                grid  = latitude.grid;              // Continue writing in existing grid.
+                grid  = latitudeShifts.grid;        // Continue writing in existing grid.
             }
             final float[] array = grid.offsets[dim];
             if (ascii != null) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -42,6 +42,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.referencing.operation.transform.InterpolatedTransform;
 import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.system.DataDirectory;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.collection.Cache;
@@ -125,7 +126,7 @@ public final class NTv2 extends Abstract
             throws ParameterNotFoundException, FactoryException
     {
         final Parameters pg = Parameters.castOrWrap(values);
-        return InterpolatedTransform.createGeodeticTransformation(factory, getOrLoad(pg.getValue(FILE)));
+        return InterpolatedTransform.createGeodeticTransformation(factory, getOrLoad(pg.getMandatoryValue(FILE)));
     }
 
     /**
@@ -135,13 +136,15 @@ public final class NTv2 extends Abstract
      * @param file Name of the datum shift grid file to load.
      */
     static DatumShiftGridFile<Angle,Angle> getOrLoad(final Path file) throws FactoryException {
-        DatumShiftGridFile<?,?> grid = DatumShiftGridFile.CACHE.peek(file);
+        final Path resolved = DataDirectory.DATUM_CHANGES.resolve(file).toAbsolutePath();
+        DatumShiftGridFile<?,?> grid = DatumShiftGridFile.CACHE.peek(resolved);
         if (grid == null) {
-            final Cache.Handler<DatumShiftGridFile<?,?>> handler = DatumShiftGridFile.CACHE.lock(file);
+            final Cache.Handler<DatumShiftGridFile<?,?>> handler = DatumShiftGridFile.CACHE.lock(resolved);
             try {
                 grid = handler.peek();
                 if (grid == null) {
-                    try (final ReadableByteChannel in = Files.newByteChannel(file)) {
+                    try (final ReadableByteChannel in = Files.newByteChannel(resolved)) {
+                        DatumShiftGridLoader.log(NTv2.class, file);
                         final Loader loader = new Loader(in, file);
                         grid = loader.readGrid();
                         loader.reportWarnings();

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -405,7 +405,7 @@ public abstract class Parameters impleme
     }
 
     /**
-     * Returns the value of the parameter identified by the given descriptor.
+     * Returns the value of the parameter identified by the given descriptor, or {@code null} if none.
      * This method uses the following information from the given {@code parameter} descriptor:
      *
      * <ul>
@@ -462,6 +462,30 @@ public abstract class Parameters impleme
     }
 
     /**
+     * Returns the value of the parameter identified by the given descriptor, or throws an exception if none.
+     * The default implementation invokes {@link #getValue(ParameterDescriptor)} and verifies that the returned
+     * value is non-null.
+     *
+     * @param  <T> The type of the parameter value.
+     * @param  parameter The name or alias of the parameter to look for, together with the desired type and unit of value.
+     * @return The requested parameter value if it exists, or the {@linkplain DefaultParameterDescriptor#getDefaultValue()
+     *         default value} otherwise provided that it is not {@code null}.
+     * @throws ParameterNotFoundException if the given {@code parameter} name or alias is not legal for this group.
+     * @throws IllegalStateException if the value is not defined and there is no default value.
+     *
+     * @since 0.7
+     */
+    public <T> T getMandatoryValue(final ParameterDescriptor<T> parameter) throws ParameterNotFoundException {
+        final T value = getValue(parameter);
+        if (value != null) {
+            return value;
+        } else {
+            throw new IllegalStateException(Errors.format(Errors.Keys.MissingValueForParameter_1,
+                    Verifier.getDisplayName(parameter)));
+        }
+    }
+
+    /**
      * Returns the default value of the given descriptor, or throws an exception if the
      * descriptor does not define a default value. This check should be kept consistent
      * with the {@link DefaultParameterValue#incompatibleValue(Object)} check.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NADCONTest.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -101,7 +101,7 @@ public final strictfp class NADCONTest e
      * @throws URISyntaxException if the URL to the test file can not be converted to a path.
      * @throws IOException if an error occurred while loading the grid.
      * @throws FactoryException if an error occurred while computing the grid.
-     * @throws TransformException if an error occurred while computing the envelope.
+     * @throws TransformException if an error occurred while computing the envelope or testing the point.
      */
     @Test
     public void testLoader() throws URISyntaxException, IOException, FactoryException, TransformException {
@@ -124,7 +124,7 @@ public final strictfp class NADCONTest e
      * @param  longitudeShifts Path to the official {@code "conus.los"} file.
      * @throws IOException if an error occurred while loading the grid.
      * @throws FactoryException if an error occurred while computing the grid.
-     * @throws TransformException if an error occurred while computing the envelope.
+     * @throws TransformException if an error occurred while computing the envelope or testing the point.
      */
     public static void testNADCON(final Path latitudeShifts, final Path longitudeShifts)
             throws IOException, FactoryException, TransformException

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -74,7 +74,7 @@ public final strictfp class NTv2Test ext
      * @throws URISyntaxException if the URL to the test file can not be converted to a path.
      * @throws IOException if an error occurred while loading the grid.
      * @throws FactoryException if an error occurred while computing the grid.
-     * @throws TransformException if an error occurred while computing the envelope.
+     * @throws TransformException if an error occurred while computing the envelope or testing the point.
      */
     @Test
     public void testLoader() throws URISyntaxException, IOException, FactoryException, TransformException {
@@ -96,7 +96,7 @@ public final strictfp class NTv2Test ext
      * @param  file Path to the official {@code "NTF_R93.gsb"} file.
      * @throws IOException if an error occurred while loading the grid.
      * @throws FactoryException if an error occurred while computing the grid.
-     * @throws TransformException if an error occurred while computing the envelope.
+     * @throws TransformException if an error occurred while computing the envelope or testing the point.
      */
     public static void testRGF93(final Path file) throws IOException, FactoryException, TransformException {
         testRGF93(file, -19800, 36000, 147600, 187200);

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DatumShiftTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DatumShiftTest.java?rev=1718278&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DatumShiftTest.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DatumShiftTest.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -0,0 +1,80 @@
+/*
+ * 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.test.integration;
+
+import java.io.IOException;
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.internal.referencing.provider.NTv2Test;
+import org.apache.sis.internal.referencing.provider.NADCONTest;
+import org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolationTest;
+import org.apache.sis.internal.system.DataDirectory;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assume.*;
+
+// Branch-specific imports
+import java.nio.file.Path;
+
+
+/**
+ * Tests datum shifts using the official grid files rather than the small extracts distributed in the SIS
+ * {@code test/resources} directories. The grid files need to be stored in the {@code $SIS_DATA/DatumChanges}
+ * directory.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+@DependsOn({
+    NTv2Test.class,
+    NADCONTest.class,
+    FranceGeocentricInterpolationTest.class
+})
+public final strictfp class DatumShiftTest extends TestCase {
+    /**
+     * Tests loading an official {@code "ntf_r93.gsb"} datum shift grid file
+     * and interpolating the sample point tested by {@link FranceGeocentricInterpolationTest}.
+     *
+     * @throws IOException if the grid exists but an error occurred while loading it.
+     * @throws FactoryException if an error occurred while computing the grid.
+     * @throws TransformException if an error occurred while computing the envelope or testing the point.
+     */
+    @Test
+    public void testRGF93() throws IOException, FactoryException, TransformException {
+        final Path file = assumeDataExists(DataDirectory.DATUM_CHANGES, "ntf_r93.gsb");
+        NTv2Test.testRGF93(file);
+    }
+
+    /**
+     * Tests loading the official {@code "conus.las"} and {@code "conus.los"} datum shift grid files
+     * and interpolating a sample point tested by {@link NADCONTest}.
+     *
+     * @throws IOException if the grids exist but an error occurred while loading them.
+     * @throws FactoryException if an error occurred while computing the grid.
+     * @throws TransformException if an error occurred while computing the envelope or testing the point.
+     */
+    @Test
+    public void testNADCON() throws IOException, FactoryException, TransformException {
+        final Path latitudeShifts  = assumeDataExists(DataDirectory.DATUM_CHANGES, "conus.las");
+        final Path longitudeShifts = assumeDataExists(DataDirectory.DATUM_CHANGES, "conus.los");
+        NADCONTest.testNADCON(latitudeShifts, longitudeShifts);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DatumShiftTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/DatumShiftTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/package-info.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/package-info.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -17,11 +17,14 @@
 
 
 /**
- * Tests the integration between two ore more SIS modules.
+ * Tests the integration between two ore more SIS modules or integration with larger data.
+ * The larger data (e.g. datum shift grids) are not distributed with SIS. If desired, they
+ * must be downloaded by the user and stored in the directory identified by the {@code SIS_DATA}
+ * environment variable.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 package org.apache.sis.test.integration;

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -194,6 +194,7 @@ import org.junit.BeforeClass;
 
     org.apache.sis.referencing.operation.builder.LinearTransformBuilderTest.class,
     org.apache.sis.internal.referencing.ServicesForMetadataTest.class,
+    org.apache.sis.test.integration.DatumShiftTest.class,
     org.apache.sis.test.integration.ReferencingInMetadataTest.class,
     org.apache.sis.test.integration.DefaultMetadataTest.class
 })

Added: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java?rev=1718278&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java (added)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -0,0 +1,191 @@
+/*
+ * 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.system;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.resources.Messages;
+
+// Branch-dependent imports
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.InvalidPathException;
+
+
+/**
+ * Sub-directories of {@code SIS_DATA} where SIS looks for EPSG database, datum shift grids and other resources.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public enum DataDirectory {
+    /**
+     * The {@code "Metadata"} directory.
+     * This directory is used for storing EPSG database and other metadata.
+     */
+    METADATA,
+
+    /**
+     * The {@code "DatumChanges"} directory.
+     * This directory is used for storing datum shift grids.
+     */
+    DATUM_CHANGES,
+
+    /**
+     * The {@code "DomainsOfValidity"} directory.
+     * This directory is used for storing shapefiles for the CRS domains of validity.
+     */
+    DOMAINS_OF_VALIDITY;
+
+    /**
+     * The name of the environment variable.
+     */
+    public static final String ENV = "SIS_DATA";
+
+    /**
+     * Key of the last message logged at {@link Level#WARNING}, or {@code null} if none.
+     *
+     * @see #getRootDirectory()
+     */
+    private static short lastWarning;
+
+    /**
+     * The root directory fetched from the {@code SIS_DATA} environment variable when first needed,
+     * or {@code null} if none or not yet determined.
+     *
+     * @see #getRootDirectory()
+     */
+    private static Path rootDirectory;
+
+    /**
+     * The directory, or {@code null} if none or not yet determined.
+     *
+     * @see #getDirectory()
+     */
+    private Path directory;
+
+    /**
+     * Logs a message to the {@code "org.apache.sis.system"} logger only if different than the last warning.
+     */
+    private static void warning(final String method, final Exception e, final short key, final Object... parameters) {
+        if (key != lastWarning) {
+            lastWarning = key;
+            log(Level.WARNING, method, e, key, parameters);
+        }
+    }
+
+    /**
+     * Logs a message to the {@code "org.apache.sis.system"} logger.
+     */
+    private static void log(final Level level, final String method, final Exception e, final short key, final Object... parameters) {
+        final LogRecord record = Messages.getResources(null).getLogRecord(level, key, parameters);
+        record.setLoggerName(Loggers.SYSTEM);
+        if (e != null) {
+            record.setThrown(e);
+        }
+        Logging.log(DataDirectory.class, method, record);
+    }
+
+    /**
+     * Returns the root directory fetched from the {@code SIS_DATA} environment variable.
+     * If the environment variable is not set or the directory does not exist, then this method returns {@code null}.
+     *
+     * @return The root SIS data directory, or {@code null} if none.
+     */
+    public static synchronized Path getRootDirectory() {
+        if (rootDirectory == null) try {
+            final String dir = System.getenv(ENV);
+            if (dir == null) {
+                warning("getRootDirectory", null, Messages.Keys.DataDirectoryNotSpecified_1, ENV);
+            } else try {
+                final Path path = Paths.get(dir);
+                if (!Files.isDirectory(path)) {
+                    warning("getRootDirectory", null, Messages.Keys.DataDirectoryDoesNotExist_2, ENV, path);
+                } else if (!Files.isReadable(path)) {
+                    warning("getRootDirectory", null, Messages.Keys.DataDirectoryNotReadable_2, ENV, path);
+                } else {
+                    log(Level.CONFIG, "getRootDirectory", null, Messages.Keys.DataDirectory_2, ENV, path);
+                    rootDirectory = path;
+                }
+            } catch (InvalidPathException e) {
+                warning("getRootDirectory", e, Messages.Keys.DataDirectoryDoesNotExist_2, ENV, dir);
+            }
+        } catch (SecurityException e) {
+            warning("getRootDirectory", e, Messages.Keys.DataDirectoryNotAuthorized_1, ENV);
+        }
+        return rootDirectory;
+    }
+
+    /**
+     * Returns the sub-directory identified by this enum, or {@code null} if the parent {@code SIS_DATA}
+     * directory was not specified.
+     *
+     * @return The sub-directory, or {@code null} if unspecified.
+     */
+    public synchronized Path getDirectory() {
+        if (directory == null) {
+            final Path root = getRootDirectory();
+            if (root != null) {
+                final StringBuilder buffer = new StringBuilder(name());
+                for (int i=1; i<buffer.length(); i++) {
+                    final char c = buffer.charAt(i);
+                    if (c == '_') buffer.deleteCharAt(i);
+                    else buffer.setCharAt(i, Character.toLowerCase(c));
+                }
+                final String name = buffer.toString();
+                final Path dir = root.resolve(name);
+                try {
+                    if (Files.isDirectory(dir)) {
+                        directory = dir;
+                    } else if (Files.isWritable(root)) try {
+                        directory = Files.createDirectory(dir);
+                    } catch (IOException e) {
+                        warning("getDirectory", e, Messages.Keys.DataDirectoryNotWritable_2, ENV, root);
+                    } else {
+                        warning("getDirectory", null, Messages.Keys.DataDirectoryNotWritable_2, ENV, root);
+                    }
+                } catch (SecurityException e) {
+                    warning("getDirectory", e, Messages.Keys.DataDirectoryNotAccessible_2, ENV, name);
+                }
+            }
+        }
+        return directory;
+    }
+
+    /**
+     * If the given path is relative, returns the path as a child of the directory represented this enum.
+     * If no valid directory is configured by the {@code SIS_DATA} environment variable, then the relative
+     * path is returned as-is.
+     *
+     * @param  file The path to resolve, or {@code null}.
+     * @return The path to use, or {@code null} if the given path was null.
+     */
+    public Path resolve(Path file) {
+        if (file != null && !file.isAbsolute()) {
+            final Path dir = getDirectory();
+            if (dir != null) {
+                return dir.resolve(file);
+            }
+        }
+        return file;
+    }
+}

Propchange: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/About.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -42,17 +42,22 @@ import org.apache.sis.util.CharSequences
 import org.apache.sis.util.Version;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.logging.LoggerFactory;
+import org.apache.sis.util.resources.Messages;
 import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TreeTables;
 import org.apache.sis.util.collection.DefaultTreeTable;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.system.Modules;
+import org.apache.sis.internal.system.DataDirectory;
 
 import static java.lang.System.getProperty;
 import static org.apache.sis.util.collection.TableColumn.NAME;
 import static org.apache.sis.util.collection.TableColumn.VALUE_AS_TEXT;
 
+// Branch-dependent imports
+import java.nio.file.Path;
+
 
 /**
  * Provides information about the Apache SIS running environment.
@@ -71,7 +76,7 @@ import static org.apache.sis.util.collec
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.7
  * @module
  */
 public enum About {
@@ -112,6 +117,8 @@ public enum About {
      * <ul>
      *   <li>User directory</li>
      *   <li>Default directory</li>
+     *   <li>SIS data directory</li>
+     *   <li>Temporary directory</li>
      *   <li>Java home directory</li>
      * </ul>
      */
@@ -309,19 +316,36 @@ fill:   for (int i=0; ; i++) {
                 }
                 case 10: {
                     if (sections.contains(PATHS)) {
+                        nameKey = Vocabulary.Keys.DataDirectory;
+                        value = System.getenv(DataDirectory.ENV);
+                        if (value == null) {
+                            value = Messages.getResources(locale).getString(Messages.Keys.DataDirectoryNotSpecified_1, DataDirectory.ENV);
+                        } else {
+                            final Path path = DataDirectory.getRootDirectory();
+                            if (path != null) {
+                                value = path.toString();
+                            } else {
+                                value = value + " (" + resources.getString(Vocabulary.Keys.Invalid) + ')';
+                            }
+                        }
+                    }
+                    break;
+                }
+                case 11: {
+                    if (sections.contains(PATHS)) {
                         nameKey = Vocabulary.Keys.TemporaryFiles;
                         value = getProperty("java.io.tmpdir");
                     }
                     break;
                 }
-                case 11: {
+                case 12: {
                     if (sections.contains(PATHS)) {
                         nameKey = Vocabulary.Keys.JavaHome;
                         value = javaHome = getProperty("java.home");
                     }
                     break;
                 }
-                case 12: {
+                case 13: {
                     newSection = LIBRARIES;
                     if (sections.contains(LIBRARIES)) {
                         nameKey = Vocabulary.Keys.JavaExtensions;
@@ -329,7 +353,7 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 13: {
+                case 14: {
                     if (sections.contains(LIBRARIES)) {
                         nameKey = Vocabulary.Keys.Classpath;
                         value = classpath(getProperty("java.class.path"), false);

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -87,6 +87,43 @@ public final class Messages extends Inde
         public static final short CreatedNamedObject_2 = 16;
 
         /**
+         * The {0} environment variable is defined, but the given “{1}” value is not an existing
+         * directory.
+         */
+        public static final short DataDirectoryDoesNotExist_2 = 20;
+
+        /**
+         * Apache SIS is not authorized to access the “{1}” sub-directory in the directory given by the
+         * {0} environment variable.
+         */
+        public static final short DataDirectoryNotAccessible_2 = 26;
+
+        /**
+         * Apache SIS is not authorized to read information given by the “{0}” environment variable.
+         */
+        public static final short DataDirectoryNotAuthorized_1 = 25;
+
+        /**
+         * The “{1}” directory specified by the {0} environment variable exists but is not readable.
+         */
+        public static final short DataDirectoryNotReadable_2 = 21;
+
+        /**
+         * The “{0}” environment variable is not set.
+         */
+        public static final short DataDirectoryNotSpecified_1 = 22;
+
+        /**
+         * Apache SIS can not write in the “{1}” directory given by the {0} environment variable.
+         */
+        public static final short DataDirectoryNotWritable_2 = 23;
+
+        /**
+         * Environment variable {0} specifies the “{1}” data directory.
+         */
+        public static final short DataDirectory_2 = 24;
+
+        /**
          * Property “{0}” has been discarded in favor of “{1}”, because those two properties are
          * mutually exclusive.
          */
@@ -108,6 +145,11 @@ public final class Messages extends Inde
         public static final short IncompleteParsing_1 = 14;
 
         /**
+         * Loading datum shift file “{0}”.
+         */
+        public static final short LoadingDatumShiftFile_1 = 27;
+
+        /**
          * Text were discarded for some locales.
          */
         public static final short LocalesDiscarded = 3;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] Mon Dec  7 10:01:29 2015
@@ -20,10 +20,18 @@ ConformanceMeansDatumShift      = This r
 ConstantProjParameterValue_1    = This parameter is shown for completeness, but should never have a value different than {0} for this projection.
 CreatedNamedObject_2            = Created an instance of \u2018{0}\u2019 named \u201c{1}\u201d.
 CreatedIdentifiedObject_3       = Created an instance of \u2018{0}\u2019 named \u201c{1}\u201d with \u201c{2}\u201d identifier.
+DataDirectory_2                 = Environment variable {0} specifies the \u201c{1}\u201d data directory.
+DataDirectoryDoesNotExist_2     = The {0} environment variable is defined, but the given \u201c{1}\u201d value is not an existing directory.
+DataDirectoryNotAccessible_2    = Apache SIS is not authorized to access the \u201c{1}\u201d sub-directory in the directory given by the {0} environment variable.
+DataDirectoryNotAuthorized_1    = Apache SIS is not authorized to read information given by the \u201c{0}\u201d environment variable.
+DataDirectoryNotReadable_2      = The \u201c{1}\u201d directory specified by the {0} environment variable exists but is not readable.
+DataDirectoryNotSpecified_1     = The \u201c{0}\u201d environment variable is not set.
+DataDirectoryNotWritable_2      = Apache SIS can not write in the \u201c{1}\u201d directory given by the {0} environment variable.
 DiscardedExclusiveProperty_2    = Property \u201c{0}\u201d has been discarded in favor of \u201c{1}\u201d, because those two properties are mutually exclusive.
 IgnoredPropertiesAfterFirst_1   = Ignored properties after the first occurrence of \u2018{0}\u2019.
 IgnoredPropertyAssociatedTo_1   = Ignored property associated to \u2018{0}\u2019.
 IncompleteParsing_1             = Parsing of \u201c{0}\u201d done, but some elements were ignored.
+LoadingDatumShiftFile_1         = Loading datum shift file \u201c{0}\u201d.
 LocalesDiscarded                = Text were discarded for some locales.
 OptionalModuleNotFound_1        = Optional module \u201c{0}\u201d requested but not found.
 PropertyHiddenBy_2              = Property \u201c{0}\u201d is hidden by \u201c{1}\u201d.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] Mon Dec  7 10:01:29 2015
@@ -27,10 +27,18 @@ ConformanceMeansDatumShift      = Ce r\u
 ConstantProjParameterValue_1    = Ce param\u00e8tre est montr\u00e9 pour \u00eatre plus complet, mais sa valeur ne devrait jamais \u00eatre diff\u00e9rente de {0} pour cette projection.
 CreatedNamedObject_2            = Cr\u00e9ation d\u2019une instance de \u2018{0}\u2019 nomm\u00e9e \u00ab\u202f{1}\u202f\u00bb.
 CreatedIdentifiedObject_3       = Cr\u00e9ation d\u2019une instance de \u2018{0}\u2019 nomm\u00e9e \u00ab\u202f{1}\u202f\u00bb avec l\u2019identifiant \u00ab\u202f{2}\u202f\u00bb.
+DataDirectory_2                 = La variable environnementale {0} sp\u00e9cifie le r\u00e9pertoire de donn\u00e9es \u00ab\u202f{1}\u202f\u00bb.
+DataDirectoryDoesNotExist_2     = La variable environnementale {0} est bien d\u00e9finie, mais sa valeur \u00ab\u202f{1}\u202f\u00bb n\u2019est pas un r\u00e9pertoire existant.
+DataDirectoryNotAccessible_2    = Apache SIS n\u2019a pas l\u2019autorisation d\u2019acc\u00e9der au sous-r\u00e9pertoire \u00ab\u202f{1}\u202f\u00bb dans le r\u00e9pertoire donn\u00e9 par la variable environnementale {0}.
+DataDirectoryNotAuthorized_1    = Apache SIS n\u2019a pas l\u2019autorisation de lire des informations donn\u00e9es par la variable environnementale \u00ab\u202f{0}\u202f\u00bb.
+DataDirectoryNotReadable_2      = Le r\u00e9pertoire \u00ab\u202f{1}\u202f\u00bb sp\u00e9cifi\u00e9 par la variable environnementale {0} existe bien mais ne peut pas \u00eatre lu.
+DataDirectoryNotSpecified_1     = La variable environnementale \u00ab\u202f{0}\u202f\u00bb n\u2019est pas d\u00e9finie.
+DataDirectoryNotWritable_2      = Apache SIS ne peut pas \u00e9crire dans le r\u00e9pertoire \u00ab\u202f{1}\u202f\u00bb sp\u00e9cifi\u00e9e par la variable environnementale {0}.
 DiscardedExclusiveProperty_2    = La propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 \u00e9cart\u00e9e en faveur de \u00ab\u202f{1}\u202f\u00bb, parce que ces deux propri\u00e9t\u00e9s sont mutuellement exclusives.
 IgnoredPropertiesAfterFirst_1   = Des propri\u00e9t\u00e9s ont \u00e9t\u00e9 ignor\u00e9es apr\u00e8s la premi\u00e8re occurrence de \u2018{0}\u2019.
 IgnoredPropertyAssociatedTo_1   = Une propri\u00e9t\u00e9 associ\u00e9e \u00e0 \u2018{0}\u2019 a \u00e9t\u00e9 ignor\u00e9e.
 IncompleteParsing_1             = La lecture de \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 faite, mais en ignorant certains \u00e9l\u00e9ments.
+LoadingDatumShiftFile_1         = Chargement du fichier de changement de r\u00e9f\u00e9rentiel \u00ab\u202f{0}\u202f\u00bb.
 LocalesDiscarded                = Des textes ont \u00e9t\u00e9 ignor\u00e9s pour certaines langues.
 OptionalModuleNotFound_1        = Le module optionnel \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 demand\u00e9 mais n\u2019a pas \u00e9t\u00e9 trouv\u00e9.
 PropertyHiddenBy_2              = La propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb est masqu\u00e9e par \u00ab\u202f{1}\u202f\u00bb.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -146,6 +146,11 @@ public final class Vocabulary extends In
         public static final short CycleOmitted = 12;
 
         /**
+         * Data directory
+         */
+        public static final short DataDirectory = 88;
+
+        /**
          * Daylight time
          */
         public static final short DaylightTime = 13;
@@ -221,6 +226,11 @@ public final class Vocabulary extends In
         public static final short Index = 22;
 
         /**
+         * Invalid
+         */
+        public static final short Invalid = 89;
+
+        /**
          * Java extensions
          */
         public static final short JavaExtensions = 23;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] Mon Dec  7 10:01:29 2015
@@ -32,6 +32,7 @@ Correlation             = Correlation
 CurrentDateTime         = Current date and time
 CurrentDirectory        = Current directory
 CycleOmitted            = Cycle omitted
+DataDirectory           = Data directory
 DaylightTime            = Daylight time
 DefaultValue            = Default value
 Description             = Description
@@ -47,6 +48,7 @@ Identifier              = Identifier
 Implementation          = Implementation
 InBetweenWords          = \u2002in\u2002
 Index                   = Index
+Invalid                 = Invalid
 JavaExtensions          = Java extensions
 JavaHome                = Java home directory
 Julian                  = Julian

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties?rev=1718278&r1=1718277&r2=1718278&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] Mon Dec  7 10:01:29 2015
@@ -39,6 +39,7 @@ Correlation             = Corr\u00e9lati
 CurrentDateTime         = Date et heure courantes
 CurrentDirectory        = R\u00e9pertoire courant
 CycleOmitted            = Cycle omit
+DataDirectory           = R\u00e9pertoire des donn\u00e9es
 DaylightTime            = Heure normale
 DefaultValue            = Valeur par d\u00e9faut
 Description             = Description
@@ -54,6 +55,7 @@ Identifier              = Identifiant
 Implementation          = Impl\u00e9mentation
 InBetweenWords          = \u2002dans\u2002
 Index                   = Index
+Invalid                 = Invalide
 JavaExtensions          = Extensions du Java
 JavaHome                = R\u00e9pertoire du Java
 Julian                  = Julien

Added: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java?rev=1718278&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java (added)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java [UTF-8] Mon Dec  7 10:01:29 2015
@@ -0,0 +1,64 @@
+/*
+ * 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.test;
+
+import java.io.IOException;
+import org.apache.sis.internal.system.DataDirectory;
+
+// Branch-specific imports
+import java.nio.file.Path;
+import java.nio.file.Files;
+
+
+/**
+ * Assumption methods used by the SIS project in addition of the JUnit ones.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public final strictfp class Assume extends org.junit.Assume {
+    /**
+     * Do not allow instantiation.
+     */
+    private Assume() {
+    }
+
+    /**
+     * Assumes that the {@code SIS_DATA} environment variable is defined, that the directory
+     * exists and contains the given file. If this condition fails, then the test is skipped.
+     *
+     * <p>This is used for tests that require data not distributed with SIS.
+     * Examples of data not distributed with SIS are datum shift grids.
+     * If desired, those grids need to be downloaded by the user and stored in the directory
+     * identified by the {@code SIS_DATA} environment variable.</p>
+     *
+     * @param  type The directory where to search for the given file.
+     * @param  file The file that needs to exist.
+     * @return The path to the given file.
+     * @throws IOException if the directory exists but a problem occurred while reading it.
+     */
+    public static Path assumeDataExists(final DataDirectory type, final String file) throws IOException {
+        assumeNotNull(System.getenv(DataDirectory.ENV));
+        Path path = type.getDirectory();
+        assumeNotNull(path);
+        path = path.resolve(file);
+        assumeTrue(Files.isReadable(path));
+        return path;
+    }
+}

Propchange: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8