sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1803070 [11/20] - in /sis/branches/JDK9: ./ application/sis-console/src/main/java/org/apache/sis/console/ core/sis-build-helper/ core/sis-build-helper/src/main/java/org/apache/sis/internal/book/ core/sis-build-helper/src/main/java/org/apac...
Date Wed, 26 Jul 2017 16:14:14 GMT
Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/NTv2Test.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -16,13 +16,11 @@
  */
 package org.apache.sis.internal.referencing.provider;
 
-import java.net.URL;
 import java.net.URISyntaxException;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.nio.file.Files;
 import java.nio.file.StandardOpenOption;
 import java.nio.channels.WritableByteChannel;
@@ -35,7 +33,6 @@ import org.apache.sis.referencing.operat
 import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.geometry.Envelopes;
 import org.apache.sis.measure.Units;
-import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.opengis.test.Assert.*;
@@ -53,7 +50,7 @@ import static org.opengis.test.Assert.*;
  * @since 0.7
  * @module
  */
-public final strictfp class NTv2Test extends TestCase {
+public final strictfp class NTv2Test extends DatumShiftTestCase {
     /**
      * Name of the file containing a small extract of the "{@code NTF_R93.gsb}" file.
      * The amount of data in this test file is less than 0.14% of the original file.
@@ -76,9 +73,7 @@ public final strictfp class NTv2Test ext
      */
     @Test
     public void testLoader() throws URISyntaxException, IOException, FactoryException, TransformException {
-        final URL url = NTv2Test.class.getResource(TEST_FILE);
-        assertNotNull("Test file \"" + TEST_FILE + "\" not found.", url);
-        testRGF93(Paths.get(url.toURI()),
+        testRGF93(getResource(TEST_FILE),
                  36000 - 360 * (72 + 5),    // Subgrid of RGF93 beginning at gridX = 72
                  36000 - 360 * (72),        // Subgrid uses 6 cells along longitude axis
                 147600 + 360 * (74),        // Subgrid of RGF93 beginning at gridY = 74

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -124,6 +124,8 @@ public final strictfp class ProvidersTes
             PositionVector7Param3D.class,
             GeocentricTranslation2D.class,
             GeocentricTranslation3D.class,
+            Geographic3Dto2D.class,
+            Geographic2Dto3D.class,
             Molodensky.class,
             AbridgedMolodensky.class,
             FranceGeocentricInterpolation.class

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -157,7 +157,7 @@ public final strictfp class ParametersTe
         final ParameterValueGroup source = descriptor.createValue();
         final ParameterValueGroup sourceSubgroup = source.addGroup(subgroupName);
         final ParameterValue<?> o1 = sourceSubgroup.parameter("Optional 4");
-        final ParameterValue<?> o2 = o1.getDescriptor().createValue(); // See ParameterFormatTest.testMultiOccurrence()
+        final ParameterValue<?> o2 = o1.getDescriptor().createValue();      // See ParameterFormatTest.testMultiOccurrence()
         sourceSubgroup.parameter("Mandatory 2").setValue(20);
         sourceSubgroup.values().add(o2);
         o1.setValue(40);
@@ -169,8 +169,8 @@ public final strictfp class ParametersTe
          */
         final ParameterValueGroup target = descriptor.createValue();
         final ParameterValueGroup targetSubgroup = target.addGroup(subgroupName);
-        targetSubgroup.parameter("Mandatory 1").setValue(-10);  // We expect this value to be overwritten.
-        targetSubgroup.parameter("Optional 3") .setValue( 30);  // We expect this value to be preserved.
+        targetSubgroup.parameter("Mandatory 1").setValue(-10);      // We expect this value to be overwritten.
+        targetSubgroup.parameter("Optional 3") .setValue( 30);      // We expect this value to be preserved.
         target.parameter("A parent parameter") .setValue("A value to be overwritten");
         /*
          * The actual test.
@@ -179,12 +179,11 @@ public final strictfp class ParametersTe
         assertSame(sourceSubgroup, TestUtilities.getSingleton(source.groups(subgroupName)));
         assertSame(targetSubgroup, TestUtilities.getSingleton(target.groups(subgroupName)));
         assertEquals("A value from the source", target.parameter("A parent parameter").getValue());
-        assertEquals("Mandatory 1", 10, targetSubgroup.parameter("Mandatory 1").intValue());
-        assertEquals("Mandatory 2", 20, targetSubgroup.parameter("Mandatory 2").intValue());
-        assertEquals("Optional 3",  30, targetSubgroup.parameter("Optional 3") .intValue());
-        assertEquals("Optional 4",  40, targetSubgroup.parameter("Optional 4") .intValue());
-        assertEquals("Optional 4 (second occurrence)", 50,
-                ((ParameterValue<?>) targetSubgroup.values().get(4)).intValue());
+        assertEquals("Mandatory 1",    10, targetSubgroup.parameter("Mandatory 1").intValue());
+        assertEquals("Mandatory 2",    20, targetSubgroup.parameter("Mandatory 2").intValue());
+        assertEquals("Optional 3",     30, targetSubgroup.parameter("Optional 3") .intValue());
+        assertEquals("Optional 4",     40, ((ParameterValue<?>) targetSubgroup.values().get(3)).intValue());
+        assertEquals("Optional 4 bis", 50, ((ParameterValue<?>) targetSubgroup.values().get(4)).intValue());
     }
 
     /**

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -151,12 +151,12 @@ public final strictfp class CRSTest exte
     }
 
     /**
-     * Tests {@link CRS#suggestTargetCRS(GeographicBoundingBox, CoordinateReferenceSystem...)}.
+     * Tests {@link CRS#suggestCommonTarget(GeographicBoundingBox, CoordinateReferenceSystem...)}.
      *
      * @since 0.8
      */
     @Test
-    public void testSuggestTargetCRS() {
+    public void testSuggestCommonTarget() {
         /*
          * Prepare 4 CRS with different datum (so we can more easily differentiate them in the assertions) and
          * different domain of validity. CRS[1] is given a domain large enough for all CRS except the last one.
@@ -185,34 +185,34 @@ public final strictfp class CRSTest exte
          * of validity large enough for all CRS; this is the second CRS created in above 'switch' statement.
          */
         assertSame("Expected CRS with widest domain of validity.", crs[1],
-                   CRS.suggestTargetCRS(null, overlappingCRS));
+                   CRS.suggestCommonTarget(null, overlappingCRS));
         /*
          * If we specify a smaller region of interest, we should get the CRS having the smallest domain of validity that
          * cover the ROI. Following lines gradually increase the ROI size and verify that we get CRS for larger domain.
          */
         final DefaultGeographicBoundingBox regionOfInterest = new DefaultGeographicBoundingBox(-1, +1, 2.1, 2.9);
         assertSame("Expected best fit for [2.1 … 2.9]°N", crs[2],
-                   CRS.suggestTargetCRS(regionOfInterest, overlappingCRS));
+                   CRS.suggestCommonTarget(regionOfInterest, overlappingCRS));
 
         regionOfInterest.setNorthBoundLatitude(3.1);
         assertSame("Expected best fit for [2.1 … 3.1]°N", crs[0],
-                   CRS.suggestTargetCRS(regionOfInterest, overlappingCRS));
+                   CRS.suggestCommonTarget(regionOfInterest, overlappingCRS));
 
         regionOfInterest.setSouthBoundLatitude(1.9);
         assertSame("Expected best fit for [1.9 … 3.1]°N", crs[1],
-                   CRS.suggestTargetCRS(regionOfInterest, overlappingCRS));
+                   CRS.suggestCommonTarget(regionOfInterest, overlappingCRS));
         /*
          * All above tests returned one of the CRS in the given array. Test now a case where none of those CRS
-         * have a domain of validity wide enough, so suggestTargetCRS(…) need to search among the base CRS.
+         * have a domain of validity wide enough, so suggestCommonTarget(…) need to search among the base CRS.
          */
         assertSame("Expected a GeodeticCRS since none of the ProjectedCRS have a domain of validity wide enough.",
-                   crs[0].getBaseCRS(), CRS.suggestTargetCRS(null, crs));
+                   crs[0].getBaseCRS(), CRS.suggestCommonTarget(null, crs));
         /*
-         * With the same domain of validity than above, suggestTargetCRS(…) should not need to fallback on the
+         * With the same domain of validity than above, suggestCommonTarget(…) should not need to fallback on the
          * base CRS anymore.
          */
         assertSame("Expected best fit for [1.9 … 3.1]°N", crs[1],
-                   CRS.suggestTargetCRS(regionOfInterest, crs));
+                   CRS.suggestCommonTarget(regionOfInterest, crs));
     }
 
     /**

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -27,6 +27,8 @@ import java.sql.Connection;
 import java.sql.Statement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import org.hsqldb.jdbc.JDBCDataSource;
+import org.postgresql.ds.PGSimpleDataSource;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.ProjectedCRS;
@@ -129,13 +131,13 @@ public final strictfp class EPSGInstalle
     @Test
     public void testCreationOnDerby() throws Exception {
         final InstallationScriptProvider scripts = getScripts();            // Needs to be invoked first.
-        final DataSource ds = TestDatabase.create("test");
+        final DataSource ds = TestDatabase.create("EPSGInstaller");
         try {
             createAndTest(ds, scripts);
         } finally {
             TestDatabase.drop(ds);
         }
-        loggings.assertNextLogContains("EPSG", "jdbc:derby:memory:test");
+        loggings.assertNextLogContains("EPSG", "jdbc:derby:memory:EPSGInstaller");
         loggings.assertNoUnexpectedLog();
     }
 
@@ -148,8 +150,8 @@ public final strictfp class EPSGInstalle
     @Test
     public void testCreationOnHSQLDB() throws Exception {
         final InstallationScriptProvider scripts = getScripts();            // Needs to be invoked first.
-        final DataSource ds = (DataSource) Class.forName("org.hsqldb.jdbc.JDBCDataSource").newInstance();
-        ds.getClass().getMethod("setURL", String.class).invoke(ds, "jdbc:hsqldb:mem:test");
+        final JDBCDataSource ds = new JDBCDataSource();
+        ds.setURL("jdbc:hsqldb:mem:EPSGInstaller");
         try {
             createAndTest(ds, scripts);
         } finally {
@@ -157,7 +159,7 @@ public final strictfp class EPSGInstalle
                 s.execute("SHUTDOWN");
             }
         }
-        loggings.assertNextLogContains("EPSG", "jdbc:hsqldb:mem:test");
+        loggings.assertNextLogContains("EPSG", "jdbc:hsqldb:mem:EPSGInstaller");
         loggings.assertNoUnexpectedLog();
     }
 
@@ -176,10 +178,9 @@ public final strictfp class EPSGInstalle
     @Ignore("This test need to be run manually on a machine having a local PostgreSQL database.")
     public void testCreationOnPostgreSQL() throws Exception {
         final InstallationScriptProvider scripts = getScripts();            // Needs to be invoked first.
-        final DataSource ds = (DataSource) Class.forName("org.postgresql.ds.PGSimpleDataSource").newInstance();
-        final Class<?> dsc = ds.getClass();
-        dsc.getMethod("setServerName",   String.class).invoke(ds, "localhost");
-        dsc.getMethod("setDatabaseName", String.class).invoke(ds, "SpatialMetadataTest");
+        final PGSimpleDataSource ds = new PGSimpleDataSource();
+        ds.setServerName("localhost");
+        ds.setDatabaseName("SpatialMetadataTest");
         createAndTest(ds, scripts);
         loggings.assertNextLogContains("EPSG", "jdbc:postgresql://localhost/SpatialMetadataTest");
         loggings.assertNoUnexpectedLog();

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -67,6 +67,7 @@ import static org.apache.sis.test.Assert
 
 /**
  * Tests {@link CoordinateOperationFinder}.
+ * Contrarily to {@link CoordinateOperationRegistryTest}, tests in this class are run without EPSG geodetic dataset.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 0.8
@@ -103,7 +104,7 @@ public final strictfp class CoordinateOp
     /**
      * The instance on which to execute the tests.
      */
-    private CoordinateOperationFinder inference;
+    private CoordinateOperationFinder finder;
 
     /**
      * Creates a new test case.
@@ -111,7 +112,7 @@ public final strictfp class CoordinateOp
      * @throws FactoryException if an error occurred while initializing the finder to test.
      */
     public CoordinateOperationFinderTest() throws FactoryException {
-        inference = new CoordinateOperationFinder(null, factory, null);
+        finder = new CoordinateOperationFinder(null, factory, null);
     }
 
     /**
@@ -184,13 +185,13 @@ public final strictfp class CoordinateOp
      * Implementation of {@link #testIdentityTransform()} using the given CRS.
      */
     private void testIdentityTransform(final CoordinateReferenceSystem crs) throws FactoryException {
-        final CoordinateOperation operation = inference.createOperation(crs, crs);
+        final CoordinateOperation operation = finder.createOperation(crs, crs);
         assertSame      ("sourceCRS",  crs, operation.getSourceCRS());
         assertSame      ("targetCRS",  crs, operation.getTargetCRS());
         assertTrue      ("isIdentity", operation.getMathTransform().isIdentity());
         assertTrue      ("accuracy",   operation.getCoordinateOperationAccuracy().isEmpty());
         assertInstanceOf("operation",  Conversion.class, operation);
-        inference = new CoordinateOperationFinder(null, factory, null);        // Reset for next call.
+        finder = new CoordinateOperationFinder(null, factory, null);        // Reset for next call.
     }
 
     /**
@@ -265,7 +266,7 @@ public final strictfp class CoordinateOp
             final GeographicCRS sourceCRS, final GeographicCRS targetCRS)
             throws ParseException, FactoryException, TransformException
     {
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS",  sourceCRS,            operation.getSourceCRS());
         assertSame      ("targetCRS",  targetCRS,            operation.getTargetCRS());
         assertFalse     ("isIdentity",                       operation.getMathTransform().isIdentity());
@@ -325,7 +326,7 @@ public final strictfp class CoordinateOp
                 "  Id[“EPSG”, “4807”]]");
 
         final GeographicCRS       targetCRS = CommonCRS.WGS84.geographic();
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
 
         assertSame      ("sourceCRS",  sourceCRS,            operation.getSourceCRS());
         assertSame      ("targetCRS",  targetCRS,            operation.getTargetCRS());
@@ -371,7 +372,7 @@ public final strictfp class CoordinateOp
                 "    Unit[“kilometre”, 1000]]");
 
         final GeocentricCRS       targetCRS = CommonCRS.WGS84.geocentric();
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
 
         assertSame      ("sourceCRS",  sourceCRS,            operation.getSourceCRS());
         assertSame      ("targetCRS",  targetCRS,            operation.getTargetCRS());
@@ -425,7 +426,7 @@ public final strictfp class CoordinateOp
                 "    Axis[“y”, NORTH],\n" +
                 "    Unit[“US survey foot”, 0.304800609601219]]");
 
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
         assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
         assertEquals    ("name",      "TM",             operation.getName().getCode());
@@ -453,6 +454,72 @@ public final strictfp class CoordinateOp
     }
 
     /**
+     * Tests a datum shift applied as a position vector transformation in geocentric domain.
+     * This test does not use the the EPSG geodetic dataset.
+     *
+     * @throws ParseException if a CRS used in this test can not be parsed.
+     * @throws FactoryException if the operation can not be created.
+     * @throws TransformException if an error occurred while converting the test points.
+     *
+     * @see DefaultCoordinateOperationFactoryTest#testPositionVectorTransformation()
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-364">SIS-364</a>
+     *
+     * @since 0.8
+     */
+    @Test
+    @DependsOnMethod("testGeographicToProjected")
+    public void testPositionVectorTransformation() throws ParseException, FactoryException, TransformException {
+        final CoordinateReferenceSystem sourceCRS = CommonCRS.WGS84.geographic();
+        final CoordinateReferenceSystem targetCRS = parse(AGD66());
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
+        transform  = operation.getMathTransform();
+        tolerance  = LINEAR_TOLERANCE;
+        λDimension = new int[] {0};
+        verifyTransform(expectedAGD66(true), expectedAGD66(false));
+        validate();
+    }
+
+    /**
+     * Returns test coordinates for a transformation between {@link #AGD66()} and WGS84.
+     * We use this method for ensuring that {@link #testPositionVectorTransformation()}
+     * and {@link DefaultCoordinateOperationFactoryTest#testPositionVectorTransformation()}
+     * use the same data, as specified in {@link #AGD66()} contract.
+     *
+     * @param  WGS84  {@code true} for the WGS84 input, or {@code false} for the AGD66 output.
+     */
+    static double[] expectedAGD66(final boolean WGS84) {
+        return WGS84 ? new double[] {-37.84, 114.0} : new double[] {763850.64, 5807560.94};
+    }
+
+    /**
+     * Returns the WKT for a CRS using the Australian Geodetic Datum 1966. This method returns a WKT 1 string
+     * with a {@code TOWGS84} element that should help Apache SIS to produce the same result regardless if an
+     * EPSG geodetic dataset is used or not.
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-364">SIS-364</a>
+     */
+    static String AGD66() {
+        return "PROJCS[“AGD66 / AMG zone 49”,"
+                + "GEOGCS[“AGD66”, "
+                +   "DATUM[“Australian_Geodetic_Datum_1966”, "
+                +     "SPHEROID[“Australian National Spheroid”,6378160, 298.25, AUTHORITY[“EPSG”,“7003”]],"
+                +     "TOWGS84[-117.808,-51.536,137.784,0.303,0.446,0.234,-0.29], AUTHORITY[“EPSG”,“6202”]],"
+                +     "PRIMEM[“Greenwich”, 0, AUTHORITY[“EPSG”,“8901”]],"
+                +     "UNIT[“degree”, 0.0174532925199433, AUTHORITY[“EPSG”,“9122”]],"
+                +   "AUTHORITY[“EPSG”,“4202”]],"
+                +   "PROJECTION[“Transverse_Mercator”],"
+                +   "PARAMETER[“latitude_of_origin”, 0],"
+                +   "PARAMETER[“central_meridian”, 111],"
+                +   "PARAMETER[“scale_factor”, 0.9996],"
+                +   "PARAMETER[“false_easting”, 500000],"
+                +   "PARAMETER[“false_northing”, 10000000],"
+                +   "UNIT[“metre”,1,AUTHORITY[“EPSG”,“9001”]],"
+                +   "AXIS[“Easting”,EAST],"
+                +   "AXIS[“Northing”,NORTH],"
+                + "AUTHORITY[“EPSG”,“20249”]]";
+    }
+
+    /**
      * Tests that an exception is thrown on attempt to grab a transformation between incompatible vertical CRS.
      *
      * @throws FactoryException if an exception other than the expected one occurred.
@@ -463,7 +530,7 @@ public final strictfp class CoordinateOp
         final VerticalCRS sourceCRS = CommonCRS.Vertical.NAVD88.crs();
         final VerticalCRS targetCRS = CommonCRS.Vertical.MEAN_SEA_LEVEL.crs();
         try {
-            inference.createOperation(sourceCRS, targetCRS);
+            finder.createOperation(sourceCRS, targetCRS);
             fail("The operation should have failed.");
         } catch (OperationNotFoundException e) {
             final String message = e.getMessage();
@@ -485,7 +552,7 @@ public final strictfp class CoordinateOp
     public void testTemporalConversion() throws FactoryException, TransformException {
         final TemporalCRS sourceCRS = CommonCRS.Temporal.UNIX.crs();
         final TemporalCRS targetCRS = CommonCRS.Temporal.MODIFIED_JULIAN.crs();
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
         assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
         assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
@@ -524,7 +591,7 @@ public final strictfp class CoordinateOp
         // NOTE: make sure that the 'sourceCRS' below is not equal to any other 'sourceCRS' created in this class.
         final CompoundCRS   sourceCRS = compound("Test4D", CommonCRS.WGS84.geographic3D(), CommonCRS.Temporal.UNIX.crs());
         final GeographicCRS targetCRS = CommonCRS.WGS84.geographic();
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
         assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
 
@@ -561,7 +628,7 @@ public final strictfp class CoordinateOp
     public void testGeographic3D_to_2D() throws FactoryException, TransformException {
         final GeographicCRS sourceCRS = CommonCRS.WGS84.geographic3D();
         final GeographicCRS targetCRS = CommonCRS.WGS84.geographic();
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
         assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
         assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
@@ -604,7 +671,7 @@ public final strictfp class CoordinateOp
     public void testGeographic2D_to_3D() throws FactoryException, TransformException {
         final GeographicCRS sourceCRS = CommonCRS.WGS84.geographic();
         final GeographicCRS targetCRS = CommonCRS.WGS84.geographic3D();
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
         assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
         assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
@@ -648,7 +715,7 @@ public final strictfp class CoordinateOp
     public void testGeographic3D_to_EllipsoidalHeight() throws FactoryException, TransformException {
         final CoordinateReferenceSystem sourceCRS = CommonCRS.WGS84.geographic3D();
         final CoordinateReferenceSystem targetCRS = HardCodedCRS.ELLIPSOIDAL_HEIGHT_cm;
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
         assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
         assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
@@ -688,7 +755,7 @@ public final strictfp class CoordinateOp
         // NOTE: make sure that the 'sourceCRS' below is not equal to any other 'sourceCRS' created in this class.
         final CompoundCRS sourceCRS = compound("Test4D", CommonCRS.WGS84.geographic3D(), CommonCRS.Temporal.JULIAN.crs());
         final VerticalCRS targetCRS = CommonCRS.Vertical.ELLIPSOIDAL.crs();
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
         assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
         assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
@@ -750,7 +817,7 @@ public final strictfp class CoordinateOp
         sourceCRS = compound("Mercator 3D", sourceCRS, CommonCRS.Vertical.ELLIPSOIDAL.crs());
         sourceCRS = compound("Mercator 4D", sourceCRS, CommonCRS.Temporal.MODIFIED_JULIAN.crs());
 
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame("sourceCRS", sourceCRS, operation.getSourceCRS());
         assertSame("targetCRS", targetCRS, operation.getTargetCRS());
 
@@ -793,7 +860,7 @@ public final strictfp class CoordinateOp
         // NOTE: make sure that the 'sourceCRS' below is not equal to any other 'sourceCRS' created in this class.
         final CompoundCRS sourceCRS = compound("Test3D", CommonCRS.WGS84.geographic(),   CommonCRS.Temporal.UNIX.crs());
         final CompoundCRS targetCRS = compound("Test4D", CommonCRS.WGS84.geographic3D(), CommonCRS.Temporal.MODIFIED_JULIAN.crs());
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame      ("sourceCRS", sourceCRS, operation.getSourceCRS());
         assertSame      ("targetCRS", targetCRS, operation.getTargetCRS());
         assertInstanceOf("operation", ConcatenatedOperation.class, operation);
@@ -843,7 +910,7 @@ public final strictfp class CoordinateOp
                     0,   0,   1
                 })), HardCodedCS.DISPLAY);
 
-        final CoordinateOperation operation = inference.createOperation(sourceCRS, targetCRS);
+        final CoordinateOperation operation = finder.createOperation(sourceCRS, targetCRS);
         assertSame("sourceCRS", sourceCRS, operation.getSourceCRS());
         assertSame("targetCRS", targetCRS, operation.getTargetCRS());
 

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -49,9 +49,11 @@ import static org.junit.Assume.*;
 
 
 /**
- * Tests {@link CoordinateOperationRegistry}.
- * This class tests the following operations:
+ * Tests {@link CoordinateOperationRegistry} using the EPSG geodetic dataset.
+ * If no EPSG geodetic dataset is available in the running environment, then tests are skipped.
+ * For tests without the need of an EPSG database, see {@link CoordinateOperationFinderTest}.
  *
+ * <p>This class tests the following operations:</p>
  * <ul>
  *   <li><cite>"NTF (Paris) to WGS 84 (1)"</cite> operation (EPSG:8094), which implies a longitude rotation
  *       followed by a geocentric translation in the geographic domain.</li>

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -32,6 +32,7 @@ import org.apache.sis.internal.util.Cons
 import org.apache.sis.geometry.DirectPosition2D;
 import org.apache.sis.io.wkt.WKTFormat;
 import org.apache.sis.referencing.CRS;
+import org.apache.sis.referencing.CommonCRS;
 
 // Test dependencies
 import org.apache.sis.referencing.operation.transform.MathTransformTestCase;
@@ -45,10 +46,17 @@ import static org.apache.sis.test.Refere
 
 
 /**
- * Tests {@link DefaultCoordinateOperationFactory}.
+ * Tests {@link DefaultCoordinateOperationFactory}, with or without EPSG geodetic dataset.
+ *
+ * <p><b>Relationship with other tests:</b></p>
+ * <ul>
+ *   <li>{@link CoordinateOperationRegistryTest} requires an EPSG geodetic dataset (otherwise tests are skipped).</li>
+ *   <li>{@link CoordinateOperationFinderTest} do not use any EPSG geodetic dataset.</li>
+ *   <li>{@code DefaultCoordinateOperationFactoryTest} is a mix of both.</li>
+ * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.7
  * @module
  */
@@ -314,4 +322,32 @@ public final strictfp class DefaultCoord
         assertEquals("Easting should be unchanged", sourcePt.getX(),  targetPt.getX(), STRICT);
         assertEquals("Expected 27 km shift", 27476, targetPt.getY() - sourcePt.getY(), tolerance);
     }
+
+    /**
+     * Tests a datum shift applied as a position vector transformation in geocentric domain.  This method performs
+     * the same test than {@link CoordinateOperationFinderTest#testPositionVectorTransformation()} except that the
+     * EPSG geodetic dataset may be used. The result however should be the same because of the {@code TOWGS84}
+     * parameter in the WKT used for the test.
+     *
+     * @throws ParseException if a CRS used in this test can not be parsed.
+     * @throws FactoryException if the operation can not be created.
+     * @throws TransformException if an error occurred while converting the test points.
+     *
+     * @see CoordinateOperationFinderTest#testPositionVectorTransformation()
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-364">SIS-364</a>
+     *
+     * @since 0.8
+     */
+    @Test
+    public void testPositionVectorTransformation() throws ParseException, FactoryException, TransformException {
+        final CoordinateReferenceSystem sourceCRS = CommonCRS.WGS84.geographic();
+        final CoordinateReferenceSystem targetCRS = parse(CoordinateOperationFinderTest.AGD66());
+        final CoordinateOperation operation = factory.createOperation(sourceCRS, targetCRS);
+        transform  = operation.getMathTransform();
+        tolerance  = Formulas.LINEAR_TOLERANCE;
+        λDimension = new int[] {0};
+        verifyTransform(CoordinateOperationFinderTest.expectedAGD66(true),
+                        CoordinateOperationFinderTest.expectedAGD66(false));
+        validate();
+    }
 }

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/Benchmark.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/Benchmark.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/Benchmark.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/Benchmark.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -28,6 +28,7 @@ import org.apache.sis.math.StatisticsFor
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.util.StandardDateFormat;
 import org.apache.sis.internal.referencing.provider.AbstractProvider;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
@@ -216,7 +217,7 @@ public final class Benchmark {
             long time = System.nanoTime();
             projection.transform(sources, 0, targets, 0, NUM_POINTS);
             time = System.nanoTime() - time;
-            final double seconds = time * NANOS_TO_SECONDS;
+            final double seconds = time / (double) StandardDateFormat.NANOS_PER_SECOND;
             System.out.printf("%s time: %1.4f%n", performance.name(), seconds);
             performance.accept(seconds);
         }
@@ -231,15 +232,10 @@ public final class Benchmark {
             kernel.transform(targets, 0, targets, 0, NUM_POINTS);
             time = System.nanoTime() - time;
             denormalize.transform(targets, 0, targets, 0, NUM_POINTS);
-            final double seconds = time * NANOS_TO_SECONDS;
+            final double seconds = time / (double) StandardDateFormat.NANOS_PER_SECOND;
             System.out.printf("%s time: %1.4f%n", performance.name(), seconds);
             performance.accept(seconds);
         }
-
-        /**
-         * For reporting the time measured by {@link System#nanoTime()}.
-         */
-        private static final double NANOS_TO_SECONDS = 1E-9;
     }
 
     /**

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorMethodComparison.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -27,6 +27,7 @@ import org.apache.sis.internal.referenci
 import org.apache.sis.internal.metadata.ReferencingServices;
 
 import static java.lang.Math.*;     // Not StrictMath in this particular case.
+import static org.apache.sis.internal.util.StandardDateFormat.NANOS_PER_SECOND;
 
 
 /**
@@ -323,9 +324,9 @@ public final class MercatorMethodCompari
         }
         final long t3 = System.nanoTime();
         final float c = (t1 - t0) / 100f;
-        out.println("Iterative method:         " + ((t1 - t0) / 1E9f) + " seconds (" + round((t1 - t0) / c) + "%).");
-        out.println("Series expansion:         " + ((t2 - t1) / 1E9f) + " seconds (" + round((t2 - t1) / c) + "%).");
-        out.println("Trigonometric identities: " + ((t3 - t2) / 1E9f) + " seconds (" + round((t3 - t2) / c) + "%).");
+        out.println("Iterative method:         " + ((t1 - t0) / (float) NANOS_PER_SECOND) + " seconds (" + round((t1 - t0) / c) + "%).");
+        out.println("Series expansion:         " + ((t2 - t1) / (float) NANOS_PER_SECOND) + " seconds (" + round((t2 - t1) / c) + "%).");
+        out.println("Trigonometric identities: " + ((t3 - t2) / (float) NANOS_PER_SECOND) + " seconds (" + round((t3 - t2) / c) + "%).");
         out.println("Mean φ values: " + (s0 / t.length) + ", "
                                       + (s1 / t.length) + " and "
                                       + (s2 / t.length) + ".");

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -239,7 +239,7 @@ public final strictfp class EllipsoidToC
     }
 
     /**
-     * Tests {@link EllipsoidToCentricTransform#concatenate(MathTransform, boolean, MathTransformFactory)}.
+     * Tests {@link EllipsoidToCentricTransform#tryConcatenate(boolean, MathTransform, MathTransformFactory)}.
      * The test creates <cite>"Geographic 3D to 2D conversion"</cite>, <cite>"Geographic/Geocentric conversions"</cite>
      * and <cite>"Geocentric translation"</cite> transforms, then concatenate them.
      *

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -34,14 +34,13 @@ import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.DependsOnMethod;
 import org.junit.Test;
 
-import static org.opengis.test.Assert.*;
 
 
 /**
  * Tests {@link InterpolatedGeocentricTransform}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.7
  * @module
  */
@@ -64,8 +63,7 @@ public strictfp class InterpolatedGeocen
      * Creates the transform using the given provider.
      */
     final void createGeodeticTransformation(final FranceGeocentricInterpolation provider) throws FactoryException {
-        final URL file = FranceGeocentricInterpolationTest.class.getResource(FranceGeocentricInterpolationTest.TEST_FILE);
-        assertNotNull("Test file \"" + FranceGeocentricInterpolationTest.TEST_FILE + "\" not found.", file);
+        final URL file = FranceGeocentricInterpolationTest.getResourceAsConvertibleURL(FranceGeocentricInterpolationTest.TEST_FILE);
         final Ellipsoid source = HardCodedDatum.NTF.getEllipsoid();     // Clarke 1880 (IGN)
         final Ellipsoid target = CommonCRS.ETRS89.ellipsoid();          // GRS 1980 ellipsoid
         final ParameterValueGroup values = provider.getParameters().createValue();

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedTransformTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedTransformTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -34,7 +34,6 @@ import org.apache.sis.test.DependsOnMeth
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
 
-import static org.junit.Assert.assertNotNull;
 
 
 /**
@@ -57,8 +56,7 @@ public final strictfp class Interpolated
      * @throws FactoryException if an error occurred while loading the grid.
      */
     private void createRGF93() throws FactoryException {
-        final URL file = NTv2Test.class.getResource(NTv2Test.TEST_FILE);
-        assertNotNull("Test file \"" + NTv2Test.TEST_FILE + "\" not found.", file);
+        final URL file = NTv2Test.getResourceAsConvertibleURL(NTv2Test.TEST_FILE);
         final NTv2 provider = new NTv2();
         final ParameterValueGroup values = provider.getParameters().createValue();
         values.parameter("Latitude and longitude difference file").setValue(file);    // Automatic conversion from URL to Path.
@@ -73,10 +71,8 @@ public final strictfp class Interpolated
      * @throws FactoryException if an error occurred while loading the grid.
      */
     private void createNADCON() throws FactoryException {
-        final URL latitudeShifts  = NADCONTest.class.getResource(NADCONTest.TEST_FILE + ".laa");
-        final URL longitudeShifts = NADCONTest.class.getResource(NADCONTest.TEST_FILE + ".loa");
-        assertNotNull("Test file \"" + NADCONTest.TEST_FILE + ".laa\" not found.", latitudeShifts);
-        assertNotNull("Test file \"" + NADCONTest.TEST_FILE + ".loa\" not found.", longitudeShifts);
+        final URL latitudeShifts  = NADCONTest.getResourceAsConvertibleURL(NADCONTest.TEST_FILE + ".laa");
+        final URL longitudeShifts = NADCONTest.getResourceAsConvertibleURL(NADCONTest.TEST_FILE + ".loa");
         final NADCON provider = new NADCON();
         final ParameterValueGroup values = provider.getParameters().createValue();
         values.parameter("Latitude difference file").setValue(latitudeShifts);

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryBase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryBase.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryBase.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryBase.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -111,6 +111,7 @@ strictfp class MathTransformFactoryBase
 
     /** Default implementation throws an exception. */
     @Override
+    @Deprecated
     public MathTransform createFromXML(String xml) throws FactoryException {
         throw new FactoryException(MESSAGE);
     }

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryMock.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryMock.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryMock.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryMock.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -163,6 +163,7 @@ public final strictfp class MathTransfor
      * @return never returned.
      */
     @Override
+    @Deprecated
     public MathTransform createFromXML(String xml) {
         throw new UnsupportedOperationException();
     }

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.io.IOException;
+import javax.measure.Unit;
 import org.opengis.util.FactoryException;
 import org.opengis.util.GenericName;
 import org.opengis.metadata.extent.GeographicBoundingBox;
@@ -46,6 +47,7 @@ import org.apache.sis.referencing.CRS;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Characters;
 import org.apache.sis.util.Numbers;
+import org.apache.sis.util.Version;
 
 // Branch-dependent imports
 import org.opengis.metadata.Identifier;
@@ -159,16 +161,24 @@ public strictfp class CoordinateOperatio
         rangeFormat = new RangeFormat(LOCALE);
         final int header = openTag("header");
         println("h1", "Apache SIS™ Coordinate Operation Methods");
-        openTag("p");
-        println("The following tables summarize the coordinate operation methods known to Apache SIS, together with the recognized parameters.");
-        println("Unless otherwise noticed, all parameters are mandatory");
-        println("(in the sense that they should always be shown in forms, regardless of whether they have default value),");
-        println("but two of them are handled in a special way: the <code>semi-major</code> and <code>semi-minor</code> parameters.");
-        println("Those two parameters are needed for all map projections, but usually do not need to be specified explicitely since they are inferred from the ellipsoid.");
-        println("The only exception is when <a href=\"http://sis.apache.org/apidocs/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.html\">creating parameterized transforms directly</a>.");
-        reopenTag("p");
-        println("All map projections support also implicit <code>earth_radius</code> and <code>inverse_flattening</code> parameters (not shown below).");
-        println("Read and write operations on those implicit parameters are delegated to the <code>semi-major</code> and <code>semi-minor</code> parameters.");
+        int item = openTag("p");
+        println("The following tables summarize the coordinate operation methods known to Apache SIS " + Version.SIS);
+        println("together with the recognized parameters. There is three kinds of parameters:");
+        closeTags(item);
+        openTag("ul", "verbose");
+        openTag("li");
+        println("The <code>semi-major</code> and <code>semi-minor</code> parameters are needed for all map projections,");
+        println("but usually do not need to be specified explicitely since they are inferred from the ellipsoid");
+        println("(unless <a href=\"http://sis.apache.org/apidocs/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.html\">creating parameterized transforms directly</a>).");
+        println("For this reason, those parameters are usually not shown in <a href=\"http://www.epsg-registry.org\">EPSG registry</a>");
+        println("or <a href=\"http://docs.opengeospatial.org/is/12-063r5/12-063r5.html\">Well Known Text</a> (WKT) definitions.");
+        reopenTag("li");
+        println("The <code>earth_radius</code> and <code>inverse_flattening</code> parameters (not shown below) are implicitly supported by all map projections.");
+        println("They are other ways to specify the ellipsoid (actually rarely used).");
+        println("Read and write operations on those implicit parameters are converted into equivalent operations on <code>semi-major</code> and <code>semi-minor</code> parameters.");
+        reopenTag("li");
+        println("Unless otherwise noticed, all other parameters are mandatory");
+        println("(in the sense that they should always be shown in forms, regardless of whether they have default value).");
         closeTags(header);
     }
 
@@ -180,7 +190,7 @@ public strictfp class CoordinateOperatio
      */
     public void writeIndex(final Iterable<? extends OperationMethod> methods) throws IOException {
         final int nav = openTag("nav");
-        println("p", "<b>Table of content:</b>");
+        println("h2", "Table of content:");
         int innerUL  = openTag("ul") + 1;
         int category = 0;
         for (final OperationMethod method : methods) {
@@ -311,8 +321,13 @@ public strictfp class CoordinateOperatio
      */
     private void writeParameters(final ParameterDescriptorGroup group) throws IOException {
         int table = openTag("table class=\"param\"");
-        println("caption", "Operation parameters:");
+        println("caption", "Operation parameters:");
         openTag("tr");
+        if (group.descriptors().isEmpty()) {
+            println("td", "None");
+            closeTags(table);
+            return;
+        }
         println("th", "EPSG");
         println("th class=\"sep\"", "Name");
         println("th class=\"sep\"", "Remarks");
@@ -380,8 +395,8 @@ public strictfp class CoordinateOperatio
         if (Constants.EPSG.equalsIgnoreCase(codeSpace)) {
             println("summary", escape(name.getCode()));
         } else {
-            println("summary", "<span class=\"non-epsg\">" + codeSpace
-                    + ":</span><code>" + name.getCode() + "</code>");
+            println("summary", "<span class=\"non-epsg\">" + codeSpace + ":</span>" +
+                               "<code>" + name.getCode() + "</code>");
         }
         openTag("table class=\"aliases\"");
         for (final GenericName alias : param.getAlias()) {
@@ -485,12 +500,15 @@ public strictfp class CoordinateOperatio
      * or an empty string (never {@code null}) if none.
      */
     private static String getUnit(final ParameterDescriptor<?> param) {
-        final String unit = param.getUnit().toString();
-        if (!unit.isEmpty()) {
-            if (unit.equals("°")) {
-                return unit;
+        final Unit<?> unit = param.getUnit();
+        if (unit != null) {
+            final String symbol = unit.toString();
+            if (!symbol.isEmpty()) {
+                if (symbol.equals("°")) {
+                    return symbol;
+                }
+                return " " + symbol;
             }
-            return " " + unit;
         }
         return "";
     }
@@ -541,7 +559,7 @@ public strictfp class CoordinateOperatio
         if (id == null) {
             id = method.getName().getCode();
         }
-        return id;
+        return id.replace(" ", "_");
     }
 
     /**

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -353,6 +353,12 @@ public final strictfp class CoordinateRe
         rd("Voirol 1879",                                                 "Voirol");
         rd("Voirol 1879 (Paris)",                                         "Voirol");
         rd("WGS 72 Transit Broadcast Ephemeris",                          "World Geodetic System 1972 — Transit Broadcast Ephemeris");
+        rd("World Geodetic System 1984 (G1150)",                          "World Geodetic System 1984");
+        rd("World Geodetic System 1984 (G1674)",                          "World Geodetic System 1984");
+        rd("World Geodetic System 1984 (G1762)",                          "World Geodetic System 1984");
+        rd("World Geodetic System 1984 (G730)",                           "World Geodetic System 1984");
+        rd("World Geodetic System 1984 (G873)",                           "World Geodetic System 1984");
+        rd("World Geodetic System 1984 (Transit)",                        "World Geodetic System 1984");
         rd("Yellow Sea 1956",                                             "Yellow Sea");
         rd("Yellow Sea 1985",                                             "Yellow Sea");
     }
@@ -453,7 +459,7 @@ public final strictfp class CoordinateRe
         properties.setProperty("PRODUCT.URL",     "http://sis.apache.org");
         properties.setProperty("JAVADOC.GEOAPI",  "http://www.geoapi.org/snapshot/javadoc");
         properties.setProperty("FACTORY.NAME",    "EPSG");
-        properties.setProperty("FACTORY.VERSION", "8.9");
+        properties.setProperty("FACTORY.VERSION", "9.0");
         properties.setProperty("FACTORY.VERSION.SUFFIX", ", together with other sources");
         properties.setProperty("PRODUCT.VERSION.SUFFIX", " (provided that <a href=\"http://sis.apache.org/epsg.html\">a connection to an EPSG database exists</a>)");
         properties.setProperty("DESCRIPTION", "<p><b>Notation:</b></p>\n" +

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/HTMLGenerator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/HTMLGenerator.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/HTMLGenerator.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/HTMLGenerator.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -156,9 +156,26 @@ abstract strictfp class HTMLGenerator im
      * @throws IOException if an error occurred while writing to the file.
      */
     final int openTag(final String tag) throws IOException {
+        return openTag(tag, null);
+    }
+
+    /**
+     * Opens a new HTML tag of the given class and increase the indentation.
+     *
+     * @param  tag     the HTML tag without brackets (e.g. {@code "h2"}).
+     * @param  classe  the CSS class, or {@code null} if none.
+     * @return the value to give to {@link #closeTags(int)} for closing the tags.
+     * @throws IOException if an error occurred while writing to the file.
+     */
+    final int openTag(final String tag, final String classe) throws IOException {
         out.write(margin);
         out.write('<');
         out.write(tag);
+        if (classe != null) {
+            out.write(" class=\"");
+            out.write(classe);
+            out.write('"');
+        }
         out.write('>');
         out.newLine();
         margin = CharSequences.spaces(margin.length() + INDENTATION).toString();

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -35,6 +35,7 @@ import org.apache.sis.io.wkt.Unformattab
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Utilities;
+import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -57,13 +58,17 @@ import static org.junit.Assert.*;
  * @since   0.7
  * @module
  */
+@DependsOn({
+    org.apache.sis.referencing.CRSTest.class,
+    org.apache.sis.io.wkt.WKTFormatTest.class
+})
 public final strictfp class ConsistencyTest extends TestCase {
     /**
      * Codes to exclude for now.
      */
     private static final Set<String> EXCLUDES = new HashSet<>(Arrays.asList(
-            "CRS:1",            // Computer display
-            "EPSG:5819"         // EPSG topocentric example A
+        "CRS:1",            // Computer display
+        "EPSG:5819"         // EPSG topocentric example A
     ));
 
     /**

Modified: sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -214,11 +214,12 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.factory.MultiAuthoritiesFactoryTest.class,
     org.apache.sis.referencing.factory.sql.EPSGFactoryTest.class,
     org.apache.sis.referencing.factory.sql.EPSGInstallerTest.class,
-    org.apache.sis.referencing.factory.sql.EPSGDataFormatterTest.class,
+    org.apache.sis.referencing.factory.sql.epsg.DataScriptFormatterTest.class,
     org.apache.sis.referencing.EPSGFactoryFallbackTest.class,
     org.apache.sis.referencing.AuthorityFactoriesTest.class,
     org.apache.sis.referencing.cs.CodesTest.class,
     org.apache.sis.referencing.CRSTest.class,
+    org.apache.sis.internal.referencing.DefinitionVerifierTest.class,
 
     // Coordinate operation finders are last, since they need everything else.
     org.apache.sis.referencing.operation.CoordinateOperationRegistryTest.class,
@@ -245,6 +246,7 @@ import org.junit.BeforeClass;
 
     org.apache.sis.distance.LatLonPointRadiusTest.class,        // Pending refactoring in a geometry package.
 
+    org.apache.sis.test.integration.CoordinateOperationTest.class,
     org.apache.sis.test.integration.DatumShiftTest.class,
     org.apache.sis.test.integration.MetadataTest.class,
     org.apache.sis.test.integration.ConsistencyTest.class

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -19,9 +19,11 @@ package org.apache.sis.internal.jaxb;
 import java.util.AbstractMap;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
-import org.opengis.util.InternationalString;
 import org.apache.sis.internal.util.Citations;
 
+// Branch-dependent imports
+import org.opengis.util.InternationalString;
+
 
 /**
  * An entry in {@link org.apache.sis.xml.IdentifierMap}. This class implements both the {@link AbstractMap.Entry}

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -22,9 +22,7 @@ import java.util.UUID;
 import java.util.Objects;
 import java.io.Serializable;
 import java.util.logging.Level;
-import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
-import org.opengis.util.InternationalString;
 import org.apache.sis.xml.XLink;
 import org.apache.sis.xml.IdentifierMap;
 import org.apache.sis.xml.IdentifierSpace;
@@ -33,6 +31,10 @@ import org.apache.sis.util.Debug;
 import org.apache.sis.util.resources.Messages;
 import org.apache.sis.internal.util.Citations;
 
+// Branch-dependent imports
+import org.opengis.metadata.Identifier;
+import org.opengis.util.InternationalString;
+
 
 /**
  * Wraps a {@link XLink}, {@link URI} or {@link UUID} as an identifier in the {@link IdentifierMap}.

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleMetadata.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleMetadata.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleMetadata.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -386,7 +386,7 @@ public class SimpleMetadata implements M
     }
 
     /**
-     * Restrictions on the access and use of data.
+     * Restrictions on the access and use of metadata.
      */
     @Override
     public Collection<Constraints> getMetadataConstraints() {

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/Modules.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -73,6 +73,11 @@ public final class Modules {
     public static final String EARTH_OBSERVATION = "org.apache.sis.storage.earth-observation";
 
     /**
+     * The {@value} module name.
+     */
+    public static final String GDAL = "org.apache.sis.storage.gdal";
+
+    /**
      * The major version number of all Apache SIS modules.
      *
      * @see org.apache.sis.util.Version

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -16,12 +16,23 @@
  */
 package org.apache.sis.internal.system;
 
+import java.net.URL;
+import java.net.URISyntaxException;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import org.apache.sis.util.logging.Logging;
+import org.apache.sis.util.resources.Errors;
+
 
 /**
  * The operation system on which SIS is running.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 0.8
  * @since   0.3
  * @module
  */
@@ -29,22 +40,29 @@ public enum OS {
     /**
      * Unknown system.
      */
-    UNKNOWN(false),
+    UNKNOWN(null, false),
 
     /**
      * Windows.
      */
-    WINDOWS(false),
+    WINDOWS("windows", false),
 
     /**
      * Mac OS.
      */
-    MAC_OS(true),
+    MAC_OS("darwin", true),
 
     /**
      * Linux.
      */
-    LINUX(true);
+    LINUX("linux", true);
+
+    /**
+     * The sub-directory where to look for native files ({@code .so} or {@code .dll}).
+     * Those subdirectories are not standard (as far as we know) and could change in
+     * any future Apache SIS version. The directory is {@code null} for unknown OS.
+     */
+    private final String libdir;
 
     /**
      * {@code true} if this OS is a kind of Unix.
@@ -54,8 +72,26 @@ public enum OS {
     /**
      * Creates a new enumeration.
      */
-    private OS(final boolean unix) {
-        this.unix = unix;
+    private OS(final String libdir, final boolean unix) {
+        this.libdir = libdir;
+        this.unix   = unix;
+    }
+
+    /**
+     * Returns the name value of {@code "os.name"} property, or {@code null} if the security manager
+     * does not allow us to access this information.
+     *
+     * <div class="note"><b>Note:</b> {@code uname} is an Unix command providing the same information.</div>
+     *
+     * @return the operation system name, or {@code null} if this information is not available.
+     */
+    public static String uname() {
+        try {
+            return System.getProperty("os.name");
+        } catch (SecurityException e) {
+            Logging.recoverableException(Logging.getLogger(Loggers.SYSTEM), OS.class, "uname", e);
+            return null;
+        }
     }
 
     /**
@@ -64,7 +100,7 @@ public enum OS {
      * @return the operation system.
      */
     public static OS current() {
-        final String name = System.getProperty("os.name");
+        final String name = uname();
         if (name != null) {
             if (name.contains("Windows")) return WINDOWS;
             if (name.contains("Mac OS"))  return MAC_OS;
@@ -72,4 +108,59 @@ public enum OS {
         }
         return UNKNOWN;
     }
+
+    /**
+     * Loads the native library of the given name from the JAR file of the given class.
+     * This method searches for a resource in the {@code /native/<os>} directory where
+     * {@code <os>} is {@code windows}, {@code darwin} or {@code linux}.
+     *
+     * @param  caller  a class in the JAR file where to look for native resources.
+     * @param  name    the native library name without {@code ".so"} or {@code ".dll"} extension.
+     * @throws UnsatisfiedLinkError if the native library can not be loaded for the current OS.
+     *
+     * @see System#load(String)
+     */
+    public static void load(final Class<?> caller, final String name) {
+        try {
+            System.load(current().nativeLibrary(caller.getClassLoader(), name));
+        } catch (IOException | SecurityException e) {
+            throw (UnsatisfiedLinkError) new UnsatisfiedLinkError(e.getMessage()).initCause(e);
+        }
+    }
+
+    /**
+     * Returns an absolute path to the library of the given name in the JAR file.
+     * If the resources can not be accessed by an absolute path, then this method
+     * copies the resource in a temporary file.
+     *
+     * @param  loader  the loader of the JAR file where to look for native resources.
+     * @param  name    the native library name without {@code ".so"} or {@code ".dll"} extension.
+     * @return absolute path to the library (may be a temporary file).
+     * @throws IOException if an error occurred while copying the library to a temporary file.
+     * @throws SecurityException if the security manager denies loading resource, creating absolute path, <i>etc</i>.
+     * @throws UnsatisfiedLinkError if no native resource has been found for the current OS.
+     *
+     * @see System#load(String)
+     */
+    private String nativeLibrary(final ClassLoader loader, final String name) throws IOException {
+        if (libdir != null) {
+            final String ext = unix ? ".so" : ".dll";
+            final String path = "native/" + libdir + '/' + name + ext;
+            final URL res = loader.getResource(path);
+            if (res != null) {
+                try {
+                    return new File(res.toURI()).getAbsolutePath();
+                } catch (IllegalArgumentException | URISyntaxException e) {
+                    Logging.recoverableException(Logging.getLogger(Loggers.SYSTEM), OS.class, "nativeLibrary", e);
+                }
+                final Path tmp = Files.createTempFile(name, ext).toAbsolutePath();
+                tmp.toFile().deleteOnExit();
+                try (InputStream in = res.openStream()) {
+                    Files.copy(in, tmp, StandardCopyOption.REPLACE_EXISTING);
+                }
+                return tmp.toString();
+            }
+        }
+        throw new UnsatisfiedLinkError(Errors.format(Errors.Keys.NativeInterfacesNotFound_2, uname(), name));
+    }
 }

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/system/Semaphores.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -21,37 +21,46 @@ 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.
- * The {@link #clear(byte)} method <strong>must</strong> be invoked after the {@link #queryAndSet(byte)} method in
+ * The {@link #clear(int)} method <strong>must</strong> be invoked after the {@link #queryAndSet(int)} method in
  * a {@code try ... finally} block.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.5
  * @module
  */
 public final class Semaphores {
     /**
+     * A flag to indicate that empty collections should be returned as {@code null}. Returning null
+     * collections is not a recommended practice, but is useful in some situations like marshalling
+     * a XML document with JAXB, when we want to omit empty XML blocks.
+     */
+    public static final int NULL_COLLECTION = 1;
+
+    /**
+     * A flag to indicate that only metadata are desired and that there is no need to create costly objects.
+     * This flag is used during iteration over many coordinate operations before to select a single one by
+     * inspecting only their metadata.
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-327">SIS-327</a>
+     */
+    public static final int METADATA_ONLY = 2;
+
+    /**
      * A lock for avoiding never-ending recursivity in the {@code equals} method of {@code AbstractDerivedCRS}
      * and {@link org.apache.sis.referencing.operation.AbstractCoordinateOperation}.
      * It is set to {@code true} when a comparison is in progress. This lock is necessary because
      * {@code AbstractDerivedCRS} objects contain a {@code conversionFromBase} field, which contains a
      * {@code DefaultConversion.targetCRS} field referencing back the {@code AbstractDerivedCRS} object.
      */
-    public static final byte CONVERSION_AND_CRS = 1;
+    public static final int CONVERSION_AND_CRS = 4;
 
     /**
      * A flag to indicate that {@link org.apache.sis.referencing.operation.AbstractCoordinateOperation}
      * is querying parameters of a {@code MathTransform} enclosed in the operation. This is often in the
      * intend to format WKT of a {@code "ProjectedCRS"} element.
      */
-    public static final byte ENCLOSED_IN_OPERATION = 2;
-
-    /**
-     * A flag to indicate that empty collections should be returned as {@code null}. Returning null
-     * collections is not a recommended practice, but is useful in some situations like marshalling
-     * a XML document with JAXB, when we want to omit empty XML blocks.
-     */
-    public static final byte NULL_COLLECTION = 4;
+    public static final int ENCLOSED_IN_OPERATION = 8;
 
     /**
      * A flag to indicate that a parameter value outside its domain of validity should not cause an exception
@@ -62,7 +71,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;
+    public static final int SUSPEND_PARAMETER_CHECK = 16;
 
     /**
      * The flags per running thread.
@@ -72,7 +81,7 @@ public final class Semaphores {
     /**
      * The bit flags.
      */
-    private byte flags;
+    private int flags;
 
     /**
      * For internal use only.
@@ -86,7 +95,7 @@ public final class Semaphores {
      * @param  flag  one of {@link #CONVERSION_AND_CRS}, {@link #ENCLOSED_IN_OPERATION} or other constants.
      * @return {@code true} if the given flag is set.
      */
-    public static boolean query(final byte flag) {
+    public static boolean query(final int flag) {
         final Semaphores s = FLAGS.get();
         return (s != null) && (s.flags & flag) != 0;
     }
@@ -97,7 +106,7 @@ public final class Semaphores {
      * @param  flag  one of {@link #CONVERSION_AND_CRS}, {@link #ENCLOSED_IN_OPERATION} or other constants.
      * @return {@code true} if the given flag was already set.
      */
-    public static boolean queryAndSet(final byte flag) {
+    public static boolean queryAndSet(final int flag) {
         Semaphores s = FLAGS.get();
         if (s == null) {
             s = new Semaphores();
@@ -113,7 +122,7 @@ public final class Semaphores {
      *
      * @param  flag  one of {@link #CONVERSION_AND_CRS}, {@link #ENCLOSED_IN_OPERATION} or other constants.
      */
-    public static void clear(final byte flag) {
+    public static void clear(final int flag) {
         final Semaphores s = FLAGS.get();
         if (s != null) {
             s.flags &= ~flag;

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -28,6 +28,9 @@ import org.opengis.parameter.InvalidPara
 
 import static org.apache.sis.util.collection.Containers.hashMapCapacity;
 
+// Branch-dependent imports
+import java.util.function.Predicate;
+
 
 /**
  * Static methods working on {@link Collection} objects.
@@ -60,6 +63,32 @@ public final class CollectionsExt extend
     }
 
     /**
+     * Returns an empty collection of the given type, or {@code null} if the given type is unknown to this method.
+     *
+     * @param  type  the desired collection type.
+     * @return an empty collection of the given type, or {@code null} if the type is unknown.
+     *
+     * @since 0.8
+     */
+    public static Collection<?> empty(final Class<?> type) {
+        if (type.isAssignableFrom(List.class)) {                    // Most common case first.
+            return Collections.EMPTY_LIST;
+        } else if (type.isAssignableFrom(Set.class)) {
+            return Collections.EMPTY_SET;
+        } else if (type.isAssignableFrom(NavigableSet.class)) {     // Rarely used case (at least in SIS).
+            if (type.isAssignableFrom(SortedSet.class)) {
+                return Collections.emptySortedSet();
+            } else {
+                return Collections.emptyNavigableSet();
+            }
+        } else if (type.isAssignableFrom(Queue.class)) {
+            return emptyQueue();
+        } else {
+            return null;
+        }
+    }
+
+    /**
      * Returns the first element of the given iterable, or {@code null} if none.
      * This method does not emit warning if more than one element is found.
      * Consequently, this method should be used only when multi-occurrence is not ambiguous.
@@ -836,6 +865,57 @@ public final class CollectionsExt extend
     }
 
     /**
+     * Returns an iterator over the elements of the given iterator where the predicate returns {@code true}.
+     * The iterator may return {@code null} elements.
+     *
+     * @param  <E>     type of elements in the iterator to return.
+     * @param  it      the iterator to filter.
+     * @param  filter  the predicate to use for filtering elements.
+     * @return an iterator over filtered elements.
+     */
+    public static <E> Iterator<E> filter(final Iterator<E> it, final Predicate<? super E> filter) {
+        return new Iterator<E>() {
+            /** Whether the {@code next} element has been verified as valid. */
+            private boolean valid;
+
+            /** The next element to return. */
+            private E next;
+
+            /** Tests whether there is more elements to return. */
+            @Override public boolean hasNext() {
+                if (!valid) {
+                    do {
+                        if (!it.hasNext()) {
+                            return false;
+                        }
+                        next = it.next();
+                    } while (!filter.test(next));
+                    valid = true;
+                }
+                return true;
+            }
+
+            /**
+             * Returns the next element. If there is no more elements,
+             * the exception will be thrown by the wrapped iterator.
+             */
+            @Override public E next() {
+                if (!valid) {
+                    do next = it.next();
+                    while (!filter.test(next));
+                }
+                valid = false;
+                return next;
+            }
+
+            /** Remove the last element returned by the iterator. */
+            @Override public void remove() {
+                it.remove();
+            }
+        };
+    }
+
+    /**
      * Returns {@code true} if the next elements returned by the given iterators are the same.
      * This method compares using the identity operation ({@code ==}), not {@code equals(Object)}.
      *

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -47,6 +47,11 @@ public final class Constants extends Sta
     /**
      * The {@value} code space.
      */
+    public static final String GEOTIFF = "GeoTIFF";
+
+    /**
+     * The {@value} code space.
+     */
     public static final String EPSG = "EPSG";
 
     /**
@@ -66,6 +71,12 @@ public final class Constants extends Sta
     public static final String SIS = "SIS";
 
     /**
+     * The {@value} code space. The project name is {@code "Proj.4"}, but this constant omits
+     * the dot because this name is used as a codes pace and we want to avoid risk of confusion.
+     */
+    public static final String PROJ4 = "Proj4";
+
+    /**
      * The {@value} code space.
      */
     public static final String CRS = "CRS";

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/LazySet.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -22,7 +22,6 @@ import java.util.Objects;
 import java.util.Iterator;
 import java.util.ServiceLoader;
 import java.util.NoSuchElementException;
-import org.apache.sis.util.Workaround;
 import org.apache.sis.internal.system.DefaultFactories;
 
 
@@ -37,7 +36,8 @@ import org.apache.sis.internal.system.De
  * {@link org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory#DefaultMathTransformFactory()}.</p>
  *
  * <p>Some usages for this class are to prepend some values before the elements given by the source {@code Iterable},
- * or to replace some values when they are loaded.</p>
+ * or to replace some values when they are loaded. It may also be used for creating filtered sets when used together
+ * with {@link CollectionsExt#filter CollectionsExt.filter(…)}.</p>
  *
  * <p>This class is not thread-safe. Synchronization, if desired, shall be done by the caller.</p>
  *
@@ -49,7 +49,6 @@ import org.apache.sis.internal.system.De
  * @since 0.6
  * @module
  */
-@Workaround(library="JDK", version="1.8.0_31-b13")
 public class LazySet<E> extends SetOfUnknownSize<E> {
     /**
      * The type of service to request with {@link ServiceLoader}, or {@code null} if unknown.

Modified: sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java?rev=1803070&r1=1803069&r2=1803070&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java [UTF-8] Wed Jul 26 16:14:09 2017
@@ -41,6 +41,7 @@ import java.time.temporal.TemporalAccess
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
+import java.time.format.SignStyle;
 
 
 /**
@@ -88,7 +89,7 @@ public final class StandardDateFormat ex
      */
     public static final DateTimeFormatter FORMAT = new DateTimeFormatterBuilder()
             // parseLenient() is for allowing fields with one digit instead of two.
-            .parseLenient()                    .appendValue(ChronoField.YEAR,             4)    // Proleptic year (use negative number if needed).
+            .parseLenient()                    .appendValue(ChronoField.YEAR, 4, 5, SignStyle.NORMAL)    // Proleptic year (use negative number if needed).
             .optionalStart().appendLiteral('-').appendValue(ChronoField.MONTH_OF_YEAR,    2)
             .optionalStart().appendLiteral('-').appendValue(ChronoField.DAY_OF_MONTH,     2)
             .optionalStart().appendLiteral('T').appendValue(ChronoField.HOUR_OF_DAY,      2)
@@ -131,6 +132,16 @@ public final class StandardDateFormat ex
     public static final int MILLISECONDS_PER_DAY = 24*60*60*1000;
 
     /**
+     * Number of nanoseconds in one millisecond.
+     */
+    public static final long NANOS_PER_MILLISECOND = 1000000;
+
+    /**
+     * Number of nanoseconds in one second.
+     */
+    public static final long NANOS_PER_SECOND = 1000000000;
+
+    /**
      * Converts the given legacy {@code Date} object into a {@code java.time} implementation in given timezone.
      * The method performs the following choice:
      *



Mime
View raw message