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 b9ad7e86ef7f862e6655ea723335cc96247c0461
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Wed Aug 2 12:03:35 2023 +0200

    Add a `GeometryType.getTypeName(Geometries)` method.
    The Java class associated to the `TypeName` depends on the geometry library.
---
 .../apache/sis/internal/feature/GeometryType.java  | 85 ++++++++++++++++++++--
 .../sis/internal/feature/GeometryTypeTest.java     | 28 ++++++-
 .../org/apache/sis/util/iso/DefaultTypeName.java   |  5 ++
 .../java/org/apache/sis/util/iso/TypeNames.java    |  6 +-
 .../org/apache/sis/util/iso/TypeNamesTest.java     | 17 +++--
 5 files changed, 126 insertions(+), 15 deletions(-)

diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/GeometryType.java
 
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/GeometryType.java
index 0476da682e..69db5d343e 100644
--- 
a/core/sis-feature/src/main/java/org/apache/sis/internal/feature/GeometryType.java
+++ 
b/core/sis-feature/src/main/java/org/apache/sis/internal/feature/GeometryType.java
@@ -17,6 +17,13 @@
 package org.apache.sis.internal.feature;
 
 import java.util.Locale;
+import java.util.EnumMap;
+import org.opengis.util.TypeName;
+import org.opengis.util.NameSpace;
+import org.apache.sis.util.iso.Names;
+import org.apache.sis.setup.GeometryLibrary;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.util.iso.DefaultNameFactory;
 
 
 /**
@@ -36,7 +43,7 @@ public enum GeometryType {
      *
      * @see Geometries#rootClass
      */
-    GEOMETRY,
+    GEOMETRY("Geometry"),
 
     /**
      * Zero-dimensional geometry containing a single point.
@@ -45,7 +52,7 @@ public enum GeometryType {
      *
      * @see Geometries#pointClass
      */
-    POINT,
+    POINT("Point"),
 
     /**
      * Sequence of points connected by straight, non-self intersecting line 
pieces.
@@ -53,7 +60,7 @@ public enum GeometryType {
      *
      * @see Geometries#polylineClass
      */
-    LINESTRING,
+    LINESTRING("LineString"),
 
     /**
      * Geometry with a positive area (two-dimensional).
@@ -61,27 +68,89 @@ public enum GeometryType {
      *
      * @see Geometries#polygonClass
      */
-    POLYGON,
+    POLYGON("Polygon"),
 
     /**
      * Set of points.
      */
-    MULTIPOINT,
+    MULTIPOINT("MultiPoint"),
 
     /**
      * Set of linestrings.
      */
-    MULTILINESTRING,
+    MULTILINESTRING("MultiLineString"),
 
     /**
      * Set of polygons.
      */
-    MULTIPOLYGON,
+    MULTIPOLYGON("MultiPolygon"),
 
     /**
      * Set of geometries of any type except other geometry collection.
      */
-    GEOMETRYCOLLECTION;
+    GEOMETRYCOLLECTION("GeometryCollection");
+
+    /**
+     * Camel-case name of this geometry type.
+     * The upper-case variant of this name is equal to {@link #name()}.
+     */
+    public final String name;
+
+    /**
+     * The geometry types as ISO 19103 type names, created when first needed.
+     * For a given enumeration value, all {@code typeNames} values are 
identical
+     * except for the associated Java class, which depends on the geometry 
library.
+     *
+     * @see #getTypeName(Geometries)
+     */
+    private final EnumMap<GeometryLibrary, TypeName> typeNames;
+
+    /**
+     * The "OGC" namespace for geometry names. Fetched when first needed.
+     */
+    private static volatile NameSpace namespace;
+
+    /**
+     * Creates a new enumeration value.
+     *
+     * @param  name  camel-case name of the geometry.
+     */
+    private GeometryType(final String name) {
+        this.name = name;
+        typeNames = new EnumMap<>(GeometryLibrary.class);
+    }
+
+    /**
+     * {@return the name of this geometry type as an ISO 19103 object}.
+     * The namespace is "OGC". The Java type depends on the geometry library.
+     *
+     * @param  library  the geometry library that determine geometry classes.
+     */
+    public final TypeName getTypeName(final Geometries<?> library) {
+        TypeName value;
+        synchronized (typeNames) {
+            value = typeNames.get(library.library);
+        }
+        if (value == null) {
+            NameSpace scope = namespace;
+            if (scope == null) {
+                /*
+                 * The `Names.createTypeName(…)` method creates a `TypeName` 
associated to the
+                 * `org.opengis.geometry.Geometry` type, which is not 
necessarily what we want.
+                 * So we keep only the namespace.
+                 */
+                namespace = scope = Names.createTypeName(Constants.OGC, null, 
"Geometry").scope();
+            }
+            value = DefaultNameFactory.provider().createTypeName(scope, name, 
library.getGeometryClass(this));
+            synchronized (typeNames) {
+                final TypeName existing = typeNames.put(library.library, 
value);
+                if (existing != null) {
+                    typeNames.put(library.library, value = existing);
+                }
+            }
+        }
+        return value;
+    }
 
     /**
      * The type of this geometry as specified in Well-Known Binary (WKB) 
specification.
diff --git 
a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometryTypeTest.java
 
b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometryTypeTest.java
index bb339e60f3..3ca324c7ce 100644
--- 
a/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometryTypeTest.java
+++ 
b/core/sis-feature/src/test/java/org/apache/sis/internal/feature/GeometryTypeTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.internal.feature;
 
+import java.util.Locale;
+import org.opengis.util.TypeName;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -26,7 +28,7 @@ import static org.junit.Assert.*;
  * Tests {@link GeometryType}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.4
  * @since   1.1
  */
 public final class GeometryTypeTest extends TestCase {
@@ -36,6 +38,30 @@ public final class GeometryTypeTest extends TestCase {
     public GeometryTypeTest() {
     }
 
+    /**
+     * Verifies {@link GeometryType#name} values.
+     */
+    @Test
+    public void verifyCamelCaseName() {
+        for (final GeometryType type : GeometryType.values()) {
+            assertEquals(type.name(), type.name.toUpperCase(Locale.US));
+        }
+    }
+
+    /**
+     * Tests {@link GeometryType#getTypeName(Geometries)}.
+     */
+    @Test
+    public void testTypeName() {
+        TypeName name = 
GeometryType.LINESTRING.getTypeName(org.apache.sis.internal.feature.jts.Factory.INSTANCE);
+        assertEquals("OGC:LineString", name.toFullyQualifiedName().toString());
+        assertEquals(org.locationtech.jts.geom.LineString.class, 
name.toJavaType().get());
+
+        name = 
GeometryType.LINESTRING.getTypeName(org.apache.sis.internal.feature.esri.Factory.INSTANCE);
+        assertEquals("OGC:LineString", name.toFullyQualifiedName().toString());
+        assertEquals(com.esri.core.geometry.Polyline.class, 
name.toJavaType().get());
+    }
+
     /**
      * Tests {@link GeometryType#forBinaryType(int)} and verifies {@link 
GeometryType#binaryType()} values.
      */
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java 
b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
index adc6beb0d6..f906117c2d 100644
--- 
a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
+++ 
b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
@@ -108,6 +108,11 @@ import org.apache.sis.util.UnknownNameException;
  *     <td class="sep"></td>
  *     <td></td>
  *   </tr><tr>
+ *     <td>{@link org.opengis.geometry.Geometry}</td>
+ *     <td>{@code OGC:Geometry}</td>
+ *     <td class="sep"></td>
+ *     <td></td>
+ *   </tr><tr>
  *     <td>Unknown Java class</td>
  *     <td>{@code class:}&lt;the class name&gt;</td>
  *     <td class="sep"></td>
diff --git 
a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/TypeNames.java 
b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/TypeNames.java
index 46253fa9a2..308c555238 100644
--- a/core/sis-metadata/src/main/java/org/apache/sis/util/iso/TypeNames.java
+++ b/core/sis-metadata/src/main/java/org/apache/sis/util/iso/TypeNames.java
@@ -28,6 +28,7 @@ import org.opengis.util.TypeName;
 import org.opengis.util.NameSpace;
 import org.opengis.util.NameFactory;
 import org.opengis.util.InternationalString;
+import org.opengis.geometry.Geometry;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.Numbers;
@@ -37,7 +38,7 @@ import org.apache.sis.util.Numbers;
  * Implements the mapping between {@link Class} and {@link TypeName} 
documented in {@link DefaultTypeName}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.3
+ * @version 1.4
  * @since   0.5
  */
 final class TypeNames {
@@ -57,9 +58,12 @@ final class TypeNames {
         m.put("URI",       URI.class);
         m.put("DateTime",  Date.class);
         m.put("PT_Locale", Locale.class);
+        m.put("Geometry",  Geometry.class);             // Was GM_Object in 
ISO 19107:2003.
         m.put("Decimal",   BigDecimal.class);
         m.put("Boolean",   Boolean.class);              // Used as a sentinel 
value for stopping iteration.
 
+        // MD_Metadata is not specified because it is handled through UML 
annotations.
+
         // Entries below this point are handled in a special way.
         m.put("FreeText",        InternationalString.class);
         m.put("CharacterString", String.class);
diff --git 
a/core/sis-metadata/src/test/java/org/apache/sis/util/iso/TypeNamesTest.java 
b/core/sis-metadata/src/test/java/org/apache/sis/util/iso/TypeNamesTest.java
index 7d95bb94cc..7686934a3d 100644
--- a/core/sis-metadata/src/test/java/org/apache/sis/util/iso/TypeNamesTest.java
+++ b/core/sis-metadata/src/test/java/org/apache/sis/util/iso/TypeNamesTest.java
@@ -23,6 +23,7 @@ import org.opengis.util.TypeName;
 import org.opengis.util.NameFactory;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.Metadata;
+import org.opengis.geometry.Geometry;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
@@ -52,8 +53,10 @@ public final class TypeNamesTest extends TestCase {
     }
 
     /**
-     * Verifies that the call to {@link TypeNames#toTypeName(NameFactory, 
Class)} returns a {@code TypeName} having the
-     * given name and namespace, then tests the reverse operation with {@link 
TypeNames#toClass(String, String)}.
+     * Tests fetching a name from a Java class and a fetching a Java class 
from a name.
+     * This method verifies that the call to {@link 
TypeNames#toTypeName(NameFactory, Class)}
+     * returns a {@code TypeName} having the given name and namespace,
+     * then tests the reverse operation with {@link TypeNames#toClass(String, 
String)}.
      */
     private static void verifyLookup(final String namespace, final String 
name, final Class<?> valueClass)
             throws ClassNotFoundException
@@ -77,7 +80,8 @@ public final class TypeNamesTest extends TestCase {
     /**
      * Tests the mapping of basic types like strings, URI, dates and numbers.
      *
-     * @throws ClassNotFoundException should not happen since we do invoke 
{@link Class#forName(String)} in this test.
+     * @throws ClassNotFoundException should not happen since we do not
+     *         invoke {@link Class#forName(String)} in this test.
      */
     @Test
     public void testBasicTypes() throws ClassNotFoundException {
@@ -106,10 +110,12 @@ public final class TypeNamesTest extends TestCase {
     /**
      * Tests the mapping of more complex object that are not basic types.
      *
-     * @throws ClassNotFoundException should not happen since we do invoke 
{@link Class#forName(String)} in this test.
+     * @throws ClassNotFoundException should not happen since we do not
+     *         invoke {@link Class#forName(String)} in this test.
      */
     @Test
     public void testMetadataClasses() throws ClassNotFoundException {
+        verifyLookup(OGC, "Geometry",    Geometry.class);
         verifyLookup(OGC, "MD_Metadata", Metadata.class);
         verifyLookup(OGC, "SC_CRS",      CoordinateReferenceSystem.class);
     }
@@ -127,7 +133,8 @@ public final class TypeNamesTest extends TestCase {
     /**
      * Checks for the sentinel values in case of invalid names.
      *
-     * @throws ClassNotFoundException should not happen since we do invoke 
{@link Class#forName(String)} in this test.
+     * @throws ClassNotFoundException should not happen since we do not
+     *         invoke {@link Class#forName(String)} in this test.
      */
     @Test
     public void testInvalidNames() throws ClassNotFoundException {

Reply via email to