sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/02: Parameterize `Numbers.primitiveToWrapper(Class<N>)` method. It avoids "unsafe cast" warning in `FeatureTypebuilder.addAttribute(…)`.
Date Wed, 23 Sep 2020 17:23:48 GMT
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 20b218b77983d986927000e9b006a4ecf71df300
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Wed Sep 23 19:20:31 2020 +0200

    Parameterize `Numbers.primitiveToWrapper(Class<N>)` method.
    It avoids "unsafe cast" warning in `FeatureTypebuilder.addAttribute(…)`.
---
 .../sis/feature/builder/FeatureTypeBuilder.java    | 12 ++--
 .../apache/sis/feature/builder/package-info.java   |  3 +-
 .../feature/builder/AttributeTypeBuilderTest.java  | 29 +++++----
 .../src/main/java/org/apache/sis/util/Numbers.java | 12 ++--
 .../test/java/org/apache/sis/util/NumbersTest.java | 68 ++++++++++++++--------
 5 files changed, 76 insertions(+), 48 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
b/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
index ebdd3d3..fc4cefa 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/builder/FeatureTypeBuilder.java
@@ -25,7 +25,6 @@ import java.util.Map;
 import java.util.Locale;
 import java.util.Set;
 import java.util.Objects;
-import org.apache.sis.util.Numbers;
 import org.opengis.util.NameSpace;
 import org.opengis.util.GenericName;
 import org.opengis.util.NameFactory;
@@ -42,6 +41,7 @@ import org.apache.sis.internal.feature.Resources;
 import org.apache.sis.util.CorruptedObjectException;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArraysExt;
+import org.apache.sis.util.Numbers;
 
 // Branch-dependent imports
 import org.opengis.feature.AttributeType;
@@ -102,7 +102,8 @@ import org.opengis.feature.Operation;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @author  Alexis Manin (Geomatys)
+ * @version 1.1
  *
  * @see org.apache.sis.parameter.ParameterBuilder
  *
@@ -677,16 +678,13 @@ public class FeatureTypeBuilder extends TypeBuilder {
      *
      * @see #properties()
      */
-    public <V> AttributeTypeBuilder<V> addAttribute(Class<V> valueClass)
{
+    public <V> AttributeTypeBuilder<V> addAttribute(final Class<V> valueClass)
{
         ensureNonNull("valueClass", valueClass);
         if (Feature.class.isAssignableFrom(valueClass)) {
             // We disallow Feature.class because that type shall be handled as association
instead than attribute.
             throw new IllegalArgumentException(errors().getString(Errors.Keys.IllegalArgumentValue_2,
"valueClass", valueClass));
         }
-
-        valueClass = (Class<V>) Numbers.primitiveToWrapper(valueClass);
-
-        final AttributeTypeBuilder<V> property = new AttributeTypeBuilder<>(this,
valueClass);
+        final AttributeTypeBuilder<V> property = new AttributeTypeBuilder<>(this,
Numbers.primitiveToWrapper(valueClass));
         properties.add(property);
         clearCache();
         return property;
diff --git a/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java
b/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java
index 6f5c1f5..d3e46b7 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/feature/builder/package-info.java
@@ -54,7 +54,8 @@
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @author  Alexis Manin (Geomatys)
+ * @version 1.1
  *
  * @see org.apache.sis.feature.DefaultFeatureType
  *
diff --git a/core/sis-feature/src/test/java/org/apache/sis/feature/builder/AttributeTypeBuilderTest.java
b/core/sis-feature/src/test/java/org/apache/sis/feature/builder/AttributeTypeBuilderTest.java
index 1ae4a64..bb2b599 100644
--- a/core/sis-feature/src/test/java/org/apache/sis/feature/builder/AttributeTypeBuilderTest.java
+++ b/core/sis-feature/src/test/java/org/apache/sis/feature/builder/AttributeTypeBuilderTest.java
@@ -20,12 +20,8 @@ import java.util.Arrays;
 import java.util.Set;
 import java.util.Collections;
 import com.esri.core.geometry.Geometry;
-import org.opengis.feature.Attribute;
-import org.opengis.feature.Feature;
-import org.opengis.feature.FeatureType;
-import org.opengis.feature.Property;
-import org.opengis.feature.PropertyType;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.feature.Features;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.internal.feature.AttributeConvention;
 import org.apache.sis.test.DependsOnMethod;
@@ -36,7 +32,12 @@ import org.junit.Test;
 import static org.apache.sis.test.Assert.*;
 
 // Branch-dependent imports
+import org.opengis.feature.Attribute;
 import org.opengis.feature.AttributeType;
+import org.opengis.feature.Feature;
+import org.opengis.feature.FeatureType;
+import org.opengis.feature.Property;
+import org.opengis.feature.PropertyType;
 
 
 /**
@@ -45,7 +46,8 @@ import org.opengis.feature.AttributeType;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @author  Alexis Manin (Geomatys)
+ * @version 1.1
  * @since   0.8
  * @module
  */
@@ -246,7 +248,11 @@ public final strictfp class AttributeTypeBuilderTest extends TestCase
{
         assertFalse("remove(IDENTIFIER_COMPONENT)", roles.remove(AttributeRole.IDENTIFIER_COMPONENT));
     }
 
+    /**
+     * Verifies that {@link FeatureTypeBuilder#addAttribute(Class)} converts primitive types
to their wrapper.
+     */
     @Test
+    @SuppressWarnings("UnnecessaryBoxing")
     public void testBoxing() {
         final FeatureTypeBuilder ftb = new FeatureTypeBuilder().setName("boxing");
         final AttributeTypeBuilder<Integer> boxBuilder = ftb.addAttribute(int.class).setName("boxed");
@@ -254,16 +260,17 @@ public final strictfp class AttributeTypeBuilderTest extends TestCase
{
 
         final FeatureType ft = ftb.build();
         final PropertyType boxedProperty = ft.getProperty("boxed");
-        assertTrue(boxedProperty instanceof AttributeType);
-        assertEquals("Attribute value type should have been boxed", Integer.class, ((AttributeType)boxedProperty).getValueClass());
+        assertInstanceOf("Unexpected property type.", AttributeType.class, boxedProperty);
+        assertEquals("Attribute value type should have been boxed", Integer.class, ((AttributeType<?>)
boxedProperty).getValueClass());
         final Feature feature = ft.newInstance();
 
         final Property p = feature.getProperty("boxed");
-        assertTrue(p instanceof Attribute);
+        assertInstanceOf("Unexpected property type.", Attribute.class, p);
         assertEquals("Attribute value type should have been boxed", Integer.class, ((Attribute<?>)
p).getType().getValueClass());
+
         int value = 3;
-        ((Attribute<Integer>) p).setValue(value);
-        assertEquals(3, p.getValue());
+        Features.cast((Attribute<?>) p, Integer.class).setValue(value);
+        assertEquals(value, p.getValue());
 
         feature.setPropertyValue("boxed", Integer.valueOf(4));
         assertEquals(4, feature.getPropertyValue("boxed"));
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java b/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
index c922291..bab3a28 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
@@ -241,28 +241,32 @@ public final class Numbers extends Static {
      * Changes a primitive class to its wrapper (for example {@code int} to {@link Integer}).
      * If the specified class is not a primitive type, then it is returned unchanged.
      *
+     * @param  <N>   the primitive and wrapper type (both have the same parametric
declaration).
      * @param  type  the primitive type (can be {@code null}).
      * @return the type as a wrapper.
      *
      * @see #wrapperToPrimitive(Class)
      */
-    public static Class<?> primitiveToWrapper(final Class<?> type) {
+    @SuppressWarnings("unchecked")
+    public static <N> Class<N> primitiveToWrapper(final Class<N> type)
{
         final Numbers mapping = MAPPING.get(type);
-        return (mapping != null) ? mapping.wrapper : type;
+        return (mapping != null) ? (Class<N>) mapping.wrapper : type;
     }
 
     /**
      * Changes a wrapper class to its primitive (for example {@link Integer} to {@code int}).
      * If the specified class is not a wrapper type, then it is returned unchanged.
      *
+     * @param  <N>   the primitive and wrapper type (both have the same parametric
declaration).
      * @param  type  the wrapper type (can be {@code null}).
      * @return the type as a primitive.
      *
      * @see #primitiveToWrapper(Class)
      */
-    public static Class<?> wrapperToPrimitive(final Class<?> type) {
+    @SuppressWarnings("unchecked")
+    public static <N> Class<N> wrapperToPrimitive(final Class<N> type)
{
         final Numbers mapping = MAPPING.get(type);
-        return (mapping != null) ? mapping.primitive : type;
+        return (mapping != null) ? (Class<N>) mapping.primitive : type;
     }
 
     /**
diff --git a/core/sis-utility/src/test/java/org/apache/sis/util/NumbersTest.java b/core/sis-utility/src/test/java/org/apache/sis/util/NumbersTest.java
index fcc73e9..6bba3aa 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/util/NumbersTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/util/NumbersTest.java
@@ -30,7 +30,7 @@ import static org.apache.sis.util.Numbers.*;
  * Tests the {@link Numbers} static methods.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.1
  * @since   0.3
  * @module
  */
@@ -101,18 +101,27 @@ public final strictfp class NumbersTest extends TestCase {
      */
     @Test
     public void testPrimitiveToWrapper() {
-        assertEquals(Byte   .class, primitiveToWrapper(Byte   .TYPE));
-        assertEquals(Short  .class, primitiveToWrapper(Short  .TYPE));
-        assertEquals(Integer.class, primitiveToWrapper(Integer.TYPE));
-        assertEquals(Long   .class, primitiveToWrapper(Long   .TYPE));
-        assertEquals(Float  .class, primitiveToWrapper(Float  .TYPE));
-        assertEquals(Double .class, primitiveToWrapper(Double .TYPE));
-        assertEquals(Byte   .class, primitiveToWrapper(Byte   .class));
-        assertEquals(Short  .class, primitiveToWrapper(Short  .class));
-        assertEquals(Integer.class, primitiveToWrapper(Integer.class));
-        assertEquals(Long   .class, primitiveToWrapper(Long   .class));
-        assertEquals(Float  .class, primitiveToWrapper(Float  .class));
-        assertEquals(Double .class, primitiveToWrapper(Double .class));
+        verifyPrimitiveToWrapper(Byte     .class,  Byte     .TYPE);
+        verifyPrimitiveToWrapper(Short    .class,  Short    .TYPE);
+        verifyPrimitiveToWrapper(Integer  .class,  Integer  .TYPE);
+        verifyPrimitiveToWrapper(Long     .class,  Long     .TYPE);
+        verifyPrimitiveToWrapper(Float    .class,  Float    .TYPE);
+        verifyPrimitiveToWrapper(Double   .class,  Double   .TYPE);
+        verifyPrimitiveToWrapper(Character.class,  Character.TYPE);
+        verifyPrimitiveToWrapper(Boolean  .class,  Boolean  .TYPE);
+        verifyPrimitiveToWrapper(Void     .class,  Void     .TYPE);
+        assertSame(String.class, primitiveToWrapper(String.class));
+    }
+
+    /**
+     * Asserts that calls to {@link Numbers#primitiveToWrapper(Class)} produces the expected
wrapper.
+     * The {@code <N>} parameter type is for making sure that e.g. {@link Integer#TYPE}
has the same
+     * type declaration than {@code Integer.class} despite being different {@link Class}
instances.
+     */
+    private static <N> void verifyPrimitiveToWrapper(final Class<N> wrapper,
final Class<N> primitive) {
+        assertNotSame(wrapper, primitive);
+        assertSame   (wrapper, primitiveToWrapper(primitive));
+        assertSame   (wrapper, primitiveToWrapper(wrapper));
     }
 
     /**
@@ -120,18 +129,27 @@ public final strictfp class NumbersTest extends TestCase {
      */
     @Test
     public void testWrapperToPrimitive() {
-        assertEquals(Byte   .TYPE, wrapperToPrimitive(Byte   .TYPE));
-        assertEquals(Short  .TYPE, wrapperToPrimitive(Short  .TYPE));
-        assertEquals(Integer.TYPE, wrapperToPrimitive(Integer.TYPE));
-        assertEquals(Long   .TYPE, wrapperToPrimitive(Long   .TYPE));
-        assertEquals(Float  .TYPE, wrapperToPrimitive(Float  .TYPE));
-        assertEquals(Double .TYPE, wrapperToPrimitive(Double .TYPE));
-        assertEquals(Byte   .TYPE, wrapperToPrimitive(Byte   .class));
-        assertEquals(Short  .TYPE, wrapperToPrimitive(Short  .class));
-        assertEquals(Integer.TYPE, wrapperToPrimitive(Integer.class));
-        assertEquals(Long   .TYPE, wrapperToPrimitive(Long   .class));
-        assertEquals(Float  .TYPE, wrapperToPrimitive(Float  .class));
-        assertEquals(Double .TYPE, wrapperToPrimitive(Double .class));
+        verifyWrapperToPrimitive(Byte     .TYPE,  Byte     .class);
+        verifyWrapperToPrimitive(Short    .TYPE,  Short    .class);
+        verifyWrapperToPrimitive(Integer  .TYPE,  Integer  .class);
+        verifyWrapperToPrimitive(Long     .TYPE,  Long     .class);
+        verifyWrapperToPrimitive(Float    .TYPE,  Float    .class);
+        verifyWrapperToPrimitive(Double   .TYPE,  Double   .class);
+        verifyWrapperToPrimitive(Character.TYPE,  Character.class);
+        verifyWrapperToPrimitive(Boolean  .TYPE,  Boolean  .class);
+        verifyWrapperToPrimitive(Void     .TYPE,  Void     .class);
+        assertSame(String.class, wrapperToPrimitive(String.class));
+    }
+
+    /**
+     * Asserts that calls to {@link Numbers#wrapperToPrimitive(Class)} produces the expected
wrapper.
+     * The {@code <N>} parameter type is for making sure that e.g. {@link Integer#TYPE}
has the same
+     * type declaration than {@code Integer.class} despite being different {@link Class}
instances.
+     */
+    private static <N> void verifyWrapperToPrimitive(final Class<N> primitive,
final Class<N> wrapper) {
+        assertNotSame(primitive, wrapper);
+        assertSame   (primitive, wrapperToPrimitive(wrapper));
+        assertSame   (primitive, wrapperToPrimitive(primitive));
     }
 
     /**


Mime
View raw message