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 a62860a7a5aa17688d67b14af1ccdd01be14c53f
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Wed Feb 21 15:15:50 2024 +0100

    Make the code more robust to absence of EPSG database.
---
 .../apache/sis/referencing/IdentifiedObjects.java  |  7 +++--
 .../operation/CoordinateOperationRegistry.java     | 32 ++++++++++++----------
 .../sis/storage/geotiff/writer/GeoEncoder.java     | 17 +++++++++++-
 3 files changed, 38 insertions(+), 18 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/IdentifiedObjects.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/IdentifiedObjects.java
index 9586af09ce..3ab9c02293 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/IdentifiedObjects.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/IdentifiedObjects.java
@@ -50,6 +50,7 @@ import org.apache.sis.metadata.internal.NameToIdentifier;
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
 import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
+import org.apache.sis.referencing.factory.UnavailableFactoryException;
 import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
@@ -443,7 +444,8 @@ public final class IdentifiedObjects extends Static {
      * @param  authority  the authority for the identifier to return, or 
{@code null} for
      *         the first identifier regardless its authority.
      * @return the identifier, or {@code null} if none was found without 
ambiguity or if the given object was null.
-     * @throws FactoryException if an error occurred during the search.
+     * @throws UnavailableFactoryException if the factory for the authority 
identified in the URN is not available.
+     * @throws FactoryException if the lookup failed for another reason.
      *
      * @see #newFinder(String)
      * @see #toURN(Class, Identifier)
@@ -561,7 +563,8 @@ public final class IdentifiedObjects extends Static {
      * @param  object  the object (usually a {@linkplain 
org.apache.sis.referencing.crs.AbstractCRS
      *         coordinate reference system}) whose EPSG code is to be found, 
or {@code null}.
      * @return the EPSG code, or {@code null} if none was found without 
ambiguity or if the given object was null.
-     * @throws FactoryException if an error occurred during the search.
+     * @throws UnavailableFactoryException if the EPSG factory is not 
available.
+     * @throws FactoryException if the lookup failed for another reason.
      *
      * @see #newFinder(String)
      *
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
index 0c47339489..2ca694b97a 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
@@ -57,6 +57,7 @@ import 
org.apache.sis.referencing.operation.transform.MathTransforms;
 import 
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
 import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
 import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
+import org.apache.sis.referencing.factory.UnavailableFactoryException;
 import org.apache.sis.referencing.factory.MissingFactoryResourceException;
 import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
 import org.apache.sis.referencing.factory.NoSuchAuthorityFactoryException;
@@ -169,7 +170,7 @@ class CoordinateOperationRegistry {
      * @see #authorityCodes
      * @see #findCode(CoordinateReferenceSystem)
      */
-    private final IdentifiedObjectFinder codeFinder;
+    private IdentifiedObjectFinder codeFinder;
 
     /**
      * The factory to use for creating operations as defined by authority, or 
{@code null} if none.
@@ -265,9 +266,6 @@ class CoordinateOperationRegistry {
 
         @SuppressWarnings("LocalVariableHidesMemberVariable")
         Map<CoordinateReferenceSystem, List<String>> authorityCodes = 
Collections.emptyMap();
-
-        @SuppressWarnings("LocalVariableHidesMemberVariable")
-        IdentifiedObjectFinder codeFinder = null;
         if (registry != null) {
             if (registry instanceof GeodeticAuthorityFactory) {
                 codeFinder = ((GeodeticAuthorityFactory) 
registry).newIdentifiedObjectFinder();
@@ -280,7 +278,6 @@ class CoordinateOperationRegistry {
                 authorityCodes = new IdentityHashMap<>(5);          // Rarely 
more than 4 entries.
             }
         }
-        this.codeFinder     = codeFinder;
         this.authorityCodes = authorityCodes;
         if (context != null) {
             areaOfInterest  = context.getAreaOfInterest();
@@ -308,7 +305,7 @@ class CoordinateOperationRegistry {
 
     /**
      * Finds the authority codes for the given coordinate reference system.
-     * This method does not trust the code given by the user in its CRS - we 
verify it.
+     * This method does not trust the code given by the user in the CRS - it 
verifies it.
      * This method may return codes even if the axis order does not match;
      * it will be caller's responsibility to make necessary adjustments.
      *
@@ -329,17 +326,22 @@ class CoordinateOperationRegistry {
                     : IdentifiedObjectFinder.Domain.VALID_DATASET);
             int matchCount = 0;
             final Citation authority = registry.getAuthority();
-            for (final IdentifiedObject candidate : codeFinder.find(crs)) {
-                final Identifier identifier = 
IdentifiedObjects.getIdentifier(candidate, authority);
-                if (identifier != null) {
-                    final String code = identifier.getCode();
-                    if (Utilities.deepEquals(candidate, crs, 
ComparisonMode.APPROXIMATE)) {
-                        // If axis order matches, give precedence to that CRS.
-                        codes.add(matchCount++, code);
-                    } else {
-                        codes.add(code);
+            try {
+                for (final IdentifiedObject candidate : codeFinder.find(crs)) {
+                    final Identifier identifier = 
IdentifiedObjects.getIdentifier(candidate, authority);
+                    if (identifier != null) {
+                        final String code = identifier.getCode();
+                        if (Utilities.deepEquals(candidate, crs, 
ComparisonMode.APPROXIMATE)) {
+                            // If axis order matches, give precedence to that 
CRS.
+                            codes.add(matchCount++, code);
+                        } else {
+                            codes.add(code);
+                        }
                     }
                 }
+            } catch (UnavailableFactoryException e) {
+                log(null, e);
+                codeFinder = null;
             }
             authorityCodes.put(crs, codes);
         }
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/GeoEncoder.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/GeoEncoder.java
index 0124b98495..25c445efbc 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/GeoEncoder.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/writer/GeoEncoder.java
@@ -18,6 +18,7 @@ package org.apache.sis.storage.geotiff.writer;
 
 import java.util.List;
 import java.util.EnumMap;
+import java.util.logging.Level;
 import static javax.imageio.plugins.tiff.GeoTIFFTagSet.TAG_GEO_ASCII_PARAMS;
 import static javax.imageio.plugins.tiff.GeoTIFFTagSet.TAG_GEO_DOUBLE_PARAMS;
 import javax.measure.Unit;
@@ -56,6 +57,7 @@ import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.cs.CoordinateSystems;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.referencing.factory.UnavailableFactoryException;
 import org.apache.sis.referencing.util.ReferencingUtilities;
 import org.apache.sis.referencing.util.WKTKeywords;
 import org.apache.sis.coverage.grid.GridGeometry;
@@ -184,6 +186,13 @@ public final class GeoEncoder {
      */
     private int citationLengthIndex;
 
+    /**
+     * Whether to disable attempts to write EPSG codes. This is set to {@code 
true} on the first attempt to use the
+     * EPSG database if it appears to be unavailable. This is used for 
avoiding many retries which will continue to
+     * fail.
+     */
+    private boolean disableEPSG;
+
     /**
      * Prepares information for writing GeoTIFF tags for the given grid 
geometry.
      * Caller shall invoke {@link #write(GridGeometry, MetadataFetcher)} 
exactly once after construction.
@@ -558,7 +567,13 @@ public final class GeoEncoder {
          * This is not necessarily a bad thing, because there is a possibility 
that future GeoTIFF
          * specifications become stricter, so we are already "strict" 
regarding usages of EPSG codes.
          */
-        final short epsg = toShortEPSG(IdentifiedObjects.lookupEPSG(object));
+        short epsg = GeoCodes.userDefined;
+        if (!disableEPSG) try {
+            epsg = toShortEPSG(IdentifiedObjects.lookupEPSG(object));
+        } catch (UnavailableFactoryException e) {
+            listeners.warning(Level.FINE, null, e);
+            disableEPSG = true;
+        }
         writeShort(key, epsg);
         return (epsg == GeoCodes.userDefined);
     }

Reply via email to