diff options
author | Teemu Suo-Anttila <teemusa@vaadin.com> | 2014-09-16 11:25:25 +0300 |
---|---|---|
committer | Johannes Dahlström <johannesd@vaadin.com> | 2014-09-19 12:59:44 +0000 |
commit | b42e8c36888b6f75ecf54e0e83160f08736cdd5c (patch) | |
tree | e47d9aadd9e33806918dc23c802ae3f16a697219 | |
parent | fcb564daacec11992703e4821ae784c0d3b305dd (diff) | |
download | vaadin-framework-b42e8c36888b6f75ecf54e0e83160f08736cdd5c.tar.gz vaadin-framework-b42e8c36888b6f75ecf54e0e83160f08736cdd5c.zip |
Add Container.Filterable to GeneratedPropertyContainer (#13334)
Change-Id: I84b1b649d1b8fc420238953f9d027b5737c5af58
-rw-r--r-- | server/src/com/vaadin/data/util/GeneratedPropertyContainer.java | 82 | ||||
-rw-r--r-- | server/tests/src/com/vaadin/data/util/GeneratedPropertyContainerTest.java | 74 |
2 files changed, 153 insertions, 3 deletions
diff --git a/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java b/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java index 6d008667f7..979f622300 100644 --- a/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java +++ b/server/src/com/vaadin/data/util/GeneratedPropertyContainer.java @@ -17,6 +17,7 @@ package com.vaadin.data.util; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -28,6 +29,7 @@ import com.google.gwt.thirdparty.guava.common.collect.Sets; import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.Property; +import com.vaadin.data.util.filter.UnsupportedFilterException; import com.vaadin.shared.ui.grid.SortDirection; import com.vaadin.ui.components.grid.sort.SortOrder; @@ -38,11 +40,13 @@ import com.vaadin.ui.components.grid.sort.SortOrder; * @author Vaadin Ltd */ public class GeneratedPropertyContainer implements Container.Indexed, - Container.Sortable { + Container.Sortable, Container.Filterable { private final Container.Indexed wrappedContainer; private final Map<Object, PropertyValueGenerator<?>> propertyGenerators; + private final Map<Filter, List<Filter>> activeFilters; private Sortable sortableContainer = null; + private Filterable filterableContainer = null; /** * Property implementation for generated properties @@ -147,6 +151,12 @@ public class GeneratedPropertyContainer implements Container.Indexed, if (wrappedContainer instanceof Sortable) { sortableContainer = (Sortable) wrappedContainer; } + if (wrappedContainer instanceof Filterable) { + activeFilters = new HashMap<Filter, List<Filter>>(); + filterableContainer = (Filterable) wrappedContainer; + } else { + activeFilters = null; + } } /* Functions related to generated properties */ @@ -208,6 +218,73 @@ public class GeneratedPropertyContainer implements Container.Indexed, } } + /* Filtering functionality */ + + @Override + public void addContainerFilter(Filter filter) + throws UnsupportedFilterException { + if (filterableContainer == null) { + throw new UnsupportedOperationException( + "Wrapped container is not filterable"); + } + + List<Filter> addedFilters = new ArrayList<Filter>(); + for (Entry<?, PropertyValueGenerator<?>> entry : propertyGenerators + .entrySet()) { + Object property = entry.getKey(); + if (filter.appliesToProperty(property)) { + // Have generated property modify filter to fit the original + // data in the container. + Filter modifiedFilter = entry.getValue().modifyFilter(filter); + filterableContainer.addContainerFilter(modifiedFilter); + // Keep track of added filters + addedFilters.add(modifiedFilter); + } + } + + if (addedFilters.isEmpty()) { + // No generated property modified this filter, use it as is + addedFilters.add(filter); + filterableContainer.addContainerFilter(filter); + } + // Map filter to actually added filters + activeFilters.put(filter, addedFilters); + } + + @Override + public void removeContainerFilter(Filter filter) { + if (filterableContainer == null) { + throw new UnsupportedOperationException( + "Wrapped container is not filterable"); + } + + if (activeFilters.containsKey(filter)) { + for (Filter f : activeFilters.get(filter)) { + filterableContainer.removeContainerFilter(f); + } + activeFilters.remove(filter); + } + } + + @Override + public void removeAllContainerFilters() { + if (filterableContainer == null) { + throw new UnsupportedOperationException( + "Wrapped container is not filterable"); + } + filterableContainer.removeAllContainerFilters(); + activeFilters.clear(); + } + + @Override + public Collection<Filter> getContainerFilters() { + if (filterableContainer == null) { + throw new UnsupportedOperationException( + "Wrapped container is not filterable"); + } + return Collections.unmodifiableSet(activeFilters.keySet()); + } + /* Sorting functionality */ @Override @@ -236,6 +313,9 @@ public class GeneratedPropertyContainer implements Container.Indexed, } if (propertyGenerators.containsKey(property)) { + // Sorting by a generated property. Generated property should + // modify sort orders to work with original properties in the + // container. for (SortOrder s : propertyGenerators.get(property) .getSortProperties(new SortOrder(property, direction))) { actualSortProperties.add(s.getPropertyId()); diff --git a/server/tests/src/com/vaadin/data/util/GeneratedPropertyContainerTest.java b/server/tests/src/com/vaadin/data/util/GeneratedPropertyContainerTest.java index e78f1295f9..04d08a6f68 100644 --- a/server/tests/src/com/vaadin/data/util/GeneratedPropertyContainerTest.java +++ b/server/tests/src/com/vaadin/data/util/GeneratedPropertyContainerTest.java @@ -18,17 +18,22 @@ package com.vaadin.data.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.junit.Before; import org.junit.Test; +import com.vaadin.data.Container.Filter; import com.vaadin.data.Container.Indexed; import com.vaadin.data.Item; +import com.vaadin.data.util.filter.Compare; +import com.vaadin.data.util.filter.UnsupportedFilterException; import com.vaadin.ui.components.grid.sort.SortOrder; public class GeneratedPropertyContainerTest { GeneratedPropertyContainer container; + private static double MILES_CONVERSION = 0.6214d; @Before public void setUp() { @@ -88,7 +93,7 @@ public class GeneratedPropertyContainerTest { .getItemProperty("baz").getValue()); container.sort(new Object[] { "baz" }, new boolean[] { false }); - assertEquals("foo 9", container.getItem(container.getIdByIndex(0)) + assertEquals("foo 10", container.getItem(container.getIdByIndex(0)) .getItemProperty("baz").getValue()); } @@ -116,16 +121,81 @@ public class GeneratedPropertyContainerTest { assertFalse(container.getSortableContainerPropertyIds().contains("bar")); } + @Test + public void testFilterByMiles() { + container.addGeneratedProperty("miles", + new PropertyValueGenerator<Double>() { + + @Override + public Double getValue(Item item, Object itemId, + Object propertyId) { + return (Double) item.getItemProperty("km").getValue() + * MILES_CONVERSION; + } + + @Override + public Class<Double> getType() { + return Double.class; + } + + @Override + public Filter modifyFilter(Filter filter) + throws UnsupportedFilterException { + if (filter instanceof Compare.LessOrEqual) { + Double value = (Double) ((Compare.LessOrEqual) filter) + .getValue(); + value = value / MILES_CONVERSION; + return new Compare.LessOrEqual("km", value); + } + return super.modifyFilter(filter); + } + }); + + for (Object itemId : container.getItemIds()) { + Item item = container.getItem(itemId); + Double km = (Double) item.getItemProperty("km").getValue(); + Double miles = (Double) item.getItemProperty("miles").getValue(); + assertTrue(miles.equals(km * MILES_CONVERSION)); + } + + Filter filter = new Compare.LessOrEqual("miles", MILES_CONVERSION); + container.addContainerFilter(filter); + for (Object itemId : container.getItemIds()) { + Item item = container.getItem(itemId); + assertTrue("Item did not pass original filter.", + filter.passesFilter(itemId, item)); + } + + assertTrue(container.getContainerFilters().contains(filter)); + container.removeContainerFilter(filter); + assertFalse(container.getContainerFilters().contains(filter)); + + boolean allPass = true; + for (Object itemId : container.getItemIds()) { + Item item = container.getItem(itemId); + if (!filter.passesFilter(itemId, item)) { + allPass = false; + } + } + + if (allPass) { + fail("Removing filter did not introduce any previous filtered items"); + } + } + private Indexed createContainer() { Indexed container = new IndexedContainer(); container.addContainerProperty("foo", String.class, "foo"); container.addContainerProperty("bar", Integer.class, 0); + // km contains double values from 0.0 to 2.0 + container.addContainerProperty("km", Double.class, 0); - for (int i = 0; i < 10; ++i) { + for (int i = 0; i <= 10; ++i) { Object itemId = container.addItem(); Item item = container.getItem(itemId); item.getItemProperty("foo").setValue("foo"); item.getItemProperty("bar").setValue(i); + item.getItemProperty("km").setValue(i / 5.0d); } return container; |