aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2016-07-11 09:02:11 +0300
committerIlia Motornyi <elmot@vaadin.com>2016-07-12 11:02:41 +0000
commita3c0378df7d066cde9b1d321bcd8bf9f26a21b34 (patch)
tree9d4d2a8e49b3e635d879404ccd6f297ba2e60b13
parentba228972ae734f3f596edb7a2382b0df19a1db9c (diff)
downloadvaadin-framework-a3c0378df7d066cde9b1d321bcd8bf9f26a21b34.tar.gz
vaadin-framework-a3c0378df7d066cde9b1d321bcd8bf9f26a21b34.zip
Add basic sorting implementation and API
Change-Id: Ic1fded7f26e3f63c234c6e5bebf8f8fed22e6365
-rw-r--r--server/src/main/java/com/vaadin/tokka/server/communication/data/DataCommunicator.java4
-rw-r--r--server/src/main/java/com/vaadin/tokka/server/communication/data/DataSource.java11
-rw-r--r--server/src/main/java/com/vaadin/tokka/server/communication/data/InMemoryDataSource.java21
-rw-r--r--server/src/main/java/com/vaadin/tokka/ui/components/Listing.java4
-rw-r--r--server/src/main/java/com/vaadin/tokka/ui/components/grid/Grid.java6
-rw-r--r--server/src/main/java/com/vaadin/tokka/ui/components/nativeselect/NativeSelect.java8
-rw-r--r--server/src/test/java/com/vaadin/tokka/data/datasource/InMemoryDataSourceTest.java70
-rw-r--r--server/src/test/java/com/vaadin/tokka/data/datasource/StrBean.java49
-rw-r--r--server/src/test/java/com/vaadin/tokka/ui/components/AbstractListingTest.java6
-rw-r--r--uitest/src/main/java/com/vaadin/tokka/tests/components/ListingTestUI.java6
10 files changed, 142 insertions, 43 deletions
diff --git a/server/src/main/java/com/vaadin/tokka/server/communication/data/DataCommunicator.java b/server/src/main/java/com/vaadin/tokka/server/communication/data/DataCommunicator.java
index 0a9e3f34c7..24cb803306 100644
--- a/server/src/main/java/com/vaadin/tokka/server/communication/data/DataCommunicator.java
+++ b/server/src/main/java/com/vaadin/tokka/server/communication/data/DataCommunicator.java
@@ -171,14 +171,14 @@ public class DataCommunicator<T> extends AbstractExtension {
protected ActiveDataHandler handler = new ActiveDataHandler();
protected DataCommunicatorClientRpc rpc;
- protected DataSource<T> dataSource;
+ protected DataSource<T, ?> dataSource;
private DataKeyMapper<T> keyMapper;
private boolean reset = false;
private final Set<T> updatedData = new HashSet<T>();
private Range pushRows = Range.withLength(0, 40);
- public DataCommunicator(DataSource<T> dataSource) {
+ public DataCommunicator(DataSource<T, ?> dataSource) {
addDataGenerator(handler);
this.dataSource = dataSource;
rpc = getRpcProxy(DataCommunicatorClientRpc.class);
diff --git a/server/src/main/java/com/vaadin/tokka/server/communication/data/DataSource.java b/server/src/main/java/com/vaadin/tokka/server/communication/data/DataSource.java
index 01257bf755..1587200c91 100644
--- a/server/src/main/java/com/vaadin/tokka/server/communication/data/DataSource.java
+++ b/server/src/main/java/com/vaadin/tokka/server/communication/data/DataSource.java
@@ -33,10 +33,19 @@ import com.vaadin.tokka.event.Registration;
* @param <T>
* data type
*/
-public interface DataSource<T> extends Function<Object, Stream<T>>,
+public interface DataSource<T, SORT> extends Function<Object, Stream<T>>,
Serializable {
/**
+ * Sets a default sorting order to the data source.
+ *
+ * @param sortOrder
+ * an object providing the needed sorting information
+ * @return new data source with modified sorting
+ */
+ DataSource<T, SORT> sortingBy(SORT sortOrder);
+
+ /**
* This method creates a new {@link InMemoryDataSource} from a given
* Collection. The InMemoryDataSource creates a protective List copy of all
* the contents in the Collection.
diff --git a/server/src/main/java/com/vaadin/tokka/server/communication/data/InMemoryDataSource.java b/server/src/main/java/com/vaadin/tokka/server/communication/data/InMemoryDataSource.java
index 5f743e2ca1..7b4b84e5b9 100644
--- a/server/src/main/java/com/vaadin/tokka/server/communication/data/InMemoryDataSource.java
+++ b/server/src/main/java/com/vaadin/tokka/server/communication/data/InMemoryDataSource.java
@@ -17,6 +17,7 @@ package com.vaadin.tokka.server.communication.data;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
@@ -27,7 +28,7 @@ import java.util.stream.Stream;
* @param <T>
* data type
*/
-public class InMemoryDataSource<T> implements DataSource<T> {
+public class InMemoryDataSource<T> implements DataSource<T, Comparator<T>> {
// FIXME: Missing Query object
private Function<Object, Stream<T>> request;
@@ -44,8 +45,26 @@ public class InMemoryDataSource<T> implements DataSource<T> {
request = query -> backend.stream();
}
+ /**
+ * Chaining constructor for making modified {@link InMemoryDataSource}s.
+ * This Constructor is used internally for making sorted and filtered
+ * variants of a base data source with actual data.
+ *
+ * @param request
+ * request for the new data source
+ */
+ protected InMemoryDataSource(Function<Object, Stream<T>> request) {
+ this.request = request;
+ }
+
@Override
public Stream<T> apply(Object query) {
return request.apply(query);
}
+
+ @Override
+ public DataSource<T, Comparator<T>> sortingBy(Comparator<T> sortOrder) {
+ return new InMemoryDataSource<T>(q -> request.apply(q)
+ .sorted(sortOrder));
+ }
}
diff --git a/server/src/main/java/com/vaadin/tokka/ui/components/Listing.java b/server/src/main/java/com/vaadin/tokka/ui/components/Listing.java
index 103d7b5b2e..38962c7446 100644
--- a/server/src/main/java/com/vaadin/tokka/ui/components/Listing.java
+++ b/server/src/main/java/com/vaadin/tokka/ui/components/Listing.java
@@ -35,7 +35,7 @@ public interface Listing<T> extends Serializable {
* @param data
* data source
*/
- void setDataSource(DataSource<T> data);
+ void setDataSource(DataSource<T, ?> data);
/**
* Sets the options available for this Listing.
@@ -62,7 +62,7 @@ public interface Listing<T> extends Serializable {
*
* @return data source
*/
- DataSource<T> getDataSource();
+ DataSource<T, ?> getDataSource();
/**
* Gets the {@link SelectionModel} for this Listing.
diff --git a/server/src/main/java/com/vaadin/tokka/ui/components/grid/Grid.java b/server/src/main/java/com/vaadin/tokka/ui/components/grid/Grid.java
index 1d81a0b8a1..3536f7b6e5 100644
--- a/server/src/main/java/com/vaadin/tokka/ui/components/grid/Grid.java
+++ b/server/src/main/java/com/vaadin/tokka/ui/components/grid/Grid.java
@@ -26,7 +26,7 @@ import com.vaadin.tokka.ui.components.AbstractListing;
public class Grid<T> extends AbstractListing<T> {
- private DataSource<T> dataSource;
+ private DataSource<T, ?> dataSource;
private Map<String, Column<T, ?>> columns = new LinkedHashMap<>();
public Grid() {
@@ -34,13 +34,13 @@ public class Grid<T> extends AbstractListing<T> {
}
@Override
- public void setDataSource(DataSource<T> data) {
+ public void setDataSource(DataSource<T, ?> data) {
this.dataSource = data;
setDataCommunicator(new DataCommunicator<>(data));
}
@Override
- public DataSource<T> getDataSource() {
+ public DataSource<T, ?> getDataSource() {
return dataSource;
}
diff --git a/server/src/main/java/com/vaadin/tokka/ui/components/nativeselect/NativeSelect.java b/server/src/main/java/com/vaadin/tokka/ui/components/nativeselect/NativeSelect.java
index dd54016521..0c18f78287 100644
--- a/server/src/main/java/com/vaadin/tokka/ui/components/nativeselect/NativeSelect.java
+++ b/server/src/main/java/com/vaadin/tokka/ui/components/nativeselect/NativeSelect.java
@@ -28,7 +28,7 @@ import elemental.json.JsonObject;
public class NativeSelect<T> extends AbstractListing<T> {
- private DataSource<T> dataSource;
+ private DataSource<T, ?> dataSource;
private Function<T, String> nameProvider = T::toString;
public NativeSelect() {
@@ -47,13 +47,13 @@ public class NativeSelect<T> extends AbstractListing<T> {
});
}
- public NativeSelect(DataSource<T> dataSource) {
+ public NativeSelect(DataSource<T, ?> dataSource) {
this();
setDataSource(dataSource);
}
@Override
- public void setDataSource(DataSource<T> data) {
+ public void setDataSource(DataSource<T, ?> data) {
dataSource = data;
if (dataSource != null) {
setDataCommunicator(new DataCommunicator<>(dataSource));
@@ -63,7 +63,7 @@ public class NativeSelect<T> extends AbstractListing<T> {
}
@Override
- public DataSource<T> getDataSource() {
+ public DataSource<T, ?> getDataSource() {
return dataSource;
}
}
diff --git a/server/src/test/java/com/vaadin/tokka/data/datasource/InMemoryDataSourceTest.java b/server/src/test/java/com/vaadin/tokka/data/datasource/InMemoryDataSourceTest.java
index 092f70b395..bd3c26f540 100644
--- a/server/src/test/java/com/vaadin/tokka/data/datasource/InMemoryDataSourceTest.java
+++ b/server/src/test/java/com/vaadin/tokka/data/datasource/InMemoryDataSourceTest.java
@@ -2,10 +2,11 @@ package com.vaadin.tokka.data.datasource;
import static org.junit.Assert.assertTrue;
-import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
-import java.util.stream.Stream;
+import java.util.stream.Collectors;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -14,30 +15,12 @@ import com.vaadin.tokka.server.communication.data.InMemoryDataSource;
public class InMemoryDataSourceTest {
- private static class StrBean {
-
- private String value;
-
- public StrBean(String value) {
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- }
-
private InMemoryDataSource<StrBean> dataSource;
private List<StrBean> data;
@Before
public void setUp() {
- data = createData();
+ data = StrBean.generateRandomBeans(100);
dataSource = DataSource.create(data);
}
@@ -46,10 +29,47 @@ public class InMemoryDataSourceTest {
dataSource.apply(null).forEach(str -> assertTrue(data.contains(str)));
}
- private List<StrBean> createData() {
- List<StrBean> list = new ArrayList<>();
- Stream.of("Foo", "Bar", "Baz").map(StrBean::new).forEach(list::add);
- return list;
+ @Test
+ public void testSortByComparatorListsDiffer() {
+ Comparator<StrBean> comp = Comparator.comparing(StrBean::getValue)
+ .thenComparing(StrBean::getRandomNumber)
+ .thenComparing(StrBean::getId);
+ List<StrBean> list = dataSource.sortingBy(comp).apply(null)
+ .collect(Collectors.toList());
+
+ // First value in data is { Xyz, 10, 100 } which should be last in list
+ Assert.assertNotEquals("First value should not match", data.get(0),
+ list.get(0));
+
+ data.sort(comp);
+ for (int i = 0; i < data.size(); ++i) {
+ Assert.assertEquals("Sorting result differed", data.get(i),
+ list.get(i));
+ }
}
+ @Test
+ public void testDefatulSortWithSpecifiedPostSort() {
+ Comparator<StrBean> comp = Comparator.comparing(StrBean::getValue)
+ .thenComparing(Comparator.comparing(StrBean::getId).reversed());
+ List<StrBean> list = dataSource.sortingBy(comp).apply(null)
+ // The sort here should come e.g from a Component
+ .sorted(Comparator.comparing(StrBean::getRandomNumber))
+ .collect(Collectors.toList());
+
+ for (int i = 1; i < list.size(); ++i) {
+ StrBean prev = list.get(i - 1);
+ StrBean cur = list.get(i);
+ // Test specific sort
+ Assert.assertTrue(prev.getRandomNumber() <= cur.getRandomNumber());
+
+ if (prev.getRandomNumber() == cur.getRandomNumber()) {
+ // Test default sort
+ Assert.assertTrue(prev.getValue().compareTo(cur.getValue()) <= 0);
+ if (prev.getValue().equals(cur.getValue())) {
+ Assert.assertTrue(prev.getId() > cur.getId());
+ }
+ }
+ }
+ }
}
diff --git a/server/src/test/java/com/vaadin/tokka/data/datasource/StrBean.java b/server/src/test/java/com/vaadin/tokka/data/datasource/StrBean.java
new file mode 100644
index 0000000000..419955f380
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tokka/data/datasource/StrBean.java
@@ -0,0 +1,49 @@
+package com.vaadin.tokka.data.datasource;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+class StrBean implements Serializable {
+
+ private static String[] values = new String[] { "Foo", "Bar", "Baz" };
+
+ private String value;
+ private final int id;
+ private final int randomNumber;
+
+ public StrBean(String value, int id, int randomNumber) {
+ this.value = value;
+ this.id = id;
+ this.randomNumber = randomNumber;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public int getRandomNumber() {
+ return randomNumber;
+ }
+
+ public static List<StrBean> generateRandomBeans(int max) {
+ List<StrBean> data = new ArrayList<StrBean>();
+ Random r = new Random(13337);
+ data.add(new StrBean("Xyz", 10, max));
+ for (int i = 0; i < max - 1; ++i) {
+ data.add(new StrBean(values[r.nextInt(values.length)], i, r
+ .nextInt(10)));
+ }
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ return "{ " + value + ", " + randomNumber + ", " + id + " }";
+ }
+} \ No newline at end of file
diff --git a/server/src/test/java/com/vaadin/tokka/ui/components/AbstractListingTest.java b/server/src/test/java/com/vaadin/tokka/ui/components/AbstractListingTest.java
index 242b5519df..c8051e0b1e 100644
--- a/server/src/test/java/com/vaadin/tokka/ui/components/AbstractListingTest.java
+++ b/server/src/test/java/com/vaadin/tokka/ui/components/AbstractListingTest.java
@@ -29,16 +29,16 @@ public class AbstractListingTest {
AbstractListing<String> testComponent = new AbstractListing<String>() {
- DataSource<String> data;
+ DataSource<String, ?> data;
@Override
- public void setDataSource(DataSource<String> data) {
+ public void setDataSource(DataSource<String, ?> data) {
this.data = data;
setDataCommunicator(new DataCommunicator<>(data));
}
@Override
- public DataSource<String> getDataSource() {
+ public DataSource<String, ?> getDataSource() {
return data;
}
};
diff --git a/uitest/src/main/java/com/vaadin/tokka/tests/components/ListingTestUI.java b/uitest/src/main/java/com/vaadin/tokka/tests/components/ListingTestUI.java
index a66ab31fda..4d2417ab9d 100644
--- a/uitest/src/main/java/com/vaadin/tokka/tests/components/ListingTestUI.java
+++ b/uitest/src/main/java/com/vaadin/tokka/tests/components/ListingTestUI.java
@@ -1,6 +1,7 @@
package com.vaadin.tokka.tests.components;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
import java.util.Random;
@@ -80,7 +81,7 @@ public class ListingTestUI extends AbstractTestUI {
.getSelectionModel().getSelected()
.forEach(s -> Notification.show(s))));
hLayout.addComponent(new Button("Random select", e -> {
- DataSource<String> ds = select.getDataSource();
+ DataSource<String, ?> ds = select.getDataSource();
int skip = r.nextInt((int) ds.apply(null).count());
ds.apply(null).skip(skip).findFirst()
.ifPresent(select.getSelectionModel()::select);
@@ -100,7 +101,8 @@ public class ListingTestUI extends AbstractTestUI {
grid.addColumn("String Value", Bean::getValue);
grid.addColumn("Integer Value", Bean::getIntVal);
grid.addColumn("toString", Bean::toString);
- grid.setDataSource(DataSource.create(Bean.generateRandomBeans()));
+ grid.setDataSource(DataSource.create(Bean.generateRandomBeans())
+ .sortingBy(Comparator.comparing(Bean::getValue)));
addComponent(new Button("Toggle Grid Selection",
new Button.ClickListener() {