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
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new c9641c4260 Fix some (not all) JUnit test failures observed when using
version 12 of the EPSG geodetic dataset. The fixes preserve compatibility with
version 9 of EPSG (for now, we revisit in the future).
c9641c4260 is described below
commit c9641c4260a16fabfa3fc11e7285ffed73c4f8c5
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sun Aug 31 15:03:55 2025 +0200
Fix some (not all) JUnit test failures observed when using version 12 of
the EPSG geodetic dataset.
The fixes preserve compatibility with version 9 of EPSG (for now, we
revisit in the future).
---
.../org/apache/sis/console/CRSCommandTest.java | 2 +-
.../sis/openoffice/ReferencingFunctionsTest.java | 5 +-
.../main/org/apache/sis/referencing/CommonCRS.java | 26 ++++----
.../apache/sis/referencing/crs/AbstractCRS.java | 65 +++++++++++---------
.../sis/referencing/crs/DefaultCompoundCRS.java | 44 +++++++-------
.../org/apache/sis/referencing/cs/AbstractCS.java | 67 ++++++++++++---------
.../sis/referencing/cs/DefaultCompoundCS.java | 36 ++++++-----
.../org/apache/sis/referencing/Assertions.java | 69 +++++++++++++++++++++-
.../org/apache/sis/referencing/CommonCRSTest.java | 4 +-
.../factory/CommonAuthorityFactoryTest.java | 4 +-
.../referencing/factory/sql/EPSGFactoryTest.java | 3 +-
.../integration/CoordinateReferenceSystemTest.java | 33 -----------
12 files changed, 204 insertions(+), 154 deletions(-)
diff --git
a/endorsed/src/org.apache.sis.console/test/org/apache/sis/console/CRSCommandTest.java
b/endorsed/src/org.apache.sis.console/test/org/apache/sis/console/CRSCommandTest.java
index d052c5c319..fe2460df08 100644
---
a/endorsed/src/org.apache.sis.console/test/org/apache/sis/console/CRSCommandTest.java
+++
b/endorsed/src/org.apache.sis.console/test/org/apache/sis/console/CRSCommandTest.java
@@ -44,7 +44,7 @@ public final class CRSCommandTest extends TestCase {
final String name = "\"WGS\\E\\s?(?:19)?\\Q84\"";
// Accept "WGS 84" or "WGS 1984".
WGS84 = "(?m)\\Q" +
// Multilines.
"GeodeticCRS[" + name + ",\n" +
- " Datum[\"World Geodetic System 1984\",\n" +
+ " Datum[\"World Geodetic System 1984\\E\\s?\\w*\\Q\",\n" +
// End with "ensemble" in EPSG 10+.
" Ellipsoid[" + name + ", 6378137.0, 298.257223563]],\n" +
" CS[ellipsoidal, 2],\n" +
" Axis[\"Latitude (B)\", north],\n" +
diff --git
a/endorsed/src/org.apache.sis.openoffice/test/org/apache/sis/openoffice/ReferencingFunctionsTest.java
b/endorsed/src/org.apache.sis.openoffice/test/org/apache/sis/openoffice/ReferencingFunctionsTest.java
index 0e78793851..69a701b16b 100644
---
a/endorsed/src/org.apache.sis.openoffice/test/org/apache/sis/openoffice/ReferencingFunctionsTest.java
+++
b/endorsed/src/org.apache.sis.openoffice/test/org/apache/sis/openoffice/ReferencingFunctionsTest.java
@@ -26,6 +26,7 @@ import org.junit.jupiter.api.TestInstance;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import org.apache.sis.test.TestCase;
+import org.apache.sis.referencing.Assertions;
/**
@@ -66,7 +67,7 @@ public final class ReferencingFunctionsTest extends TestCase {
assertEquals("WGS 84", instance.getName("urn:ogc:def:crs:epsg::4326"));
assertEquals("WGS 84",
instance.getName("http://www.opengis.net/gml/srs/epsg.xml#4326"));
assertEquals("WGS 84", instance.getName("EPSG:4326"));
- assertEquals("World Geodetic System 1984",
instance.getName("urn:ogc:def:datum:epsg::6326"));
+ Assertions.assertLegacyEquals("World Geodetic System 1984",
instance.getName("urn:ogc:def:datum:epsg::6326"));
}
/**
@@ -88,7 +89,7 @@ public final class ReferencingFunctionsTest extends TestCase {
assertEquals("Latitude (°)",
instance.getAxis("EPSG:4326", 1));
assertEquals("Longitude (°)",
instance.getAxis("EPSG:4326", 2));
assertEquals("Index 3 is out of bounds.",
instance.getAxis("EPSG:4326", 3));
- assertEquals("Expected “urn:ogc:def:datum:epsg::6326” to reference an
instance of ‘CoordinateReferenceSystem’, " +
+ Assertions.assertLegacyEquals("Expected “urn:ogc:def:datum:epsg::6326”
to reference an instance of ‘CoordinateReferenceSystem’, " +
"but found an instance of ‘GeodeticDatum’.",
instance.getAxis("urn:ogc:def:datum:epsg::6326", 1));
}
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
index 003bce6e6e..e8a9d1db04 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/CommonCRS.java
@@ -366,7 +366,7 @@ public enum CommonCRS {
*
* @see #normalizedGeographic()
*/
- private transient GeographicCRS cachedNormalized;
+ private transient volatile GeographicCRS cachedNormalized;
/**
* The three-dimensional geographic CRS, created when first needed.
@@ -602,19 +602,19 @@ public enum CommonCRS {
* @see DefaultGeographicCRS#forConvention(AxesConvention)
* @see AxesConvention#NORMALIZED
*/
- public synchronized GeographicCRS normalizedGeographic() {
+ public GeographicCRS normalizedGeographic() {
/*
- * Note on synchronization: a previous version of this class was using
volatile fields for the caches,
- * and kept the synchronized blocks as small as possible. It has been
replaced by simpler synchronized
- * methods in order to avoid race conditions which resulted in
duplicated and confusing log messages
- * when the EPSG factory is not available.
+ * Avoid synchronization since we observed that it can be a cause of
deadlock.
+ * In particular, the call to `forConvention(…)` may require an access
to the
+ * EPSG geodetic dataset. The methods invoked below are already
thread-safe.
*/
- if (cachedNormalized == null) {
- DefaultGeographicCRS crs =
DefaultGeographicCRS.castOrCopy(geographic());
- crs = crs.forConvention(AxesConvention.RIGHT_HANDED); //
Equivalent to NORMALIZED in our cases, but faster.
+ GeographicCRS crs = cachedNormalized;
+ if (crs == null) {
+ crs =
DefaultGeographicCRS.castOrCopy(geographic()).forConvention(AxesConvention.RIGHT_HANDED);
+ // `RIGHT_HANDED` is equivalent to `NORMALIZED` in this case, but
faster.
cachedNormalized = crs;
}
- return cachedNormalized;
+ return crs;
}
/**
@@ -643,6 +643,12 @@ public enum CommonCRS {
* @see DefaultGeographicCRS
*/
public synchronized GeographicCRS geographic() {
+ /*
+ * Note on synchronization: a previous version of this class was using
volatile fields for the caches,
+ * and kept the synchronized blocks as small as possible. It has been
replaced by simpler synchronized
+ * methods in order to avoid race conditions which resulted in
duplicated and confusing log messages
+ * when the EPSG factory is not available.
+ */
GeographicCRS object = geographic(cached);
if (object == null) {
final GeodeticAuthorityFactory factory = factory();
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/AbstractCRS.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/AbstractCRS.java
index 55593e9fd2..df9ddc56eb 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/AbstractCRS.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/AbstractCRS.java
@@ -19,7 +19,6 @@ package org.apache.sis.referencing.crs;
import java.util.Map;
import java.util.EnumMap;
import java.util.Objects;
-import java.util.ConcurrentModificationException;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlSeeAlso;
@@ -121,7 +120,7 @@ public class AbstractCRS extends AbstractReferenceSystem
implements CoordinateRe
*
* @see #forConvention(AxesConvention)
*/
- final EnumMap<AxesConvention,AbstractCRS> forConvention;
+ private final EnumMap<AxesConvention,AbstractCRS> forConvention;
/**
* Creates the value to assign to the {@link #forConvention} map by
constructors.
@@ -337,23 +336,33 @@ public class AbstractCRS extends AbstractReferenceSystem
implements CoordinateRe
}
/**
- * Sets the CRS for the given axes convention.
+ * Returns the cached <abbr>CRS</abbr> for the given axes convention.
*
- * @param crs the CRS to cache.
+ * @return the cached <abbr>CRS</abbr>, or {@code null} if none.
+ */
+ final AbstractCRS getCached(final AxesConvention convention) {
+ synchronized (forConvention) {
+ return forConvention.get(convention);
+ }
+ }
+
+ /**
+ * Sets the <abbr>CRS</abbr> for the given axes convention.
+ *
+ * @param crs the <abbr>CRS</abbr> to cache.
* @return the cached CRS. May be different than the given {@code crs} if
an existing instance has been found.
*/
final AbstractCRS setCached(final AxesConvention convention, AbstractCRS
crs) {
- assert Thread.holdsLock(forConvention);
- for (final AbstractCRS existing : forConvention.values()) {
- if (crs.equals(existing, ComparisonMode.IGNORE_METADATA)) {
- crs = existing;
- break;
- }
- }
- if (forConvention.put(convention, crs) != null) {
- throw new ConcurrentModificationException(); // Should never
happen, unless we have a synchronization bug.
+ synchronized (forConvention) {
+ return forConvention.computeIfAbsent(convention, (c) -> {
+ for (final AbstractCRS existing : forConvention.values()) {
+ if (crs.equals(existing, ComparisonMode.IGNORE_METADATA)) {
+ return existing;
+ }
+ }
+ return crs;
+ });
}
- return crs;
}
/**
@@ -366,23 +375,21 @@ public class AbstractCRS extends AbstractReferenceSystem
implements CoordinateRe
* @see AbstractCS#forConvention(AxesConvention)
*/
public AbstractCRS forConvention(final AxesConvention convention) {
- synchronized (forConvention) {
- AbstractCRS crs =
forConvention.get(Objects.requireNonNull(convention));
- if (crs == null) {
- final AbstractCS cs = AbstractCS.castOrCopy(coordinateSystem);
- final AbstractCS candidate = cs.forConvention(convention);
- if (candidate.equals(cs, ComparisonMode.IGNORE_METADATA)) {
- crs = this;
- } else try {
- crs = createSameType(candidate);
- crs.getCoordinateSystem(); // Throws
ClassCastException if the CS type is invalid.
- } catch (ClassCastException e) {
- throw new
IllegalArgumentException(Errors.format(Errors.Keys.CanNotCompute_1,
convention), e);
- }
- crs = setCached(convention, crs);
+ AbstractCRS crs = getCached(Objects.requireNonNull(convention));
+ if (crs == null) {
+ final AbstractCS cs = AbstractCS.castOrCopy(coordinateSystem);
+ final AbstractCS candidate = cs.forConvention(convention);
+ if (candidate.equals(cs, ComparisonMode.IGNORE_METADATA)) {
+ crs = this;
+ } else try {
+ crs = createSameType(candidate);
+ crs.getCoordinateSystem(); // Throws
ClassCastException if the CS type is invalid.
+ } catch (ClassCastException e) {
+ throw new
IllegalArgumentException(Errors.format(Errors.Keys.CanNotCompute_1,
convention), e);
}
- return crs;
+ crs = setCached(convention, crs);
}
+ return crs;
}
/**
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
index 7c619b698b..9cd24a1aa5 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
@@ -534,33 +534,31 @@ public class DefaultCompoundCRS extends AbstractCRS
implements CompoundCRS {
*/
@Override
public DefaultCompoundCRS forConvention(final AxesConvention convention) {
- synchronized (forConvention) {
- var crs = (DefaultCompoundCRS)
forConvention.get(Objects.requireNonNull(convention));
- if (crs == null) {
- crs = this;
- boolean changed = false;
- final boolean reorderCRS = convention.ordinal() >=
AxesConvention.DISPLAY_ORIENTED.ordinal();
- final List<? extends CoordinateReferenceSystem> elements =
reorderCRS ? singles : components;
- final CoordinateReferenceSystem[] newComponents = new
CoordinateReferenceSystem[elements.size()];
- for (int i=0; i<newComponents.length; i++) {
- CoordinateReferenceSystem component = elements.get(i);
- AbstractCRS m = castOrCopy(component);
- if (m != (m = m.forConvention(convention))) {
- component = m;
- changed = true;
- }
- newComponents[i] = component;
+ var crs = (DefaultCompoundCRS)
getCached(Objects.requireNonNull(convention));
+ if (crs == null) {
+ crs = this;
+ boolean changed = false;
+ final boolean reorderCRS = convention.ordinal() >=
AxesConvention.DISPLAY_ORIENTED.ordinal();
+ final List<? extends CoordinateReferenceSystem> elements =
reorderCRS ? singles : components;
+ final CoordinateReferenceSystem[] newComponents = new
CoordinateReferenceSystem[elements.size()];
+ for (int i=0; i<newComponents.length; i++) {
+ CoordinateReferenceSystem component = elements.get(i);
+ AbstractCRS m = castOrCopy(component);
+ if (m != (m = m.forConvention(convention))) {
+ component = m;
+ changed = true;
}
- if (changed) {
- if (reorderCRS) {
- Arrays.sort(newComponents, SubTypes.BY_TYPE); //
This array typically has less than 4 elements.
- }
- crs = new DefaultCompoundCRS(crs, newComponents);
+ newComponents[i] = component;
+ }
+ if (changed) {
+ if (reorderCRS) {
+ Arrays.sort(newComponents, SubTypes.BY_TYPE); // This
array typically has less than 4 elements.
}
- crs = (DefaultCompoundCRS) setCached(convention, crs);
+ crs = new DefaultCompoundCRS(crs, newComponents);
}
- return crs;
+ crs = (DefaultCompoundCRS) setCached(convention, crs);
}
+ return crs;
}
/**
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/AbstractCS.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/AbstractCS.java
index 08eda817e8..11321ae857 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/AbstractCS.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/AbstractCS.java
@@ -19,7 +19,7 @@ package org.apache.sis.referencing.cs;
import java.util.Map;
import java.util.EnumMap;
import java.util.Arrays;
-import java.util.ConcurrentModificationException;
+import java.util.Objects;
import java.util.logging.Logger;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.XmlElement;
@@ -135,7 +135,7 @@ public class AbstractCS extends AbstractIdentifiedObject
implements CoordinateSy
*
* @see #forConvention(AxesConvention)
*/
- final EnumMap<AxesConvention,AbstractCS> forConvention;
+ private final EnumMap<AxesConvention,AbstractCS> forConvention;
/**
* Creates the value to assign to the {@link #forConvention} map by
constructors.
@@ -427,27 +427,37 @@ next: for (final CoordinateSystemAxis axis : axes) {
}
/**
- * Sets the CS for the given axes convention.
+ * Returns the cached Coordinate System (<abbr>CS</abbr>) for the given
axes convention.
*
- * @param cs the CS to cache.
- * @return the cached CS. May be different than the given {@code cs} if an
existing instance has been found.
+ * @return the cached <abbr>CS</abbr>, or {@code null} if none.
*/
- final AbstractCS setCached(final AxesConvention convention, AbstractCS cs)
{
- assert Thread.holdsLock(forConvention);
- /*
- * It happens often that the CRS created by RIGHT_HANDED,
DISPLAY_ORIENTED and NORMALIZED are the same.
- * Sharing the same instance not only saves memory, but can also makes
future comparisons faster.
- */
- for (final AbstractCS existing : forConvention.values()) {
- if (cs.equals(existing, ComparisonMode.IGNORE_METADATA)) {
- cs = existing;
- break;
- }
+ final AbstractCS getCached(final AxesConvention convention) {
+ synchronized (forConvention) {
+ return forConvention.get(convention);
}
- if (forConvention.put(convention, cs) != null) {
- throw new ConcurrentModificationException(); // Should never
happen, unless we have a synchronization bug.
+ }
+
+ /**
+ * Sets the Coordinate System (<abbr>CS</abbr>) for the given axes
convention.
+ *
+ * @param cs the <abbr>CS</abbr> to cache.
+ * @return the cached CS. May be different than the given {@code cs} if an
existing instance has been found.
+ */
+ final AbstractCS setCached(final AxesConvention convention, final
AbstractCS cs) {
+ synchronized (forConvention) {
+ /*
+ * It happens often that the CRS created by RIGHT_HANDED,
DISPLAY_ORIENTED and NORMALIZED are the same.
+ * Sharing the same instance not only saves memory, but can also
makes future comparisons faster.
+ */
+ return forConvention.computeIfAbsent(convention, (c) -> {
+ for (final AbstractCS existing : forConvention.values()) {
+ if (cs.equals(existing, ComparisonMode.IGNORE_METADATA)) {
+ return existing;
+ }
+ }
+ return cs;
+ });
}
- return cs;
}
/**
@@ -460,19 +470,18 @@ next: for (final CoordinateSystemAxis axis : axes) {
* @see
org.apache.sis.referencing.crs.AbstractCRS#forConvention(AxesConvention)
*/
public AbstractCS forConvention(final AxesConvention convention) {
- synchronized (forConvention) {
- AbstractCS cs = forConvention.get(convention);
+ AbstractCS cs = getCached(Objects.requireNonNull(convention));
+ if (cs == null) {
+ // Need to be outside the synchronized block because it may query
the EPSG database.
+ cs = Normalizer.forConvention(this, convention);
if (cs == null) {
- cs = Normalizer.forConvention(this, convention);
- if (cs == null) {
- cs = this; // This coordinate system is already
normalized.
- } else if (convention != AxesConvention.POSITIVE_RANGE) {
- cs = cs.resolveEPSG(this);
- }
- cs = setCached(convention, cs);
+ cs = this; // This coordinate system is already
normalized.
+ } else if (convention != AxesConvention.POSITIVE_RANGE) {
+ cs = cs.resolveEPSG(this);
}
- return cs;
+ cs = setCached(convention, cs);
}
+ return cs;
}
/**
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/DefaultCompoundCS.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/DefaultCompoundCS.java
index c43920f06f..7d77b4a6fa 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/DefaultCompoundCS.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/DefaultCompoundCS.java
@@ -189,28 +189,26 @@ public class DefaultCompoundCS extends AbstractCS {
*/
@Override
public DefaultCompoundCS forConvention(final AxesConvention convention) {
- synchronized (forConvention) {
- var cs = (DefaultCompoundCS)
forConvention.get(Objects.requireNonNull(convention));
- if (cs == null) {
- cs = this;
- boolean changed = false;
- final var newComponents = new
CoordinateSystem[components.size()];
- for (int i=0; i<newComponents.length; i++) {
- CoordinateSystem component = components.get(i);
- AbstractCS m = castOrCopy(component);
- if (m != (m = m.forConvention(convention))) {
- component = m;
- changed = true;
- }
- newComponents[i] = component;
+ DefaultCompoundCS cs = (DefaultCompoundCS)
getCached(Objects.requireNonNull(convention));
+ if (cs == null) {
+ cs = this;
+ boolean changed = false;
+ final var newComponents = new CoordinateSystem[components.size()];
+ for (int i=0; i<newComponents.length; i++) {
+ CoordinateSystem component = components.get(i);
+ AbstractCS m = castOrCopy(component);
+ if (m != (m = m.forConvention(convention))) {
+ component = m;
+ changed = true;
}
- if (changed) {
- cs = new DefaultCompoundCS(cs, newComponents);
- }
- cs = (DefaultCompoundCS) setCached(convention, cs);
+ newComponents[i] = component;
+ }
+ if (changed) {
+ cs = new DefaultCompoundCS(cs, newComponents);
}
- return cs;
+ cs = (DefaultCompoundCS) setCached(convention, cs);
}
+ return cs;
}
/*
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/Assertions.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/Assertions.java
index d571c2d513..11d2eb31e8 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/Assertions.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/Assertions.java
@@ -74,6 +74,20 @@ public final class Assertions extends Static {
WKT_FORMAT.setSymbols(s);
}
+ /**
+ * Replacements to perform in <abbr>WKT</abbr> strings for compatibility
between different versions
+ * of the <abbr>EPSG</abbr> geodetic dataset. Values at even indexes are
legacy names that may still
+ * be present in the tests. Values at odd indexes are the names as they
may be formatted when using
+ * newer versions of the <abbr>EPSG</abbr> geodetic dataset.
+ *
+ * <p>We may remove this hack in a future <abbr>SIS</abbr> version if we
abandon support of version 9
+ * of <abbr>EPSG</abbr> dataset (the current version at the time of
writing is 12).</p>
+ */
+ private static final String[] REPLACEMENTS = {
+ "“World Geodetic System 1984”", "“World Geodetic System 1984
ensemble”",
+ "“NGF IGN69 height”", "“NGF-IGN69 height”"
+ };
+
/**
* Do not allow instantiation of this class.
*/
@@ -105,10 +119,10 @@ public final class Assertions extends Static {
*/
public static void assertEpsgIdentifierEquals(final String expected, final
Identifier actual) {
assertNotNull(actual);
- assertEquals(expected, actual.getCode(), "code");
+ assertLegacyEquals(expected, actual.getCode(), "code");
assertEquals(Constants.EPSG, actual.getCodeSpace(), "codeSpace");
assertEquals(Constants.EPSG,
Citations.toCodeSpace(actual.getAuthority()), "authority");
- assertEquals(Constants.EPSG + Constants.DEFAULT_SEPARATOR + expected,
IdentifiedObjects.toString(actual), "identifier");
+ assertLegacyEquals(Constants.EPSG + Constants.DEFAULT_SEPARATOR +
expected, IdentifiedObjects.toString(actual), "identifier");
}
/**
@@ -468,6 +482,48 @@ public final class Assertions extends Static {
}
}
+ /**
+ * Asserts that the given string is equal to the expected string,
+ * with a tolerance for name changes in <abbr>EPSG</abbr> database.
+ * If the expected string is a old name while the actual string is a new
name,
+ * then they are considered equal.
+ *
+ * <p>We may remove this hack in a future <abbr>SIS</abbr> version if we
abandon support of version 9
+ * of <abbr>EPSG</abbr> dataset (the current version at the time of
writing is 12). If this method is
+ * removed, it would be replaced by an ordinary {@code assertEquals}.</p>
+ *
+ * @param expected the expected string.
+ * @param actual the actual string.
+ */
+ public static void assertLegacyEquals(final String expected, final String
actual) {
+ assertLegacyEquals(expected, actual, null);
+ }
+
+ private static void assertLegacyEquals(String expected, final String
actual, final String message) {
+ if (expected != null && actual != null) {
+ for (int i=0; i < REPLACEMENTS.length;) {
+ final String oldName = REPLACEMENTS[i++];
+ final String newName = REPLACEMENTS[i++];
+ final int ol = oldName.length() - 2; // Omit quotes.
+ final int nl = newName.length() - 2;
+ final int s = expected.length() - ol;
+ if (expected.regionMatches(s, oldName, 1, ol) &&
+ actual.regionMatches(actual.length() - nl, newName, 1,
nl))
+ {
+ expected = expected.substring(0, s) + newName.substring(1,
nl + 1);
+ }
+ }
+ if (expected.replace("GeodeticDatum",
"DatumEnsemble").equals(actual)) {
+ return;
+ }
+ }
+ if (message != null) {
+ assertEquals(expected, actual, message);
+ } else {
+ assertEquals(expected, actual);
+ }
+ }
+
/**
* Asserts that the WKT 2 of the given object is equal to the expected one.
* This method expected the {@code “…”} quotation marks instead of {@code
"…"}
@@ -489,7 +545,7 @@ public final class Assertions extends Static {
* @param expected the expected text, or {@code null} if {@code object}
is expected to be null.
* @param object the object to format in <i>Well Known Text</i>
format, or {@code null}.
*/
- public static void assertWktEquals(final Convention convention, final
String expected, final Object object) {
+ public static void assertWktEquals(final Convention convention, String
expected, final Object object) {
if (expected == null) {
assertNull(object);
} else {
@@ -499,6 +555,13 @@ public final class Assertions extends Static {
WKT_FORMAT.setConvention(convention);
wkt = WKT_FORMAT.format(object);
}
+ for (int i=0; i < REPLACEMENTS.length;) {
+ final String oldName = REPLACEMENTS[i++];
+ final String newName = REPLACEMENTS[i++];
+ if (expected.contains(oldName) && wkt.contains(newName)) {
+ expected = expected.replace(oldName, newName);
+ }
+ }
assertMultilinesEquals(expected, wkt, (object instanceof
IdentifiedObject) ?
((IdentifiedObject) object).getName().getCode() :
object.getClass().getSimpleName());
}
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
index f457ff1b51..ce8bf97cb0 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/CommonCRSTest.java
@@ -399,8 +399,8 @@ public final class CommonCRSTest extends
EPSGDependentTestCase {
*/
@Test
public void testFormat() {
- assertEquals("World Geodetic System 1984", String.format("%s",
CommonCRS.WGS84.datum()));
- assertEquals("WORLD GEODETIC SYSTEM 1984", String.format("%S",
CommonCRS.WGS84.datum()));
+ Assertions.assertLegacyEquals("World Geodetic System 1984",
String.format("%s", CommonCRS.WGS84.datum()));
+ assertTrue(String.format("%S",
CommonCRS.WGS84.datum()).startsWith("WORLD GEODETIC SYSTEM 1984"));
assertTrue(String.format("%#s",
CommonCRS.WGS84.datum()).endsWith(":6326"));
}
}
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
index 2a258c95f1..ae0e7d31b5 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/CommonAuthorityFactoryTest.java
@@ -383,7 +383,7 @@ public final class CommonAuthorityFactoryTest extends
TestCase {
GeographicCRS crs = factory.createGeographicCRS("CRS:84");
assertWktEqualsRegex(Convention.WKT1, "(?m)\\Q" + //
Multilines
"GEOGCS[" + WGS84 + ",\n" +
- " DATUM[“World Geodetic System 1984”,\n" +
+ " DATUM[“World Geodetic System 1984\\E\\s?\\w*\\Q”,\n" +
" SPHEROID[" + WGS84 + ", 6378137.0, 298.257223563]],\n" +
" PRIMEM[“Greenwich”, 0.0],\n" +
" UNIT[“degree”, 0.017453292519943295],\n" +
@@ -393,7 +393,7 @@ public final class CommonAuthorityFactoryTest extends
TestCase {
assertWktEqualsRegex(Convention.WKT2, "(?m)\\Q" +
"GEODCRS[" + WGS84 + ",\n" +
- " DATUM[“World Geodetic System 1984”,\n" +
+ " DATUM[“World Geodetic System 1984\\E\\s?\\w*\\Q”,\n" +
" ELLIPSOID[" + WGS84 + ", 6378137.0, 298.257223563,
LENGTHUNIT[“metre”, 1]]],\n" +
" PRIMEM[“Greenwich”, 0.0, ANGLEUNIT[“degree”,
0.017453292519943295]],\n" +
" CS[ellipsoidal, 2],\n" +
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java
index 3dcd46f972..985c0fa85b 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java
@@ -48,6 +48,7 @@ import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.IdentifiedObjects;
import org.apache.sis.referencing.cs.AxesConvention;
import org.apache.sis.referencing.crs.DefaultGeographicCRS;
+import org.apache.sis.referencing.datum.DatumOrEnsemble;
import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
import org.apache.sis.util.collection.BackingStoreException;
@@ -117,7 +118,7 @@ public final class EPSGFactoryTest extends TestCaseWithLogs
{
final EPSGFactory factory = dataEPSG.factory();
final GeographicCRS crs = factory.createGeographicCRS("EPSG:4326");
assertEpsgNameAndIdentifierEqual("WGS 84", 4326, crs);
- assertEpsgNameAndIdentifierEqual("World Geodetic System 1984", 6326,
crs.getDatum());
+ assertEpsgNameAndIdentifierEqual("World Geodetic System 1984", 6326,
DatumOrEnsemble.of(crs));
assertAxisDirectionsEqual(crs.getCoordinateSystem(),
AxisDirection.NORTH, AxisDirection.EAST);
assertSame(crs, factory.createCoordinateReferenceSystem("4326"), "CRS
shall be cached.");
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/CoordinateReferenceSystemTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/CoordinateReferenceSystemTest.java
index 7ab3a9864d..f8a28d18a3 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/CoordinateReferenceSystemTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/test/integration/CoordinateReferenceSystemTest.java
@@ -17,9 +17,6 @@
package org.apache.sis.test.integration;
import org.opengis.util.FactoryException;
-import org.opengis.referencing.cs.CartesianCS;
-import org.opengis.referencing.cs.EllipsoidalCS;
-import org.opengis.referencing.crs.DerivedCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.referencing.CRS;
@@ -29,9 +26,6 @@ import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.test.TestCase;
import org.apache.sis.referencing.factory.TestFactorySource;
-// Specific to the geoapi-4.0 branch:
-import org.opengis.referencing.crs.ProjectedCRS;
-
/**
* Advanced CRS constructions requiring the EPSG geodetic dataset.
@@ -57,31 +51,4 @@ public final class CoordinateReferenceSystemTest extends
TestCase {
CoordinateReferenceSystem crs = CRS.forCode("urn:ogc:def:crs,
crs:EPSG::27700, crs:EPSG::5701");
assertSame(CRS.forCode("EPSG:7405"), crs, "OSGB 1936 / British
National Grid + ODN height");
}
-
- /**
- * Tests creation of "EPSG topocentric example A/B". They are derived
geodetic CRS.
- *
- * @throws FactoryException if an authority or a code is not recognized.
- */
- @Test
- public void testDerivedCRS() throws FactoryException {
- assertTrue(TestFactorySource.getSharedFactory() != null);
- CoordinateReferenceSystem crs = CRS.forCode("EPSG:5820");
- assertInstanceOf(DerivedCRS .class, crs);
- assertInstanceOf(ProjectedCRS.class, crs);
- assertInstanceOf(CartesianCS .class, crs.getCoordinateSystem());
- assertInstanceOf(CartesianCS .class, ((DerivedCRS)
crs).getBaseCRS().getCoordinateSystem());
- /*
- * Some tests are disabled because `EPSGDataAccess` confuses CRS type.
- * We are waiting for upgrade to EPSG database 10+ before to
re-evaluate
- * how to fix this issue.
- *
- * https://issues.apache.org/jira/browse/SIS-518
- */
- crs = CRS.forCode("EPSG:5819");
-// assertInstanceOf(DerivedCRS .class, crs);
-// assertInstanceOf(GeodeticCRS.class, crs);
- assertInstanceOf(CartesianCS.class, crs.getCoordinateSystem());
- assertInstanceOf(EllipsoidalCS.class, ((DerivedCRS)
crs).getBaseCRS().getCoordinateSystem());
- }
}