You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2022/01/26 17:45:46 UTC

[sis] 03/03: Fix a `MetadataVisitorException` when coyping the `Metadata.getLocaleAndCharsets()` property. It was caused by ClassCastException: Map.Entry.

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 bf22b758e100296e177b4a72b346a5b69cda0056
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Wed Jan 26 18:36:00 2022 +0100

    Fix a `MetadataVisitorException` when coyping the `Metadata.getLocaleAndCharsets()` property.
    It was caused by ClassCastException: Map.Entry.
---
 .../org/apache/sis/metadata/MetadataCopier.java    | 19 ++++++++-------
 .../java/org/apache/sis/metadata/package-info.java |  2 +-
 .../apache/sis/metadata/MetadataCopierTest.java    | 27 +++++++++++++++++++++-
 3 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java
index 7f3134d..cd54882 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java
@@ -20,7 +20,6 @@ import java.util.Set;
 import java.util.EnumSet;
 import java.util.LinkedHashSet;
 import java.util.Map;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Arrays;
 import java.util.Collection;
@@ -60,7 +59,7 @@ import org.apache.sis.internal.metadata.Resources;
  * In multi-threads environment, each thread should use its own {@code MetadataCopier} instance.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.2
  * @since   0.8
  * @module
 */
@@ -240,7 +239,7 @@ public class MetadataCopier extends MetadataVisitor<Object> {
                 if (c instanceof EnumSet<?> || c instanceof CodeListSet<?>) {
                     /*
                      * Enum and CodeList elements can not be cloned. Do not clone their collection neither;
-                     * we presume that the setter method will do that itself.
+                     * we presume that the setter method (to be invoked by reflection) will do that itself.
                      */
                 } else {
                     final Object[] array = c.toArray();
@@ -254,12 +253,16 @@ public class MetadataCopier extends MetadataVisitor<Object> {
                 }
                 return c;
             }
+            /*
+             * Maps are rare in GeoAPI interfaces derived from ISO 19115. The main one
+             * is `Map<Locale,Charset>` returned by `Metadata.getLocalesAndCharsets()`.
+             * We can not copy those entries because the `type` argument is `Map.Entry`,
+             * which is not enough information. Recursive copy should not be necessary
+             * anyway because we do not use `Map` for storing other metadata objects.
+             * We do not clone the map because it should be done by the setter method.
+             */
             if (metadata instanceof Map<?,?>) {
-                final Map<Object,Object> copy = new LinkedHashMap<>((Map<?,?>) metadata);
-                for (final Map.Entry<Object,Object> entry : copy.entrySet()) {
-                    entry.setValue(copyRecursively(type, entry.getValue()));
-                }
-                return copy;
+                return metadata;
             }
         }
         return copyRecursively(type, metadata);
diff --git a/core/sis-metadata/src/main/java/org/apache/sis/metadata/package-info.java b/core/sis-metadata/src/main/java/org/apache/sis/metadata/package-info.java
index ca31242..036790a 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/metadata/package-info.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/metadata/package-info.java
@@ -119,7 +119,7 @@
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Adrian Custer (Geomatys)
- * @version 1.0
+ * @version 1.2
  * @since   0.3
  * @module
  */
diff --git a/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java b/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java
index 5c2634c..e2e25d7 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java
@@ -16,8 +16,14 @@
  */
 package org.apache.sis.metadata;
 
+import java.util.Map;
+import java.util.Locale;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import org.opengis.metadata.Metadata;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.extent.GeographicExtent;
+import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.metadata.iso.citation.DefaultCitation;
 import org.apache.sis.metadata.iso.citation.HardCodedCitations;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicDescription;
@@ -34,7 +40,7 @@ import static org.apache.sis.test.TestUtilities.getSingleton;
  * Unless otherwise specified, all tests use the {@link MetadataStandard#ISO_19115} constant.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.2
  *
  * @see org.apache.sis.internal.metadata.MergerTest
  *
@@ -99,4 +105,23 @@ public final strictfp class MetadataCopierTest extends TestCase {
             assertTrue(message, message.contains("DefaultCitation"));
         }
     }
+
+    /**
+     * Tests with a metadata containing a {@link DefaultMetadata#getLocalesAndCharsets()} property.
+     * This property is defined by a {@link Map}.
+     */
+    @Test
+    public void testLocaleAndCharsets() {
+        final MetadataCopier copier = new MetadataCopier(MetadataStandard.ISO_19115);
+        final DefaultMetadata original = new DefaultMetadata();
+        original.getLocalesAndCharsets().put(Locale.FRENCH,   StandardCharsets.UTF_8);
+        original.getLocalesAndCharsets().put(Locale.JAPANESE, StandardCharsets.UTF_16);
+        final Metadata copy = copier.copy(Metadata.class, original);
+        final Map<Locale,Charset> lc = copy.getLocalesAndCharsets();
+        assertEquals(StandardCharsets.UTF_8,  lc.get(Locale.FRENCH));
+        assertEquals(StandardCharsets.UTF_16, lc.get(Locale.JAPANESE));
+        assertEquals (original, copy);
+        assertNotSame(original, copy);
+        assertNotSame(original.getLocalesAndCharsets(), lc);
+    }
 }