]> source.dussan.org Git - vaadin-framework.git/commitdiff
Use compare for Comparable when determining equals for filtering (#10310) 09/309/3
authorArtur Signell <artur@vaadin.com>
Tue, 20 Nov 2012 16:06:57 +0000 (18:06 +0200)
committerVaadin Code Review <review@vaadin.com>
Thu, 22 Nov 2012 11:41:13 +0000 (11:41 +0000)
Change-Id: Ie6e12b1d606d6ed06ae94527427049621b515eed

server/src/com/vaadin/data/util/filter/Compare.java
server/tests/src/com/vaadin/data/util/filter/CompareFilterTest.java

index 7730bace6b746b4920f19df9524e57c4f7790f44..a13a5bfaa76fdb769757986324d2092f472c62c8 100644 (file)
@@ -47,7 +47,8 @@ public abstract class Compare implements Filter {
      * A {@link Compare} filter that accepts items for which the identified
      * property value is equal to <code>value</code>.
      * 
-     * For in-memory filters, equals() is used for the comparison. For other
+     * For in-memory filters, {@link Comparable#compareTo(Object)} or, if not
+     * Comparable, {@link #equals(Object)} is used for the comparison. For other
      * containers, the comparison implementation is container dependent and may
      * use e.g. database comparison operations.
      * 
@@ -248,8 +249,7 @@ public abstract class Compare implements Filter {
         Object value = p.getValue();
         switch (getOperation()) {
         case EQUAL:
-            return (null == this.value) ? (null == value) : this.value
-                    .equals(value);
+            return compareEquals(value);
         case GREATER:
             return compareValue(value) > 0;
         case LESS:
@@ -263,6 +263,29 @@ public abstract class Compare implements Filter {
         return false;
     }
 
+    /**
+     * Checks if the this value equals the given value. Favors Comparable over
+     * equals to better support e.g. BigDecimal where equals is stricter than
+     * compareTo.
+     * 
+     * @param otherValue
+     *            The value to compare to
+     * @return true if the values are equal, false otherwise
+     */
+    private boolean compareEquals(Object otherValue) {
+        if (value == null || otherValue == null) {
+            return (otherValue == value);
+        } else if (value == otherValue) {
+            return true;
+        } else if (value instanceof Comparable
+                && otherValue.getClass()
+                        .isAssignableFrom(getValue().getClass())) {
+            return ((Comparable) value).compareTo(otherValue) == 0;
+        } else {
+            return value.equals(otherValue);
+        }
+    }
+
     @SuppressWarnings({ "unchecked", "rawtypes" })
     protected int compareValue(Object value1) {
         if (null == value) {
index 99e8429a51ed27a127770c9eb88057c4838b0f9b..b7ccd68429e795033f0587932a0ab4ce32914cc5 100644 (file)
@@ -1,5 +1,6 @@
 package com.vaadin.data.util.filter;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 import junit.framework.Assert;
@@ -153,6 +154,59 @@ public class CompareFilterTest extends AbstractFilterTest<Compare> {
         Assert.assertFalse(isNonPositive.passesFilter(null, itemPositive));
     }
 
+    public void testCompareBigDecimal() {
+        BigDecimal negative = new BigDecimal(-1);
+        BigDecimal zero = new BigDecimal(0);
+        BigDecimal positive = new BigDecimal(1);
+        positive.setScale(1);
+        BigDecimal positiveScaleTwo = new BigDecimal(1).setScale(2);
+
+        Item itemNegative = new PropertysetItem();
+        itemNegative.addItemProperty(PROPERTY1, new ObjectProperty<BigDecimal>(
+                negative, BigDecimal.class));
+        Item itemZero = new PropertysetItem();
+        itemZero.addItemProperty(PROPERTY1, new ObjectProperty<BigDecimal>(
+                zero, BigDecimal.class));
+        Item itemPositive = new PropertysetItem();
+        itemPositive.addItemProperty(PROPERTY1, new ObjectProperty<BigDecimal>(
+                positive, BigDecimal.class));
+        Item itemPositiveScaleTwo = new PropertysetItem();
+        itemPositiveScaleTwo.addItemProperty(PROPERTY1,
+                new ObjectProperty<BigDecimal>(positiveScaleTwo,
+                        BigDecimal.class));
+
+        Filter equalZero = new Equal(PROPERTY1, zero);
+        Assert.assertFalse(equalZero.passesFilter(null, itemNegative));
+        Assert.assertTrue(equalZero.passesFilter(null, itemZero));
+        Assert.assertFalse(equalZero.passesFilter(null, itemPositive));
+
+        Filter isPositive = new Greater(PROPERTY1, zero);
+        Assert.assertFalse(isPositive.passesFilter(null, itemNegative));
+        Assert.assertFalse(isPositive.passesFilter(null, itemZero));
+        Assert.assertTrue(isPositive.passesFilter(null, itemPositive));
+
+        Filter isNegative = new Less(PROPERTY1, zero);
+        Assert.assertTrue(isNegative.passesFilter(null, itemNegative));
+        Assert.assertFalse(isNegative.passesFilter(null, itemZero));
+        Assert.assertFalse(isNegative.passesFilter(null, itemPositive));
+
+        Filter isNonNegative = new GreaterOrEqual(PROPERTY1, zero);
+        Assert.assertFalse(isNonNegative.passesFilter(null, itemNegative));
+        Assert.assertTrue(isNonNegative.passesFilter(null, itemZero));
+        Assert.assertTrue(isNonNegative.passesFilter(null, itemPositive));
+
+        Filter isNonPositive = new LessOrEqual(PROPERTY1, zero);
+        Assert.assertTrue(isNonPositive.passesFilter(null, itemNegative));
+        Assert.assertTrue(isNonPositive.passesFilter(null, itemZero));
+        Assert.assertFalse(isNonPositive.passesFilter(null, itemPositive));
+
+        Filter isPositiveScaleTwo = new Equal(PROPERTY1, positiveScaleTwo);
+        Assert.assertTrue(isPositiveScaleTwo.passesFilter(null,
+                itemPositiveScaleTwo));
+        Assert.assertTrue(isPositiveScaleTwo.passesFilter(null, itemPositive));
+
+    }
+
     public void testCompareDate() {
         Date now = new Date();
         // new Date() is only accurate to the millisecond, so repeating it gives