This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit d5834c52c3c0ccf30fb4a01a492b1687b53af5d6
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Tue Feb 20 16:14:35 2024 +0100

    Handle a log record about a deprecated EPSG code.
    That record may or may not be emitted depending on execution order.
---
 .../referencing/factory/sql/EPSGDataAccess.java    | 18 +++++---
 .../test/org/apache/sis/referencing/CRSTest.java   |  3 +-
 .../transform/EllipsoidToCentricTransformTest.java | 28 +++++++++++-
 .../test/org/apache/sis/test/LoggingWatcher.java   | 51 ++++++++++++++++++----
 .../sis/util/logging/PerformanceLevelTest.java     |  3 +-
 5 files changed, 87 insertions(+), 16 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
index 45749cd97c..abcd65befc 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
@@ -1209,6 +1209,7 @@ codes:  for (int i=0; i<codes.length; i++) {
         if ("?".equals(scope)) {                // EPSG sometimes uses this 
value for unspecified scope.
             scope = null;
         }
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         final Map<String,Object> properties = createProperties(table, name, 
code, remarks, deprecated);
         if (domainCode != null) {
             properties.put(Datum.DOMAIN_OF_VALIDITY_KEY, 
owner.createExtent(domainCode));
@@ -1487,7 +1488,8 @@ codes:  for (int i=0; i<codes.length; i++) {
                                  * We need to check if EPSG database 10+ has 
more specific information.
                                  * See 
https://issues.apache.org/jira/browse/SIS-518
                                  */
-                                final Map<String, Object> properties = 
createProperties("Coordinate Reference System",
+                                
@SuppressWarnings("LocalVariableHidesMemberVariable")
+                                final Map<String,Object> properties = 
createProperties("Coordinate Reference System",
                                                                         name, 
epsg, area, scope, remarks, deprecated);
                                 if (baseCRS instanceof GeographicCRS) {
                                     crs = 
crsFactory.createProjectedCRS(properties, (GeographicCRS) baseCRS, op, cs);
@@ -1555,8 +1557,9 @@ codes:  for (int i=0; i<codes.length; i++) {
                     case "geocentric": {
                         final CoordinateSystem cs = 
owner.createCoordinateSystem(getString(code, result, 8));
                         final GeodeticDatum datum = owner.createGeodeticDatum  
 (getString(code, result, 9));
+                        @SuppressWarnings("LocalVariableHidesMemberVariable")
                         final Map<String,Object> properties = 
createProperties("Coordinate Reference System",
-                                name, epsg, area, scope, remarks, deprecated);
+                                                                name, epsg, 
area, scope, remarks, deprecated);
                         if (cs instanceof CartesianCS) {
                             crs = crsFactory.createGeocentricCRS(properties, 
datum, (CartesianCS) cs);
                         } else if (cs instanceof SphericalCS) {
@@ -1659,8 +1662,8 @@ codes:  for (int i=0; i<codes.length; i++) {
                 final String  scope      = getOptionalString (result, 7);
                 final String  remarks    = getOptionalString (result, 8);
                 final boolean deprecated = getOptionalBoolean(result, 9);
-                Map<String,Object> properties = createProperties("Datum",
-                        name, epsg, area, scope, remarks, deprecated);
+                @SuppressWarnings("LocalVariableHidesMemberVariable")
+                Map<String,Object> properties = createProperties("Datum", 
name, epsg, area, scope, remarks, deprecated);
                 if (anchor != null) {
                     properties.put(Datum.ANCHOR_POINT_KEY, anchor);
                 }
@@ -1683,6 +1686,7 @@ codes:  for (int i=0; i<codes.length; i++) {
                         }
                     }
                     if (year != 0) {
+                        @SuppressWarnings("LocalVariableHidesMemberVariable")
                         final Calendar calendar = getCalendar();
                         calendar.set(year, month, day);
                         properties.put(Datum.REALIZATION_EPOCH_KEY, 
calendar.getTime());
@@ -1945,6 +1949,7 @@ codes:  for (int i=0; i<codes.length; i++) {
                 final String  remarks           = getOptionalString (result, 
7);
                 final boolean deprecated        = getOptionalBoolean(result, 
8);
                 final Unit<Length> unit         = 
owner.createUnit(unitCode).asType(Length.class);
+                @SuppressWarnings("LocalVariableHidesMemberVariable")
                 final Map<String,Object> properties = 
createProperties("Ellipsoid", name, epsg, remarks, deprecated);
                 final Ellipsoid ellipsoid;
                 if (Double.isNaN(inverseFlattening)) {
@@ -2164,6 +2169,7 @@ codes:  for (int i=0; i<codes.length; i++) {
                 final String  remarks    = getOptionalString (result, 5);
                 final boolean deprecated = getOptionalBoolean(result, 6);
                 final CoordinateSystemAxis[] axes = 
createCoordinateSystemAxes(epsg, dimension);
+                @SuppressWarnings("LocalVariableHidesMemberVariable")
                 final Map<String,Object> properties = 
createProperties("Coordinate System", name, epsg, remarks, deprecated);   // 
Must be after axes.
                 /*
                  * The following switch statement should have a case for all 
"epsg_cs_kind" values enumerated
@@ -2607,7 +2613,8 @@ next:                   while (r.next()) {
                     case 1:  valueDomain = 
MeasurementRange.create(Double.NEGATIVE_INFINITY, false,
                                     Double.POSITIVE_INFINITY, false, 
CollectionsExt.first(units)); break;
                 }
-                final Map<String, Object> properties =
+                @SuppressWarnings("LocalVariableHidesMemberVariable")
+                final Map<String,Object> properties =
                         createProperties("Coordinate_Operation Parameter", 
name, epsg, isReversible, deprecated);
                 properties.put(Identifier.DESCRIPTION_KEY, description);
                 final ParameterDescriptor<?> descriptor = new 
DefaultParameterDescriptor<>(properties,
@@ -2771,6 +2778,7 @@ next:                   while (r.next()) {
                 final String  remarks    = getOptionalString (result, 3);
                 final boolean deprecated = getOptionalBoolean(result, 4);
                 final ParameterDescriptor<?>[] descriptors = 
createParameterDescriptors(epsg);
+                @SuppressWarnings("LocalVariableHidesMemberVariable")
                 Map<String,Object> properties = 
createProperties("Coordinate_Operation Method", name, epsg, remarks, 
deprecated);
                 /*
                  * Note: we do not store the formula at this time, because the 
text is very verbose and rarely used.
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CRSTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CRSTest.java
index 65f91dabba..a347e64488 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CRSTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CRSTest.java
@@ -247,6 +247,7 @@ public final class CRSTest extends TestCaseWithLogs {
                     null, new DefaultGeographicBoundingBox(-1, +1, ymin, 
ymax), null, null));
             crs[i] = new DefaultProjectedCRS(properties, baseCRS.geographic(), 
HardCodedConversions.MERCATOR, cs);
         }
+        loggings.skipNextLogIfContains("EPSG:4047");                        // 
No longer supported by EPSG.
         final ProjectedCRS[] overlappingCRS = Arrays.copyOf(crs, 3);        // 
Exclude the last CRS only.
         /*
          * Test between the 3 overlapping CRS without region of interest. We 
expect the CRS having a domain
@@ -257,7 +258,7 @@ public final class CRSTest extends TestCaseWithLogs {
          * 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);
+        final var regionOfInterest = new DefaultGeographicBoundingBox(-1, +1, 
2.1, 2.9);
         assertSame(crs[2], CRS.suggestCommonTarget(regionOfInterest, 
overlappingCRS));      // Best fit for [2.1 … 2.9]°N
 
         regionOfInterest.setNorthBoundLatitude(3.1);
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
index 210ca7fdc8..fa28f39131 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransformTest.java
@@ -28,13 +28,16 @@ import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.util.Formulas;
 import org.apache.sis.geometry.DirectPosition2D;
 import org.apache.sis.geometry.GeneralDirectPosition;
+import org.apache.sis.system.Loggers;
 import org.apache.sis.measure.Units;
 
 // Test dependencies
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
-import org.apache.sis.referencing.operation.provider.GeocentricTranslationTest;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.apache.sis.test.LoggingWatcher;
 import static org.apache.sis.test.Assertions.assertSerializedEquals;
+import org.apache.sis.referencing.operation.provider.GeocentricTranslationTest;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import org.opengis.test.ToleranceModifier;
@@ -46,10 +49,17 @@ import org.opengis.test.ToleranceModifier;
  * @author  Martin Desruisseaux (IRD, Geomatys)
  */
 public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase {
+    /**
+     * A JUnit extension for listening to log events.
+     */
+    @RegisterExtension
+    public final LoggingWatcher loggings;
+
     /**
      * Creates a new test case.
      */
     public EllipsoidToCentricTransformTest() {
+        loggings = new LoggingWatcher(Loggers.CRS_FACTORY);
     }
 
     /**
@@ -93,6 +103,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
         tolerance = GeocentricTranslationTest.precision(2);         // Half 
the precision of target sample point
         verifyTransform(GeocentricTranslationTest.samplePoint(1),   // 
53°48'33.820"N, 02°07'46.380"E, 73.00 metres
                         GeocentricTranslationTest.samplePoint(2));  // 
3771793.968,  140253.342,  5124304.349 metres
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -115,6 +126,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
         zDimension = new int[] {2};                                 // 
Dimension of h where to apply zTolerance
         verifyTransform(GeocentricTranslationTest.samplePoint(2),   // X = 
3771793.968,  Y = 140253.342,  Z = 5124304.349 metres
                         GeocentricTranslationTest.samplePoint(1));  // 
53°48'33.820"N, 02°07'46.380"E, 73.00 metres
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -131,6 +143,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
         toleranceModifier = ToleranceModifier.PROJECTION;
         createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
         verifyInDomain(CoordinateDomain.GEOGRAPHIC, 306954540);
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -151,6 +164,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
         tolerance         = Formulas.LINEAR_TOLERANCE;
         toleranceModifier = ToleranceModifier.PROJECTION;
         verifyInverse(40, 30, 10000);
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -179,6 +193,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
         tolerance = 1E-8;
         derivativeDeltas = new double[] {1};                                   
 // Approximately one metre.
         verifyDerivative(point.getCoordinate());
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -191,6 +206,8 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
     public void testDerivativeOnSphere() throws FactoryException, 
TransformException {
         testDerivative(CommonCRS.SPHERE.ellipsoid(), true);
         testDerivative(CommonCRS.SPHERE.ellipsoid(), false);
+        loggings.skipNextLogIfContains("EPSG:4047");            // No longer 
supported by EPSG.
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -203,6 +220,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
     public void testDerivative() throws FactoryException, TransformException {
         testDerivative(CommonCRS.WGS84.ellipsoid(), true);
         testDerivative(CommonCRS.WGS84.ellipsoid(), false);
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -226,6 +244,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
         tolerance = GeocentricTranslationTest.precision(2);
         verifyTransform(GeocentricTranslationTest.samplePoint(1),
                         GeocentricTranslationTest.samplePoint(2));
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -270,6 +289,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
         assertInstanceOf(LinearTransform.class, step = it.next());
         assertEquals(2, step.getSourceDimensions());
         assertEquals(2, step.getTargetDimensions());
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -290,6 +310,8 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
         assertWktEquals("PARAM_MT[“Geocentric_To_Ellipsoid”,\n" +
                         "  PARAMETER[“semi_major”, 6378137.0],\n" +
                         "  PARAMETER[“semi_minor”, 6356752.314245179]]");
+
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -314,6 +336,8 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
                         "    PARAMETER[“semi_major”, 6378137.0],\n" +
                         "    PARAMETER[“semi_minor”, 6356752.314245179]],\n" +
                         "  PARAM_MT[“Geographic3D to 2D conversion”]]");
+
+        loggings.assertNoUnexpectedLog();
     }
 
     /**
@@ -365,5 +389,7 @@ public final class EllipsoidToCentricTransformTest extends 
MathTransformTestCase
                 "    Parameter[“elt_0_0”, 57.29577951308232],\n" +
                 "    Parameter[“elt_1_1”, 57.29577951308232],\n" +
                 "    Parameter[“elt_2_2”, 6378137.0]]]");
+
+        loggings.assertNoUnexpectedLog();
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/LoggingWatcher.java 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/LoggingWatcher.java
index f4047385b7..c3d704e592 100644
--- 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/LoggingWatcher.java
+++ 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/test/LoggingWatcher.java
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.test;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.Queue;
 import java.util.LinkedList;
 import java.util.ConcurrentModificationException;
@@ -95,9 +97,42 @@ public final class LoggingWatcher implements 
BeforeEachCallback, AfterEachCallba
     public static final String LOCK = "Logging";
 
     /**
-     * The logged messages.
+     * The logged messages. All accesses to this list shall be synchronized on 
{@code this}.
      */
-    private final Queue<String> messages = new LinkedList<>();
+    private final Queue<Message> messages = new LinkedList<>();
+
+    /**
+     * Elements in the {@link #messages} queue.
+     */
+    private static final class Message extends 
org.apache.sis.pending.jdk.Record {
+        /** Formatted text of the log record. */
+        final String text;
+
+        /** Stack trace that we can use for finding the emitter, or {@code 
null} if none. */
+        final Throwable trace;
+
+        /** Creates a new message. */
+        Message(final String text, Throwable trace) {
+            this.text  = text;
+            this.trace = trace;
+        }
+
+        /**
+         * Returns the formatted log message together with its source.
+         * This is the string to show if an assertion fail.
+         */
+        @Override public String toString() {
+            if (trace == null) {
+                return text;
+            }
+            final var buffer = new StringWriter();
+            buffer.write(text);
+            buffer.write(System.lineSeparator());
+            buffer.write("Caused by: ");
+            trace.printStackTrace(new PrintWriter(buffer));
+            return buffer.toString();
+        }
+    }
 
     /**
      * The logger to watch.
@@ -238,7 +273,7 @@ public final class LoggingWatcher implements 
BeforeEachCallback, AfterEachCallba
                 return true;
             }
             synchronized (owner) {
-                owner.messages.add(owner.formatter.formatMessage(record));
+                owner.messages.add(new 
Message(owner.formatter.formatMessage(record), record.getThrown()));
             }
         }
         return TestCase.VERBOSE;
@@ -254,10 +289,10 @@ public final class LoggingWatcher implements 
BeforeEachCallback, AfterEachCallba
      */
     @SuppressWarnings("StringEquality")
     public synchronized void skipNextLogIfContains(final String... keywords) {
-        final String message = messages.peek();
+        final Message message = messages.peek();
         if (message != null) {
             for (final String word : keywords) {
-                if (!message.contains(word)) {
+                if (!message.text.contains(word)) {
                     return;
                 }
             }
@@ -278,9 +313,9 @@ public final class LoggingWatcher implements 
BeforeEachCallback, AfterEachCallba
         if (messages.isEmpty()) {
             fail("Expected a logging messages but got no more.");
         }
-        final String message = messages.remove();
+        final Message message = messages.remove();
         for (final String word : keywords) {
-            if (!message.contains(word)) {
+            if (!message.text.contains(word)) {
                 fail("Expected the logging message to contains the “" + word + 
"” word but got:\n" + message);
             }
         }
@@ -290,7 +325,7 @@ public final class LoggingWatcher implements 
BeforeEachCallback, AfterEachCallba
      * Verifies that there is no more log message.
      */
     public synchronized void assertNoUnexpectedLog() {
-        final String message = messages.peek();
+        final Message message = messages.peek();
         if (message != null) {
             fail("Unexpected logging message: " + message);
         }
diff --git 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/logging/PerformanceLevelTest.java
 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/logging/PerformanceLevelTest.java
index 42c217e23c..3ca8b87833 100644
--- 
a/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/logging/PerformanceLevelTest.java
+++ 
b/endorsed/src/org.apache.sis.util/test/org/apache/sis/util/logging/PerformanceLevelTest.java
@@ -24,6 +24,7 @@ import static org.apache.sis.util.logging.PerformanceLevel.*;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.*;
 import org.junit.jupiter.api.parallel.ResourceLock;
+import org.apache.sis.test.LoggingWatcher;
 import org.apache.sis.test.TestCase;
 
 
@@ -52,7 +53,7 @@ public final class PerformanceLevelTest extends TestCase {
      * Tests modifying the configuration.
      */
     @Test
-    @ResourceLock("Logging")
+    @ResourceLock(LoggingWatcher.LOCK)
     public void testSetMinDuration() {
         final long t1 = SLOWNESS.getMinDuration(TimeUnit.SECONDS);
         final long t2 = SLOWER  .getMinDuration(TimeUnit.SECONDS);

Reply via email to