Repository: metamodel
Updated Branches:
  refs/heads/master 0ddd0cdfe -> d8c7056e1


METAMODEL-215: Fixed

Fixes #75

Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo
Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/d8c7056e
Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/d8c7056e
Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/d8c7056e

Branch: refs/heads/master
Commit: d8c7056e1c61860994db7bd77213aae042b03cc3
Parents: 0ddd0cd
Author: Kasper Sørensen <i.am.kasper.soren...@gmail.com>
Authored: Mon Dec 7 14:29:04 2015 +0100
Committer: Kasper Sørensen <i.am.kasper.soren...@gmail.com>
Committed: Mon Dec 7 14:30:08 2015 +0100

----------------------------------------------------------------------
 .../apache/metamodel/util/NumberComparator.java | 200 ++++++++++++-------
 .../metamodel/util/NumberComparatorTest.java    | 111 +++++++++-
 2 files changed, 225 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metamodel/blob/d8c7056e/core/src/main/java/org/apache/metamodel/util/NumberComparator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/util/NumberComparator.java 
b/core/src/main/java/org/apache/metamodel/util/NumberComparator.java
index 4442c65..84c1fd2 100644
--- a/core/src/main/java/org/apache/metamodel/util/NumberComparator.java
+++ b/core/src/main/java/org/apache/metamodel/util/NumberComparator.java
@@ -18,7 +18,11 @@
  */
 package org.apache.metamodel.util;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.Comparator;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -29,79 +33,125 @@ import org.slf4j.LoggerFactory;
  */
 public final class NumberComparator implements Comparator<Object> {
 
-       private static final Logger logger = LoggerFactory
-                       .getLogger(NumberComparator.class);
-
-       private static final Comparator<Object> _instance = new 
NumberComparator();
-
-       public static Comparator<Object> getComparator() {
-               return _instance;
-       }
-
-       private NumberComparator() {
-       }
-
-       public static Comparable<Object> getComparable(Object o) {
-               final Number n = toNumber(o);
-               return new Comparable<Object>() {
-
-                       @Override
-                       public boolean equals(Object obj) {
-                               return _instance.equals(obj);
-                       }
-
-                       public int compareTo(Object o) {
-                               return _instance.compare(n, o);
-                       }
-
-                       @Override
-                       public String toString() {
-                               return "NumberComparable[number=" + n + "]";
-                       }
-
-               };
-       }
-
-       public int compare(Object o1, Object o2) {
-               if (o1 == null && o2 == null) {
-                       return 0;
-               }
-               if (o1 == null) {
-                       return -1;
-               }
-               if (o2 == null) {
-                       return 1;
-               }
-               Number n1 = toNumber(o1);
-               Number n2 = toNumber(o2);
-               return 
Double.valueOf(n1.doubleValue()).compareTo(n2.doubleValue());
-       }
-
-       public static Number toNumber(Object value) {
-               if (value == null) {
-                       return null;
-               } else if (value instanceof Number) {
-                       return (Number) value;
-               } else if (value instanceof Boolean) {
-                       if (Boolean.TRUE.equals(value)) {
-                               return 1;
-                       } else {
-                               return 0;
-                       }
-               } else {
-                       String stringValue = value.toString();
-                       try {
-                               return Integer.parseInt(stringValue);
-                       } catch (NumberFormatException e1) {
-                               try {
-                                       return Double.parseDouble(stringValue);
-                               } catch (NumberFormatException e2) {
-                                       logger.warn(
-                                                       "Could not convert '{}' 
to number, returning null",
-                                                       value);
-                                       return null;
-                               }
-                       }
-               }
-       }
+    private static final Logger logger = 
LoggerFactory.getLogger(NumberComparator.class);
+
+    private static final Comparator<Object> _instance = new NumberComparator();
+
+    public static Comparator<Object> getComparator() {
+        return _instance;
+    }
+
+    private NumberComparator() {
+    }
+
+    public static Comparable<Object> getComparable(Object o) {
+        final Number n = toNumber(o);
+        return new Comparable<Object>() {
+
+            @Override
+            public boolean equals(Object obj) {
+                return _instance.equals(obj);
+            }
+
+            public int compareTo(Object o) {
+                return _instance.compare(n, o);
+            }
+
+            @Override
+            public String toString() {
+                return "NumberComparable[number=" + n + "]";
+            }
+
+        };
+    }
+
+    public int compare(Object o1, Object o2) {
+        final Number n1 = toNumber(o1);
+        final Number n2 = toNumber(o2);
+
+        if (n1 == null && n2 == null) {
+            return 0;
+        }
+        if (n1 == null) {
+            return -1;
+        }
+        if (n2 == null) {
+            return 1;
+        }
+
+        if (n1 instanceof BigInteger && n2 instanceof BigInteger) {
+            return ((BigInteger) n1).compareTo((BigInteger) n2);
+        }
+
+        if (n1 instanceof BigDecimal && n2 instanceof BigDecimal) {
+            return ((BigDecimal) n1).compareTo((BigDecimal) n2);
+        }
+
+        if (isIntegerType(n1) && isIntegerType(n2)) {
+            return Long.valueOf(n1.longValue()).compareTo(n2.longValue());
+        }
+
+        return Double.valueOf(n1.doubleValue()).compareTo(n2.doubleValue());
+    }
+
+    /**
+     * Determines if a particular number is an integer-type number such as
+     * {@link Byte}, {@link Short}, {@link Integer}, {@link Long},
+     * {@link AtomicInteger} or {@link AtomicLong}.
+     * 
+     * Note that {@link BigInteger} is not included in this set of number
+     * classes since treatment of {@link BigInteger} requires different logic.
+     * 
+     * @param n
+     * @return
+     */
+    public static boolean isIntegerType(Number n) {
+        return n instanceof Byte || n instanceof Short || n instanceof Integer 
|| n instanceof Long
+                || n instanceof AtomicInteger || n instanceof AtomicLong;
+    }
+
+    public static Number toNumber(Object value) {
+        if (value == null) {
+            return null;
+        } else if (value instanceof Number) {
+            return (Number) value;
+        } else if (value instanceof Boolean) {
+            if (Boolean.TRUE.equals(value)) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else {
+            final String stringValue = value.toString().trim();
+            if (stringValue.isEmpty()) {
+                return null;
+            }
+
+            try {
+                return Integer.parseInt(stringValue);
+            } catch (NumberFormatException e) {
+            }
+            try {
+                return Long.parseLong(stringValue);
+            } catch (NumberFormatException e) {
+            }
+            try {
+                return Double.parseDouble(stringValue);
+            } catch (NumberFormatException e) {
+            }
+
+            // note: Boolean.parseBoolean does not throw NumberFormatException 
-
+            // it just returns false in case of invalid values.
+            {
+                if ("true".equalsIgnoreCase(stringValue)) {
+                    return 1;
+                }
+                if ("false".equalsIgnoreCase(stringValue)) {
+                    return 0;
+                }
+            }
+            logger.warn("Could not convert '{}' to number, returning null", 
value);
+            return null;
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/metamodel/blob/d8c7056e/core/src/test/java/org/apache/metamodel/util/NumberComparatorTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/metamodel/util/NumberComparatorTest.java 
b/core/src/test/java/org/apache/metamodel/util/NumberComparatorTest.java
index f0f0bcd..e138607 100644
--- a/core/src/test/java/org/apache/metamodel/util/NumberComparatorTest.java
+++ b/core/src/test/java/org/apache/metamodel/util/NumberComparatorTest.java
@@ -18,20 +18,109 @@
  */
 package org.apache.metamodel.util;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
 import java.util.Comparator;
 
-import junit.framework.TestCase;
+import org.junit.Test;
+
+public class NumberComparatorTest {
+
+    @Test
+    public void testDoubleAndIntegerComparison() throws Exception {
+        Comparator<Object> comparator = NumberComparator.getComparator();
+        assertEquals(0, comparator.compare(1, 1.0));
+    }
+
+    @Test
+    public void testComparable() throws Exception {
+        Comparable<Object> comparable = NumberComparator.getComparable("125");
+        assertEquals(0, comparable.compareTo(125));
+        assertEquals(-1, comparable.compareTo(126));
+    }
+
+    @Test
+    public void testToNumberInt() throws Exception {
+        assertEquals(4212, NumberComparator.toNumber("4212"));
+    }
+
+    @Test
+    public void testToNumberLong() throws Exception {
+        assertEquals(4212000000l, NumberComparator.toNumber("4212000000"));
+    }
+
+    @Test
+    public void testToNumberDouble() throws Exception {
+        assertEquals(42.12, NumberComparator.toNumber("42.12"));
+    }
+
+    @Test
+    public void testCompareNull() throws Exception {
+        assertTrue(NumberComparator.getComparator().compare(null, null) == 0);
+        assertTrue(NumberComparator.getComparator().compare(null, "1234") < 0);
+        assertTrue(NumberComparator.getComparator().compare("1234", null) > 0);
+    }
+
+    @Test
+    public void testCompareBoolean() throws Exception {
+        assertTrue(NumberComparator.getComparator().compare("1", "true") == 0);
+        assertTrue(NumberComparator.getComparator().compare("1", "false") > 0);
+        assertTrue(NumberComparator.getComparator().compare("0", "false") == 
0);
+    }
+
+    @Test
+    public void testCompareOneNonConvertableStrings() throws Exception {
+        assertTrue(NumberComparator.getComparator().compare("1", "bar") > 0);
+        assertTrue(NumberComparator.getComparator().compare("foo", "2") < 0);
+    }
+    
+    @Test
+    public void testCompareBothNonConvertableStrings() throws Exception {
+        // odd cases we don't support - but for regression here's some
+        // "documentation" of it's behaviour
+        assertTrue(NumberComparator.getComparator().compare("foo", null) == 0);
+        assertTrue(NumberComparator.getComparator().compare("foo", "bar") == 
0);
+        assertTrue(NumberComparator.getComparator().compare("foo", "") == 0);
+        assertTrue(NumberComparator.getComparator().compare(null, "bar") == 0);
+    }
+
+    @Test
+    public void testCompareBigIntegers() throws Exception {
+        assertTrue(NumberComparator.getComparator().compare(BigInteger.ONE, 
BigInteger.ONE) == 0);
+        assertTrue(NumberComparator.getComparator().compare(BigInteger.ONE, 
BigInteger.TEN) < 0);
+
+        assertTrue(NumberComparator.getComparator().compare(BigInteger.ONE, 
BigInteger.ONE) == 0);
+        assertTrue(NumberComparator.getComparator().compare(new 
BigInteger("-4239842739427492"),
+                new BigInteger("-3239842739427492")) < 0);
+    }
+
+    @Test
+    public void testCompareBigDecimals() throws Exception {
+        assertTrue(NumberComparator.getComparator().compare(BigInteger.ONE, 
BigInteger.ONE) == 0);
+        assertTrue(NumberComparator.getComparator().compare(BigInteger.ONE, 
BigInteger.TEN) < 0);
+
+        assertTrue(NumberComparator.getComparator().compare(BigInteger.ONE, 
BigInteger.ONE) == 0);
+        assertTrue(NumberComparator.getComparator().compare(new 
BigInteger("-4239842739427492"),
+                new BigInteger("-3239842739427492")) < 0);
+    }
 
-public class NumberComparatorTest extends TestCase {
+    @Test
+    public void testCompareIntegers() throws Exception {
+        assertTrue(NumberComparator.getComparator().compare(42, 42) == 0);
+        assertTrue(NumberComparator.getComparator().compare(42, 43) < 0);
+    }
 
-       public void testDoubleAndIntegerComparison() throws Exception {
-               Comparator<Object> comparator = 
NumberComparator.getComparator();
-               assertEquals(0, comparator.compare(1, 1.0));
-       }
+    @Test
+    public void testCompareLongs() throws Exception {
+        assertTrue(NumberComparator.getComparator().compare(42000000000l, 
42000000000l) == 0);
+        assertTrue(NumberComparator.getComparator().compare(42000000000l, 
42000000001l) < 0);
+    }
 
-       public void testComparable() throws Exception {
-               Comparable<Object> comparable = 
NumberComparator.getComparable("125");
-               assertEquals(0, comparable.compareTo(125));
-               assertEquals(-1, comparable.compareTo(126));
-       }
+    @Test
+    public void testCompareDoubles() throws Exception {
+        assertTrue(NumberComparator.getComparator().compare(42.01, 42.01) == 
0);
+        assertTrue(NumberComparator.getComparator().compare(42.01, 42.02) < 0);
+    }
 }
\ No newline at end of file

Reply via email to