--- /dev/null
+package com.vaadin.data.util.filter;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+
+/**
+ * Simple container filter checking whether an item property value is null.
+ *
+ * This filter also directly supports in-memory filtering.
+ *
+ * @since 6.6
+ */
+public final class IsNull implements Filter {
+
+ private final Object propertyId;
+
+ /**
+ * Constructor for a filter that compares the value of an item property with
+ * null.
+ *
+ * For in-memory filtering, a simple == check is performed. For other
+ * containers, the comparison implementation is container dependent but
+ * should correspond to the in-memory null check.
+ *
+ * @param propertyId
+ * the identifier (not null) of the property whose value to check
+ */
+ public IsNull(Object propertyId) {
+ this.propertyId = propertyId;
+ }
+
+ public boolean passesFilter(Object itemId, Item item)
+ throws UnsupportedOperationException {
+ final Property p = item.getItemProperty(getPropertyId());
+ if (null == p) {
+ return false;
+ }
+ return null == p.getValue();
+ }
+
+ public boolean appliesToProperty(Object propertyId) {
+ return this.propertyId == propertyId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ // Only objects of the same class can be equal
+ if (!getClass().equals(obj.getClass())) {
+ return false;
+ }
+ final IsNull o = (IsNull) obj;
+
+ // Checks the properties one by one
+ return (null != getPropertyId()) ? getPropertyId().equals(
+ o.getPropertyId()) : null == o.getPropertyId();
+ }
+
+ @Override
+ public int hashCode() {
+ return (null != getPropertyId() ? getPropertyId().hashCode() : 0);
+ }
+
+ public Object getPropertyId() {
+ return propertyId;
+ }
+
+}
--- /dev/null
+package com.vaadin.tests.server.container.filter;
+
+import junit.framework.Assert;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.ObjectProperty;
+import com.vaadin.data.util.PropertysetItem;
+import com.vaadin.data.util.filter.And;
+import com.vaadin.data.util.filter.IsNull;
+
+public class IsNullFilterTest extends AbstractFilterTest {
+
+ public void testIsNull() {
+ Item item1 = new PropertysetItem();
+ item1.addItemProperty("a", new ObjectProperty<String>(null,
+ String.class));
+ item1.addItemProperty("b",
+ new ObjectProperty<String>("b", String.class));
+ Item item2 = new PropertysetItem();
+ item2.addItemProperty("a",
+ new ObjectProperty<String>("a", String.class));
+ item2.addItemProperty("b", new ObjectProperty<String>(null,
+ String.class));
+
+ Filter filter1 = new IsNull("a");
+ Filter filter2 = new IsNull("b");
+
+ Assert.assertTrue(filter1.passesFilter(null, item1));
+ Assert.assertFalse(filter1.passesFilter(null, item2));
+ Assert.assertFalse(filter2.passesFilter(null, item1));
+ Assert.assertTrue(filter2.passesFilter(null, item2));
+ }
+
+ public void testIsNullEqualsHashCode() {
+ Filter filter1 = new IsNull("a");
+ Filter filter1b = new IsNull("a");
+ Filter filter2 = new IsNull("b");
+
+ // equals()
+ Assert.assertEquals(filter1, filter1b);
+ Assert.assertFalse(filter1.equals(filter2));
+ Assert.assertFalse(filter1.equals(new And()));
+
+ // hashCode()
+ Assert.assertEquals(filter1.hashCode(), filter1b.hashCode());
+ }
+
+}