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 cf8135d4e3ff035de67f431bd907b8cd2f1699a1 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Sun Oct 6 16:21:22 2024 +0200 `ConcurrentAuthorityFactory.getAuthority()` should propagate the exception instead of logging when the Data Access Object (DAO) cannot connect to the EPSG database. The previous policy was partially responsible for the too verbose logs because it caused callers to retry before they realize that the EPSG factory is not available. --- .../org/apache/sis/util/iso/AbstractFactory.java | 17 ++++++--- .../sis/referencing/MultiRegisterOperations.java | 12 ++++--- .../factory/ConcurrentAuthorityFactory.java | 30 +++------------- .../factory/GeodeticAuthorityFactory.java | 15 ++++---- .../factory/IdentifiedObjectFinder.java | 2 ++ .../referencing/factory/IdentifiedObjectSet.java | 12 +++++-- .../factory/MultiAuthoritiesFactory.java | 30 +++++++++++----- .../referencing/factory/sql/EPSGDataAccess.java | 2 +- .../sis/referencing/internal/EPSGFactoryProxy.java | 2 +- .../operation/transform/MathTransformBuilder.java | 4 +-- .../org/apache/sis/io/wkt/WKTDictionaryTest.java | 41 +++++++++++++--------- .../sis/referencing/AuthorityFactoriesTest.java | 15 +++++--- .../sis/referencing/EPSGFactoryFallbackTest.java | 3 ++ .../referencing/factory/AuthorityFactoryMock.java | 10 ++++-- .../factory/CommonAuthorityFactoryTest.java | 15 ++++++-- .../factory/MultiAuthoritiesFactoryTest.java | 37 ++++++++++++------- .../referencing/factory/sql/EPSGFactoryTest.java | 12 ++++--- .../referencing/factory/sql/EPSGInstallerTest.java | 3 ++ geoapi/snapshot | 2 +- 19 files changed, 164 insertions(+), 100 deletions(-) diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/AbstractFactory.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/AbstractFactory.java index 11a32493d4..63ffdc7d42 100644 --- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/AbstractFactory.java +++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/util/iso/AbstractFactory.java @@ -17,6 +17,7 @@ package org.apache.sis.util.iso; import org.opengis.util.Factory; +import org.opengis.util.FactoryException; import org.opengis.metadata.citation.Citation; import org.apache.sis.metadata.simple.SimpleCitation; import org.apache.sis.util.privy.Strings; @@ -42,11 +43,12 @@ public abstract class AbstractFactory implements Factory { * manifest associated to the package of {@code this.getClass()}. * * @return the vendor for this factory implementation, or {@code null} if unknown. + * @throws FactoryException if an error occurred while fetching the vendor information. * * @see Package#getImplementationVendor() */ @Override - public Citation getVendor() { + public Citation getVendor() throws FactoryException { final Package p = getClass().getPackage(); if (p != null) { final String vendor = p.getImplementationVendor(); @@ -68,10 +70,15 @@ public abstract class AbstractFactory implements Factory { @Override public String toString() { final var args = new Object[2]; - Citation c = getVendor(); - if (c != null) { - args[0] = "vendor"; - args[1] = c.getTitle(); + try { + Citation c = getVendor(); + if (c != null) { + args[0] = "vendor"; + args[1] = c.getTitle(); + } + } catch (FactoryException e) { + args[0] = "exception"; + args[1] = e.toString(); } return Strings.toString(getClass(), args); } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/MultiRegisterOperations.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/MultiRegisterOperations.java index df73f26de5..ca5b60b103 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/MultiRegisterOperations.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/MultiRegisterOperations.java @@ -180,12 +180,13 @@ public class MultiRegisterOperations extends AbstractFactory implements Register * @param authority identification of the registry to use (e.g., "EPSG"). * @param version the registry version to use, or {@code null} for the default version. * @throws NoSuchAuthorityFactoryException if the specified registry has not been found. + * @throws FactoryException if an error occurred while initializing this factory. * * @see #withAuthority(String) * @see #withVersion(String) */ protected MultiRegisterOperations(final MultiRegisterOperations source, final String authority, final String version) - throws NoSuchAuthorityFactoryException + throws FactoryException { this.authority = Objects.requireNonNull(authority); this.version = version; @@ -205,10 +206,11 @@ public class MultiRegisterOperations extends AbstractFactory implements Register * @param newValue the desired authority, or {@code null} for all of them. * @return register operations for the specified authority. * @throws NoSuchAuthorityFactoryException if the given authority is unknown to SIS. + * @throws FactoryException if the factory cannot be created for another reason. * * @see CRS#getAuthorityFactory(String) */ - public MultiRegisterOperations withAuthority(final String newValue) throws NoSuchAuthorityFactoryException { + public MultiRegisterOperations withAuthority(final String newValue) throws FactoryException { if (version == null && Objects.equals(authority, newValue)) { return this; } else if (newValue == null) { @@ -227,8 +229,9 @@ public class MultiRegisterOperations extends AbstractFactory implements Register * @return register operations for the specified version of the geodetic registry. * @throws IllegalStateException if the version is non-null and no authority has been specified previously. * @throws NoSuchAuthorityFactoryException if the given version is unknown to SIS. + * @throws FactoryException if the factory cannot be created for another reason. */ - public MultiRegisterOperations withVersion(final String newValue) throws NoSuchAuthorityFactoryException { + public MultiRegisterOperations withVersion(final String newValue) throws FactoryException { if (Objects.equals(version, newValue)) { return this; } else if (newValue == null && authority == null) { @@ -365,9 +368,10 @@ public class MultiRegisterOperations extends AbstractFactory implements Register * @return factory of the specified type. * @throws NullPointerException if the specified type is null. * @throws IllegalArgumentException if the specified type is not one of the above-cited values. + * @throws FactoryException if an error occurred while searching or preparing the requested factory. */ @Override - public <T extends Factory> Optional<T> getFactory(final Class<? extends T> type) { + public <T extends Factory> Optional<T> getFactory(final Class<? extends T> type) throws FactoryException { final Factory factory; final Boolean b = FACTORY_TYPES.get(type); if (b != null) { diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java index 38ea78fc05..3e675a5408 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java @@ -56,7 +56,6 @@ import org.apache.sis.util.logging.PerformanceLevel; import org.apache.sis.util.collection.Cache; import org.apache.sis.util.privy.CollectionsExt; import org.apache.sis.util.privy.Constants; -import org.apache.sis.metadata.simple.SimpleCitation; import org.apache.sis.system.Cleaners; import org.apache.sis.system.DelayedExecutor; import org.apache.sis.system.DelayedRunnable; @@ -117,14 +116,10 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa @Configuration private static final long DURATION_FOR_LOGGING = 10_000_000L; // 10 milliseconds. - /** - * Sentinel value when {@link #authority} cannot be determined because the data access object - * cannot be constructed. - */ - private static final Citation UNAVAILABLE = new SimpleCitation("unavailable"); - /** * The authority, cached after first requested. + * + * @see #getAuthority() */ private transient volatile Citation authority; @@ -726,15 +721,13 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa * </li> * </ul> * - * If this method cannot get a Data Access Object (for example because no database connection is available), - * then this method returns {@code null}. - * * @return the organization responsible for definition of the database, or {@code null} if unavailable. + * @throws FactoryException if an error occurred while creating the Data Access Object (<abbr>DAO</abbr>). */ @Override - public Citation getAuthority() { + public Citation getAuthority() throws FactoryException { Citation c = authority; - if (c == null || c == UNAVAILABLE) try { + if (c == null) { final DAO factory = getDataAccess(); try { /* @@ -745,19 +738,6 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa } finally { release("getAuthority", Citation.class, null); } - } catch (FactoryException e) { - authority = UNAVAILABLE; - /* - * Use the warning level only on the first failure, then the fine level on all subsequent failures. - * Do not log the stack trace if we failed because of UnavailableFactoryException since it may be - * normal (the EPSG geodetic dataset is optional, even if strongly recommended). - */ - final var record = new LogRecord(c == null ? Level.WARNING : Level.FINE, e.getLocalizedMessage()); - if (!(e instanceof UnavailableFactoryException)) { - record.setThrown(e); - } - Logging.completeAndLog(LOGGER, ConcurrentAuthorityFactory.class, "getAuthority", record); - c = null; } return c; } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java index 55a356df52..9f6ab5bd22 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java @@ -103,11 +103,12 @@ public abstract class GeodeticAuthorityFactory extends AbstractFactory implement * The online resource description with a “Connection” function is a SIS extension. * * @return the organization responsible for definition of the database, or {@code null} if unknown. + * @throws FactoryException if an error occurred while fetching information about the authority. * * @see #getVendor() */ @Override - public abstract Citation getAuthority(); + public abstract Citation getAuthority() throws FactoryException; /** * Returns all namespaces recognized by this factory. Those namespaces can appear before codes in @@ -141,8 +142,9 @@ public abstract class GeodeticAuthorityFactory extends AbstractFactory implement * all factory lifetime. * * @return the namespaces recognized by this factory, or an empty set if none. + * @throws FactoryException if an error occurred while listing the code spaces managed by this factory. */ - public Set<String> getCodeSpaces() { + public Set<String> getCodeSpaces() throws FactoryException { final String authority = Citations.toCodeSpace(getAuthority()); return (authority != null) ? Set.of(authority) : Set.of(); } @@ -1254,12 +1256,12 @@ public abstract class GeodeticAuthorityFactory extends AbstractFactory implement * are removed, together with {@link Character#isIdentifierIgnorable(int) ignorable characters}. * * @param code the code to trim. - * @return the code with the namespace part removed if that part matched one of the values given by - * {@link #getCodeSpaces()}. + * @return the code with the namespace part removed if that part matched one of the values given by {@link #getCodeSpaces()}. + * @throws FactoryException if an error occurred while listing the code spaces managed by this factory. * * @since 0.8 */ - protected final String trimNamespace(String code) { + protected final String trimNamespace(String code) throws FactoryException { code = CharSequences.trimIgnorables(code).toString(); int s = code.indexOf(Constants.DEFAULT_SEPARATOR); if (s >= 0) { @@ -1293,10 +1295,11 @@ public abstract class GeodeticAuthorityFactory extends AbstractFactory implement * @param code the authority code, used only for formatting an error message. * @return the object casted to the given type. * @throws NoSuchAuthorityCodeException if the given object is not an instance of the given type. + * @throws FactoryException if an error occurred while listing the code spaces managed by this factory. */ @SuppressWarnings("unchecked") private <T> T cast(final Class<T> type, final IdentifiedObject object, final String code) - throws NoSuchAuthorityCodeException + throws FactoryException { if (type.isInstance(object)) { return (T) object; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java index 035277476d..75daa4bc2f 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectFinder.java @@ -523,6 +523,8 @@ public class IdentifiedObjectFinder { result.add(candidate); } } + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); } finally { Semaphores.clear(Semaphores.FINER_OBJECT_CREATION_LOGS, finer); } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectSet.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectSet.java index 3abc6e9f4b..818e5379f3 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectSet.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/IdentifiedObjectSet.java @@ -31,6 +31,7 @@ import java.util.logging.LogRecord; import org.opengis.util.FactoryException; import org.opengis.util.NoSuchIdentifierException; import org.opengis.metadata.Identifier; +import org.opengis.metadata.citation.Citation; import org.opengis.referencing.AuthorityFactory; import org.opengis.referencing.IdentifiedObject; import org.opengis.referencing.NoSuchAuthorityCodeException; @@ -76,7 +77,7 @@ import org.apache.sis.util.collection.CheckedContainer; * if they intent to cache {@code IdentifiedObjectSet} instances. * * @author Martin Desruisseaux (IRD, Geomatys) - * @version 1.4 + * @version 1.5 * * @param <T> the type of objects to be included in this set. * @@ -503,9 +504,16 @@ public class IdentifiedObjectSet<T extends IdentifiedObject> extends AbstractSet * * @param object the object for which to get the authority code. * @return the authority code of the given identified object. + * @throws BackingStoreException if an error occurred while fetching the authority code. */ protected String getAuthorityCode(final T object) { - final Identifier id = IdentifiedObjects.getIdentifier(object, factory.getAuthority()); + final Citation authority; + try { + authority = factory.getAuthority(); + } catch (FactoryException e) { + throw new BackingStoreException(e); + } + final Identifier id = IdentifiedObjects.getIdentifier(object, authority); return (id != null) ? id.getCode() : IdentifiedObjects.getIdentifierOrName(object); } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java index 682ea459d2..2a274354f7 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java @@ -464,7 +464,11 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements private final AuthorityFactoryProxy<Boolean> contains = new AuthorityFactoryProxy<Boolean>(Boolean.class, AuthorityFactoryIdentifier.Type.ANY) { @Override Boolean createFromAPI(AuthorityFactory factory, String code) throws FactoryException { - return getAuthorityCodes(factory).contains(code); + try { + return getAuthorityCodes(factory).contains(code); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); + } } @Override AuthorityFactoryProxy<Boolean> specialize(String typeName) { return this; @@ -500,10 +504,11 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements * The current implementation may be relatively costly because it implies instantiation of all factories. * * @return the code spaces of all factories. + * @throws FactoryException if an error occurred while listing the code spaces managed by this factory. */ @Override @SuppressWarnings("ReturnOfCollectionOrArrayField") - public Set<String> getCodeSpaces() { + public Set<String> getCodeSpaces() throws FactoryException { Set<String> union = codeSpaces; if (union == null) { union = new LinkedHashSet<>(); @@ -520,7 +525,7 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements * This method delegates to {@link GeodeticAuthorityFactory#getCodeSpaces()} if possible, * or reproduces its default implementation otherwise. */ - private static Set<String> getCodeSpaces(final AuthorityFactory factory) { + private static Set<String> getCodeSpaces(final AuthorityFactory factory) throws FactoryException { if (factory instanceof GeodeticAuthorityFactory) { return ((GeodeticAuthorityFactory) factory).getCodeSpaces(); } else { @@ -531,12 +536,19 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements /** * Returns the "main" namespace of the given factory, or {@code null} if none. + * The purpose of this method is to get a unique identifier of a factory, ignoring version number. * Current implementation returns the first namespace, but this may be changed in any future SIS version. * - * <p>The purpose of this method is to get a unique identifier of a factory, ignoring version number.</p> + * @param factory the factory for which to get the main code space. + * @return the main code space of the given factory, or {@code null} if none. + * @throws BackingStoreException if an error occurred while listing the code spaces managed by this factory. */ static String getCodeSpace(final AuthorityFactory factory) { - return CollectionsExt.first(getCodeSpaces(factory)); + try { + return CollectionsExt.first(getCodeSpaces(factory)); + } catch (FactoryException e) { + throw new BackingStoreException(e); + } } /** @@ -578,6 +590,7 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements * @param version the version of the desired factory, or {@code null} for the default version. * @return the factory for the given type, authority and version. * @throws NoSuchAuthorityFactoryException if no suitable factory has been found. + * @throws FactoryException if an error occurred while getting the authority or code spaces managed by this factory. */ /* * This method is declared final for avoiding the false impression than overriding this method would change @@ -585,7 +598,7 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements * `getAuthorityFactory(…)` instead of the public one. */ public final <T extends AuthorityFactory> T getAuthorityFactory(final Class<T> type, - final String authority, final String version) throws NoSuchAuthorityFactoryException + final String authority, final String version) throws FactoryException { ArgumentChecks.ensureNonNull("type", type); ArgumentChecks.ensureNonNull("authority", authority); @@ -599,10 +612,9 @@ public class MultiAuthoritiesFactory extends GeodeticAuthorityFactory implements * @param request the type, authority and version of the desired factory. * @return the factory for the given type, authority and version. * @throws NoSuchAuthorityFactoryException if no suitable factory has been found. + * @throws FactoryException if an error occurred while getting the authority or code spaces managed by this factory. */ - private AuthorityFactory getAuthorityFactory(final AuthorityFactoryIdentifier request) - throws NoSuchAuthorityFactoryException - { + private AuthorityFactory getAuthorityFactory(final AuthorityFactoryIdentifier request) throws FactoryException { AuthorityFactory factory = factories.get(request); if (factory != null) { return factory; 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 f1157ed54d..261177717c 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 @@ -1091,7 +1091,7 @@ codes: for (int i=0; i<codes.length; i++) { */ @SuppressWarnings("ReturnOfCollectionOrArrayField") private Map<String,Object> createProperties(final String table, String name, final Integer code, - CharSequence remarks, final boolean deprecated) throws SQLException, FactoryDataException + CharSequence remarks, final boolean deprecated) throws SQLException, FactoryException { /* * Search for aliases. Note that searching for the object code is not sufficient. We also need to check if the diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/EPSGFactoryProxy.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/EPSGFactoryProxy.java index d95a07f53a..1aaced7e15 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/EPSGFactoryProxy.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/internal/EPSGFactoryProxy.java @@ -52,7 +52,7 @@ public abstract class EPSGFactoryProxy implements AuthorityFactory { } @Override - public final Citation getVendor() { + public final Citation getVendor() throws FactoryException { try { return factory().getVendor(); } catch (FactoryException e) { diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransformBuilder.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransformBuilder.java index 05ec64e681..27b845bc66 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransformBuilder.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransformBuilder.java @@ -21,9 +21,9 @@ import java.util.Optional; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.OperationMethod; -import org.apache.sis.metadata.iso.citation.Citations; import org.apache.sis.referencing.IdentifiedObjects; import org.apache.sis.util.privy.Strings; +import org.apache.sis.util.Classes; /** @@ -104,7 +104,7 @@ public abstract class MathTransformBuilder implements MathTransform.Builder { @Override public String toString() { return Strings.toString(getClass(), - "factory", Citations.getIdentifier(factory.getVendor()), + "factory", Classes.getShortClassName(factory), "method", IdentifiedObjects.getDisplayName(provider, null)); } } diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/WKTDictionaryTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/WKTDictionaryTest.java index d937e32a3d..1d9e70c197 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/WKTDictionaryTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/WKTDictionaryTest.java @@ -36,6 +36,7 @@ import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.crs.GeodeticCRS; import org.opengis.referencing.cs.AxisDirection; import org.apache.sis.metadata.iso.DefaultIdentifier; +import org.apache.sis.util.collection.BackingStoreException; // Test dependencies import org.junit.jupiter.api.Test; @@ -92,12 +93,16 @@ public final class WKTDictionaryTest extends TestCase { */ assertArrayEquals(new String[] {"TEST"}, factory.getCodeSpaces().toArray(), "getCodeSpaces()"); assertEquals("TEST", factory.getAuthority().getTitle().toString(), "getAuthority()"); - Set<String> codes = factory.getAuthorityCodes(IdentifiedObject.class); - assertSame( codes, factory.getAuthorityCodes(SingleCRS.class)); - assertSame( codes, factory.getAuthorityCodes(GeodeticCRS.class)); - assertSame( codes, factory.getAuthorityCodes(GeographicCRS.class)); - assertEquals(0, factory.getAuthorityCodes(ProjectedCRS.class).size()); - assertSetEquals(List.of("21", "E1"), codes); + try { + Set<String> codes = factory.getAuthorityCodes(IdentifiedObject.class); + assertSame( codes, factory.getAuthorityCodes(SingleCRS.class)); + assertSame( codes, factory.getAuthorityCodes(GeodeticCRS.class)); + assertSame( codes, factory.getAuthorityCodes(GeographicCRS.class)); + assertEquals(0, factory.getAuthorityCodes(ProjectedCRS.class).size()); + assertSetEquals(List.of("21", "E1"), codes); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); + } /* * Tests CRS creation, potentially with expected error. */ @@ -118,7 +123,7 @@ public final class WKTDictionaryTest extends TestCase { */ @Test public void testLoad() throws IOException, FactoryException { - final WKTDictionary factory = new WKTDictionary(null); + final var factory = new WKTDictionary(null); try (BufferedReader source = new BufferedReader(new InputStreamReader( WKTFormatTest.class.getResourceAsStream("ExtraCRS.txt"), "UTF-8"))) { @@ -137,15 +142,19 @@ public final class WKTDictionaryTest extends TestCase { */ assertArrayEquals(new String[] {"TEST", "ESRI"}, factory.getCodeSpaces().toArray(), "getCodeSpaces()"); assertEquals("TEST", factory.getAuthority().getTitle().toString(), "getAuthority()"); - Set<String> codes = factory.getAuthorityCodes(IdentifiedObject.class); - assertSame( codes, factory.getAuthorityCodes(IdentifiedObject.class)); // Test caching. - assertSame( codes, factory.getAuthorityCodes(SingleCRS.class)); // Test sharing. - assertSetEquals(List.of("102018", "ESRI::102021", "TEST::102021", "TEST:v2:102021", "E1", "E2"), codes); - assertSetEquals(List.of("102018", "ESRI::102021"), factory.getAuthorityCodes(ProjectedCRS.class)); - codes = factory.getAuthorityCodes(GeographicCRS.class); - assertSetEquals(List.of("TEST::102021", "TEST:v2:102021", "E1", "E2"), codes); - assertSame(codes, factory.getAuthorityCodes(GeodeticCRS.class)); // Test sharing. - assertSame(codes, factory.getAuthorityCodes(GeographicCRS.class)); // Test caching. + try { + Set<String> codes = factory.getAuthorityCodes(IdentifiedObject.class); + assertSame( codes, factory.getAuthorityCodes(IdentifiedObject.class)); // Test caching. + assertSame( codes, factory.getAuthorityCodes(SingleCRS.class)); // Test sharing. + assertSetEquals(List.of("102018", "ESRI::102021", "TEST::102021", "TEST:v2:102021", "E1", "E2"), codes); + assertSetEquals(List.of("102018", "ESRI::102021"), factory.getAuthorityCodes(ProjectedCRS.class)); + codes = factory.getAuthorityCodes(GeographicCRS.class); + assertSetEquals(List.of("TEST::102021", "TEST:v2:102021", "E1", "E2"), codes); + assertSame(codes, factory.getAuthorityCodes(GeodeticCRS.class)); // Test sharing. + assertSame(codes, factory.getAuthorityCodes(GeographicCRS.class)); // Test caching. + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); + } /* * Test descriptions before CRS creation. * Implementation fetches them from `StoredTree` instances. diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/AuthorityFactoriesTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/AuthorityFactoriesTest.java index 1592f40443..e10e95df20 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/AuthorityFactoriesTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/AuthorityFactoriesTest.java @@ -24,9 +24,10 @@ import org.opengis.referencing.IdentifiedObject; import org.opengis.referencing.crs.CRSAuthorityFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.GeographicCRS; -import org.apache.sis.util.ComparisonMode; import org.apache.sis.system.Loggers; +import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.privy.Constants; +import org.apache.sis.util.collection.BackingStoreException; import org.apache.sis.referencing.internal.EPSGFactoryProxy; import org.apache.sis.referencing.factory.CommonAuthorityFactory; import org.apache.sis.referencing.factory.IdentifiedObjectFinder; @@ -235,10 +236,14 @@ public final class AuthorityFactoriesTest extends TestCaseWithLogs { @Test public void testGetAuthorityCodes() throws FactoryException { final CRSAuthorityFactory factory = AuthorityFactories.ALL; - final Collection<String> codes = factory.getAuthorityCodes(CoordinateReferenceSystem.class); - assertFalse(codes.isEmpty()); - assertTrue(codes.contains("CRS:84")); - assertTrue(codes.contains("AUTO:42001") || codes.contains("AUTO2:42001")); + try { + final Collection<String> codes = factory.getAuthorityCodes(CoordinateReferenceSystem.class); + assertFalse(codes.isEmpty()); + assertTrue(codes.contains("CRS:84")); + assertTrue(codes.contains("AUTO:42001") || codes.contains("AUTO2:42001")); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); + } loggings.assertNoUnexpectedLog(); } diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/EPSGFactoryFallbackTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/EPSGFactoryFallbackTest.java index 30ef5d3382..69bac5ec7d 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/EPSGFactoryFallbackTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/EPSGFactoryFallbackTest.java @@ -39,6 +39,7 @@ import org.apache.sis.system.Configuration; import org.apache.sis.system.Loggers; import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.Utilities; +import org.apache.sis.util.collection.BackingStoreException; // Test dependencies import org.junit.jupiter.api.Test; @@ -265,6 +266,8 @@ public final class EPSGFactoryFallbackTest extends TestCaseWithLogs { final CoordinateReferenceSystem expected = EPSG.createCoordinateReferenceSystem(code); assertTrue(Utilities.deepEquals(expected, crs, ComparisonMode.DEBUG), code); } + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); } finally { setEPSGFactory(EPSG); } diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/AuthorityFactoryMock.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/AuthorityFactoryMock.java index f1762481ef..0720e17f41 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/AuthorityFactoryMock.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/AuthorityFactoryMock.java @@ -34,6 +34,7 @@ import org.opengis.referencing.datum.GeodeticDatum; import org.opengis.referencing.datum.PrimeMeridian; import org.opengis.referencing.datum.VerticalDatum; import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory; +import org.opengis.util.FactoryException; import org.opengis.util.InternationalString; import org.apache.sis.util.SimpleInternationalString; import org.apache.sis.metadata.simple.SimpleCitation; @@ -125,9 +126,10 @@ public final class AuthorityFactoryMock extends GeodeticAuthorityFactory impleme * Returns the geodetic object for the given code. * * @throws NoSuchAuthorityCodeException if the given code is unknown. + * @throws FactoryException if the creation failed for another reason. */ @Override - public IdentifiedObject createObject(final String code) throws NoSuchAuthorityCodeException { + public IdentifiedObject createObject(final String code) throws FactoryException { assertFalse(isClosed()); final int n; try { @@ -162,9 +164,10 @@ public final class AuthorityFactoryMock extends GeodeticAuthorityFactory impleme * * @return the unit of measurement. * @throws NoSuchAuthorityCodeException if the given code is unknown. + * @throws FactoryException if the creation failed for another reason. */ @Override - public Unit<?> createUnit(final String code) throws NoSuchAuthorityCodeException { + public Unit<?> createUnit(final String code) throws FactoryException { assertFalse(isClosed()); final int n; try { @@ -184,9 +187,10 @@ public final class AuthorityFactoryMock extends GeodeticAuthorityFactory impleme * * @return the spatial extent. * @throws NoSuchAuthorityCodeException if the given code is unknown. + * @throws FactoryException if the creation failed for another reason. */ @Override - public Extent createExtent(final String code) throws NoSuchAuthorityCodeException { + public Extent createExtent(final String code) throws FactoryException { assertFalse(isClosed()); final int n; try { 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 08182cb292..2a258c95f1 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 @@ -34,6 +34,7 @@ import org.opengis.referencing.crs.TemporalCRS; import org.opengis.referencing.cs.AxisDirection; import org.opengis.referencing.datum.Datum; import org.apache.sis.util.privy.Constants; +import org.apache.sis.util.collection.BackingStoreException; import org.apache.sis.referencing.IdentifiedObjects; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.operation.provider.TransverseMercator; @@ -81,7 +82,11 @@ public final class CommonAuthorityFactoryTest extends TestCase { */ @Test public void testGetAuthorityCodes() throws FactoryException { - assertTrue(factory.getAuthorityCodes(Datum.class).isEmpty()); + try { + assertTrue(factory.getAuthorityCodes(Datum.class).isEmpty()); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); + } assertSetEquals(List.of("CRS:1", "CRS:27", "CRS:83", "CRS:84", "CRS:88", "AUTO2:42001", "AUTO2:42002", "AUTO2:42003", "AUTO2:42004", "AUTO2:42005", "OGC:JulianDate", "OGC:TruncatedJulianDate", "OGC:UnixTime"), @@ -121,8 +126,12 @@ public final class CommonAuthorityFactoryTest extends TestCase { assertTrue(expected.add(IdentifiedObjects.toString(getSingleton(e.crs().getIdentifiers())))); } assertFalse(expected.isEmpty()); - for (final String code : factory.getAuthorityCodes(TemporalCRS.class)) { - assertTrue(expected.remove(code), code); + try { + for (final String code : factory.getAuthorityCodes(TemporalCRS.class)) { + assertTrue(expected.remove(code), code); + } + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); } for (final String remaining : expected) { assertFalse(remaining.startsWith(Constants.OGC), remaining); diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java index 6c4e5ec5ee..99865879a7 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java @@ -36,6 +36,7 @@ import org.opengis.util.FactoryException; import org.apache.sis.system.Loggers; import org.apache.sis.metadata.iso.extent.Extents; import org.apache.sis.measure.Units; +import org.apache.sis.util.collection.BackingStoreException; // Test dependencies import org.junit.jupiter.api.Test; @@ -80,18 +81,22 @@ public final class MultiAuthoritiesFactoryTest extends TestCaseWithLogs { CoordinateReferenceSystem.class, IdentifiedObject.class }; - for (final Class<?> type : types) { + for (final Class<?> type : types) try { for (final String code : factory.getAuthorityCodes(type.asSubclass(IdentifiedObject.class))) { assertInstanceOf(type, factory.createObject(code), code); } + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); } } /** * Tests {@link MultiAuthoritiesFactory#getCodeSpaces()}. + * + * @throws FactoryException if a problem occurred with the factory to test. */ @Test - public void testGetCodeSpaces() { + public void testGetCodeSpaces() throws FactoryException { final var mock1 = new AuthorityFactoryMock("MOCK1", "2.3"); final var mock2 = new AuthorityFactoryMock("MOCK2", null); final var mock3 = new AuthorityFactoryMock("MOCK3", null); @@ -106,9 +111,10 @@ public final class MultiAuthoritiesFactoryTest extends TestCaseWithLogs { * Tests {@link MultiAuthoritiesFactory#getAuthorityFactory(Class, String, String)}. * * @throws NoSuchAuthorityFactoryException if an authority is not recognized. + * @throws FactoryException if a problem occurred with the factory to test. */ @Test - public void testGetAuthorityFactory() throws NoSuchAuthorityFactoryException { + public void testGetAuthorityFactory() throws FactoryException { final var mock1 = new AuthorityFactoryMock("MOCK1", null); final var mock2 = new AuthorityFactoryMock("MOCK2", "1.2"); final var mock3 = new AuthorityFactoryMock("MOCK1", "2.3"); @@ -141,9 +147,10 @@ public final class MultiAuthoritiesFactoryTest extends TestCaseWithLogs { * with a conflict in the factory namespace. * * @throws NoSuchAuthorityFactoryException if an authority is not recognized. + * @throws FactoryException if a problem occurred with the factory to test. */ @Test - public void testConflict() throws NoSuchAuthorityFactoryException { + public void testConflict() throws FactoryException { final var mock1 = new AuthorityFactoryMock("MOCK1", "2.3"); final var mock2 = new AuthorityFactoryMock("MOCK1", "2.3"); final var mock3 = new AuthorityFactoryMock("MOCK3", "1.2"); @@ -331,15 +338,19 @@ public final class MultiAuthoritiesFactoryTest extends TestCaseWithLogs { new AuthorityFactoryMock("MOCK", null), new AuthorityFactoryMock("MOCK", "2.3")); final var factory = new MultiAuthoritiesFactory(mock, mock, mock, null); - final Set<String> codes = factory.getAuthorityCodes(CoordinateReferenceSystem.class); - - assertTrue(codes.contains("MOCK:4979")); // A geocentric CRS. - assertTrue(codes.contains(" mock :: 84")); // A geographic CRS. - assertTrue(codes.contains("http://www.opengis.net/gml/srs/mock.xml#4326")); - - assertFalse(codes.contains("MOCK:6326")); // A geodetic reference frame. - assertFalse(codes.isEmpty()); - assertArrayEquals(new String[] {"MOCK:4979", "MOCK:84", "MOCK:4326", "MOCK:5714", "MOCK:9905"}, codes.toArray()); + try { + final Set<String> codes = factory.getAuthorityCodes(CoordinateReferenceSystem.class); + + assertTrue(codes.contains("MOCK:4979")); // A geocentric CRS. + assertTrue(codes.contains(" mock :: 84")); // A geographic CRS. + assertTrue(codes.contains("http://www.opengis.net/gml/srs/mock.xml#4326")); + + assertFalse(codes.contains("MOCK:6326")); // A geodetic reference frame. + assertFalse(codes.isEmpty()); + assertArrayEquals(new String[] {"MOCK:4979", "MOCK:84", "MOCK:4326", "MOCK:5714", "MOCK:9905"}, codes.toArray()); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); + } loggings.assertNoUnexpectedLog(); } 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 ec037182a5..2eec4f4bc1 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 @@ -52,6 +52,7 @@ import org.apache.sis.referencing.datum.BursaWolfParameters; import org.apache.sis.referencing.datum.DefaultGeodeticDatum; import org.apache.sis.referencing.operation.AbstractCoordinateOperation; import org.apache.sis.referencing.factory.IdentifiedObjectFinder; +import org.apache.sis.util.collection.BackingStoreException; // Test dependencies import org.junit.jupiter.api.Tag; @@ -554,10 +555,13 @@ public final class EPSGFactoryTest extends TestCaseWithLogs { * Most basic objects. * Note: the numbers in 'size() >= x' checks were determined from the content of EPSG dataset version 7.9. */ - final Set<String> axes = factory.getAuthorityCodes(CoordinateSystemAxis.class); - assertFalse(axes.isEmpty(), "Axes not found."); - assertTrue (axes.contains("115"), "Shall contain Geocentric X."); - + try { + final Set<String> axes = factory.getAuthorityCodes(CoordinateSystemAxis.class); + assertFalse(axes.isEmpty(), "Axes not found."); + assertTrue (axes.contains("115"), "Shall contain Geocentric X."); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); + } final Set<String> coordinateSystems = factory.getAuthorityCodes(CoordinateSystem.class); assertFalse(coordinateSystems.isEmpty(), "Coordinate systems not found."); assertTrue (coordinateSystems.contains("6422"), "Shall contain ellipsoidal CS."); diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java index 5822892e0a..ba0168b6bc 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java @@ -35,6 +35,7 @@ import org.apache.sis.system.Loggers; import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.Utilities; import org.apache.sis.util.privy.Constants; +import org.apache.sis.util.collection.BackingStoreException; import org.apache.sis.metadata.sql.privy.Reflection; // Test dependencies @@ -229,6 +230,8 @@ public final class EPSGInstallerTest extends TestCaseWithLogs { codes = new HashSet<>(codes); assertTrue (codes.contains("4979")); assertFalse(codes.contains("4329")); + } catch (BackingStoreException e) { + throw e.unwrapOrRethrow(FactoryException.class); } assertEquals(1, countCRSTables(ds), "Should contain EPSG tables after we created them."); } diff --git a/geoapi/snapshot b/geoapi/snapshot index 8b993c74d8..c830770c8c 160000 --- a/geoapi/snapshot +++ b/geoapi/snapshot @@ -1 +1 @@ -Subproject commit 8b993c74d8f49b215f6b4aa2747e0f362d97d3e3 +Subproject commit c830770c8c13ea9219a9eefd98cf08e18a01c33c