* 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.
*
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:
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) {
package com.vaadin.data.util.filter;
+import java.math.BigDecimal;
import java.util.Date;
import junit.framework.Assert;
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