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 29ab2c8a4470bb677bbd4a370a616f600eda3063
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Sat Jul 16 18:26:43 2022 +0200

    Remove the `if (quantity instanceof Scalar)` special case in `Quantities` 
because it add conversions on top of conversions already done.
    Documentation updates related to units of measurement.
---
 .../apache/sis/internal/util/SetOfUnknownSize.java |  4 +--
 .../java/org/apache/sis/measure/Quantities.java    | 38 ++++++++++------------
 .../org/apache/sis/measure/QuantityFormat.java     | 13 +++-----
 .../java/org/apache/sis/measure/UnitFormat.java    |  2 --
 .../java/org/apache/sis/measure/UnitServices.java  |  2 +-
 .../main/java/org/apache/sis/measure/Units.java    |  3 --
 6 files changed, 25 insertions(+), 37 deletions(-)

diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/internal/util/SetOfUnknownSize.java
 
b/core/sis-utility/src/main/java/org/apache/sis/internal/util/SetOfUnknownSize.java
index be3fcda9f4..399bdf67e3 100644
--- 
a/core/sis-utility/src/main/java/org/apache/sis/internal/util/SetOfUnknownSize.java
+++ 
b/core/sis-utility/src/main/java/org/apache/sis/internal/util/SetOfUnknownSize.java
@@ -68,8 +68,8 @@ public abstract class SetOfUnknownSize<E> extends 
AbstractSet<E> {
 
     /**
      * Returns the number of elements in this set. The default implementation 
counts the number of elements
-     * returned by the {@link #iterator() iterator}. Subclasses are encouraged 
to cache this value if they
-     * know that the underlying storage is immutable.
+     * returned by the {@linkplain #iterator() iterator}. Subclasses are 
encouraged to cache this value
+     * if they know that the underlying storage is immutable.
      *
      * @return the number of elements in this set.
      */
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java 
b/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java
index 3c47d6242d..f798ca6a74 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java
@@ -42,7 +42,7 @@ import org.apache.sis.util.resources.Errors;
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.3
  * @since   0.8
  * @module
  */
@@ -218,25 +218,23 @@ public final class Quantities extends Static {
         Number v2 = u2.getConverterTo(s2).convert(q2.getValue());
         if (Numbers.isNaN(v2)) return q1;
         if (Numbers.isNaN(v1)) return q2;
-        /*
-         * If the two types are instances of `Scalar`, we can compare them 
directly. Otherwise convert the
-         * `Scalar` type (if any) to `Double` type, then convert again to the 
widest type of both values.
-         */
-        final boolean t1 = (v1 instanceof Scalar);
-        final boolean t2 = (v2 instanceof Scalar);
-        if (!(t1 & t2)) {
-            if (t1) v1 = v1.doubleValue();
-            if (t2) v2 = v2.doubleValue();
-            final Class<? extends Number> type = Numbers.widestClass(v1, v2);
-            v1 = Numbers.cast(v1, type);
-            v2 = Numbers.cast(v2, type);
-        }
-        /*
-         * Both v1 and v2 are instance of `Comparable<?>` because 
`Numbers.widestClass(…)`
-         * accepts only known number types such as `Integer`, `Float`, 
`BigDecimal`, etc.
-         */
-        @SuppressWarnings("unchecked")
-        final int c = ((Comparable) v1).compareTo((Comparable) v2);
+        final int c = compare(v1, v2);
         return (max ? c >= 0 : c <= 0) ? q1 : q2;
     }
+
+    /**
+     * Compares the two given number, without casting to {@code double} if we 
can avoid that cast.
+     * The intent is to avoid loosing precision for example by casting a 
{@code BigDecimal}.
+     */
+    @SuppressWarnings("unchecked")
+    private static int compare(final Number v1, final Number v2) {
+        if (v1 instanceof Comparable<?>) {
+            if (v1.getClass().isInstance(v2)) {
+                return ((Comparable) v1).compareTo(v2);
+            } else if (v2 instanceof Comparable<?> && 
v2.getClass().isInstance(v1)) {
+                return -((Comparable) v2).compareTo(v1);
+            }
+        }
+        return Double.compare(v1.doubleValue(), v2.doubleValue());
+    }
 }
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java 
b/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java
index 9060ccf455..b727122486 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/QuantityFormat.java
@@ -24,6 +24,7 @@ import java.text.ParsePosition;
 import javax.measure.Quantity;
 import javax.measure.Unit;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.internal.util.FinalFieldSetter;
 
 
 /**
@@ -130,16 +131,10 @@ public class QuantityFormat extends Format {
     public QuantityFormat clone() {
         final QuantityFormat clone = (QuantityFormat) super.clone();
         try {
-            java.lang.reflect.Field field;
-            field = QuantityFormat.class.getField("numberFormat");
-            field.setAccessible(true);
-            field.set(clone, numberFormat.clone());
-
-            field = QuantityFormat.class.getField("unitFormat");
-            field.setAccessible(true);
-            field.set(clone, unitFormat.clone());
+            FinalFieldSetter.set(QuantityFormat.class, "numberFormat", 
"unitFormat",
+                                 clone, numberFormat.clone(), 
unitFormat.clone());
         } catch (ReflectiveOperationException e) {
-            throw new AssertionError(e);
+            throw FinalFieldSetter.cloneFailure(e);
         }
         return clone;
     }
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java 
b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
index d5df26e825..73ca72bff9 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitFormat.java
@@ -68,8 +68,6 @@ import static java.util.logging.Logger.getLogger;
  * The attributes in netCDF files often merge the axis direction with the 
angular unit,
  * as in {@code "degrees_east"}, {@code "degrees_north"} or {@code "Degrees 
North"}.
  * This class ignores those suffixes and unconditionally returns {@link 
Units#DEGREE} for all axis directions.
- * In particular, the units for {@code "degrees_west"} and {@code 
"degrees_east"} do <strong>not</strong> have
- * opposite sign. It is caller responsibility to handle the direction of axes 
associated to netCDF units.
  *
  * <h2>Multi-threading</h2>
  * {@code UnitFormat} is generally not thread-safe. If units need to be parsed 
or formatted in different threads,
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java 
b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java
index 386e114762..0c615ea354 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java
@@ -46,7 +46,7 @@ import static java.util.logging.Logger.getLogger;
  * without direct dependency. A {@code UnitServices} instance can be obtained 
by call to {@link #current()}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.8
  * @module
  */
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java 
b/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
index 0cad26f04f..d2fa3a646f 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
@@ -1709,9 +1709,6 @@ public final class Units extends Static {
      * The attributes in netCDF files often merge the axis direction with the 
angular unit,
      * as in {@code "degrees_east"} or {@code "degrees_north"}. This {@code 
valueOf} method
      * ignores those suffixes and unconditionally returns {@link #DEGREE} for 
all axis directions.
-     * In particular, the units for {@code "degrees_west"} and {@code 
"degrees_east"}
-     * do <strong>not</strong> have opposite sign.
-     * It is caller responsibility to handle the direction of axes associated 
to netCDF units.
      *
      * @param  uom  the symbol to parse, or {@code null}.
      * @return the parsed symbol, or {@code null} if {@code uom} was null.

Reply via email to