aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2016-07-08 18:30:47 +0300
committerIlia Motornyi <elmot@vaadin.com>2016-07-12 10:41:56 +0000
commitba228972ae734f3f596edb7a2382b0df19a1db9c (patch)
tree99f7e0dbb19ec75e6a8fd4a18a37bccb3829b9fa
parent4f6cdc327b6cfc40d288acd1052c1cf705cce3eb (diff)
downloadvaadin-framework-ba228972ae734f3f596edb7a2382b0df19a1db9c.tar.gz
vaadin-framework-ba228972ae734f3f596edb7a2382b0df19a1db9c.zip
Simplify DataSource to be a function that provides Stream of values
This patch also removes the old automatic update logic. Change-Id: Idb50137eee2592c1acd14ff67f577ad5edbbd2ff
-rw-r--r--server/src/main/java/com/vaadin/tokka/server/communication/data/AbstractDataSource.java97
-rw-r--r--server/src/main/java/com/vaadin/tokka/server/communication/data/DataCommunicator.java91
-rw-r--r--server/src/main/java/com/vaadin/tokka/server/communication/data/DataSource.java69
-rw-r--r--server/src/main/java/com/vaadin/tokka/server/communication/data/InMemoryDataSource.java (renamed from server/src/main/java/com/vaadin/tokka/server/communication/data/ListDataSource.java)38
-rw-r--r--server/src/test/java/com/vaadin/tokka/data/datasource/InMemoryDataSourceTest.java55
-rw-r--r--server/src/test/java/com/vaadin/tokka/data/datasource/ListDataSourceTest.java100
-rw-r--r--server/src/test/java/com/vaadin/tokka/ui/components/AbstractListingTest.java25
-rw-r--r--uitest/src/main/java/com/vaadin/tokka/tests/components/ListingTestUI.java5
8 files changed, 92 insertions, 388 deletions
diff --git a/server/src/main/java/com/vaadin/tokka/server/communication/data/AbstractDataSource.java b/server/src/main/java/com/vaadin/tokka/server/communication/data/AbstractDataSource.java
deleted file mode 100644
index 4e2bfbf6bf..0000000000
--- a/server/src/main/java/com/vaadin/tokka/server/communication/data/AbstractDataSource.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2000-2014 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.vaadin.tokka.server.communication.data;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import com.vaadin.tokka.event.Registration;
-
-/**
- * Base class for AbstractDataSource. Provides tracking for
- * {@link DataChangeHandler}s and helper methods to call them.
- *
- * @since
- */
-public abstract class AbstractDataSource<T> implements DataSource<T> {
-
- protected final Set<DataChangeHandler<T>> handlers = new LinkedHashSet<DataChangeHandler<T>>();
-
- @Override
- public Registration addDataChangeHandler(DataChangeHandler<T> handler) {
- if (handler != null) {
- handlers.add(handler);
- return () -> handlers.remove(handler);
- }
- return () -> { /* NO-OP */ };
- }
-
- /**
- * Informs all handlers of a generic change in the data. This usually
- * triggers a full cache invalidation and refresh of all data, which is
- * usually an expensive operation. Should be called when none of the other
- * methods help.
- *
- * @see #fireDataAppend(Object)
- * @see #fireDataRemove(Object)
- * @see #fireDataUpdate(Object)
- */
- protected void fireDataChange() {
- for (DataChangeHandler<T> handler : handlers) {
- handler.onDataChange();
- }
- }
-
- /**
- * Informs all handlers of an added data object in the back end. This method
- * should only be called when the newly added data object is the last object
- * in the back end. Other additions can be handled with
- * {@link #fireDataChange()}.
- *
- * @param data
- * added data object
- */
- protected void fireDataAppend(T data) {
- for (DataChangeHandler<T> handler : handlers) {
- handler.onDataAppend(data);
- }
- }
-
- /**
- * Informs all handlers of a data object that was removed from the back end.
- *
- * @param data
- * removed data object
- */
- protected void fireDataRemove(T data) {
- for (DataChangeHandler<T> handler : handlers) {
- handler.onDataRemove(data);
- }
- }
-
- /**
- * Informs all handlers of an existing data object that was updated in the
- * back end.
- *
- * @param data
- * updated data object
- */
- protected void fireDataUpdate(T data) {
- for (DataChangeHandler<T> handler : handlers) {
- handler.onDataUpdate(data);
- }
- }
-}
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 19b4ed8965..0a9e3f34c7 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
@@ -25,7 +25,6 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.vaadin.server.AbstractExtension;
-import com.vaadin.server.ClientConnector;
import com.vaadin.shared.data.DataRequestRpc;
import com.vaadin.shared.data.typed.DataCommunicatorClientRpc;
import com.vaadin.shared.data.typed.DataProviderConstants;
@@ -72,8 +71,8 @@ public class DataCommunicator<T> extends AbstractExtension {
* longer needed. Data tracking is based on key string provided by
* {@link DataKeyMapper}.
* <p>
- * When the {@link DataCommunicator} is pushing new data to the client-side via
- * {@link DataCommunicator#pushData(long, Collection)},
+ * When the {@link DataCommunicator} is pushing new data to the client-side
+ * via {@link DataCommunicator#pushData(long, Collection)},
* {@link #addActiveData(Collection)} and {@link #cleanUp(Collection)} are
* called with the same parameter. In the clean up method any dropped data
* objects that are not in the given collection will be cleaned up and
@@ -173,8 +172,6 @@ public class DataCommunicator<T> extends AbstractExtension {
protected DataCommunicatorClientRpc rpc;
protected DataSource<T> dataSource;
- private Registration dataChangeHandler;
- private DetachListener detachListener;
private DataKeyMapper<T> keyMapper;
private boolean reset = false;
@@ -186,8 +183,6 @@ public class DataCommunicator<T> extends AbstractExtension {
this.dataSource = dataSource;
rpc = getRpcProxy(DataCommunicatorClientRpc.class);
registerRpc(createRpc());
- dataChangeHandler = this.dataSource
- .addDataChangeHandler(createDataChangeHandler());
keyMapper = createKeyMapper();
}
@@ -200,11 +195,13 @@ public class DataCommunicator<T> extends AbstractExtension {
super.beforeClientResponse(initial);
if (initial || reset) {
- rpc.reset(dataSource.size());
+ // FIXME: Rethink the size question.
+ rpc.reset((int) dataSource.apply(null).count());
}
if (!pushRows.isEmpty()) {
- Stream<T> rowsToPush = dataSource.request()
+ // FIXME: Query object
+ Stream<T> rowsToPush = dataSource.apply(null)
.skip(pushRows.getStart()).limit(pushRows.length());
pushData(pushRows.getStart(), rowsToPush);
}
@@ -223,32 +220,6 @@ public class DataCommunicator<T> extends AbstractExtension {
updatedData.clear();
}
- @Override
- public void attach() {
- super.attach();
-
- if (detachListener == null) {
- detachListener = new DetachListener() {
-
- @Override
- public void detach(DetachEvent event) {
- cleanUp();
- }
- };
- getUI().addDetachListener(detachListener);
- }
- }
-
- @Override
- public void setParent(ClientConnector parent) {
- if (getParent() != null && parent == null) {
- // Removing from parent, clean up.
- cleanUp();
- }
-
- super.setParent(parent);
- }
-
/**
* Adds a {@link TypedDataGenerator} to this {@link DataCommunicator}.
*
@@ -341,22 +312,6 @@ public class DataCommunicator<T> extends AbstractExtension {
}
/**
- * Clean up method for removing all listeners attached by the
- * {@link DataCommunicator}. This method is called from {@link #remove()} or
- * when the UI gets detached.
- */
- protected void cleanUp() {
- if (dataSource != null) {
- dataChangeHandler.removeHandler();
- dataChangeHandler = null;
- }
- if (detachListener != null) {
- getUI().removeDetachListener(detachListener);
- detachListener = null;
- }
- }
-
- /**
* Informs the DataProvider that a data object has been added. It is assumed
* to be the last object in the collection.
*
@@ -406,7 +361,7 @@ public class DataCommunicator<T> extends AbstractExtension {
}
/**
- * Creates a {@link DataKeyMapper} to use with this {@link DataCommunicator}.
+ * Creates a {@link DataKeyMapper} to use with this DataCommunicator.
* <p>
* This method is called from the constructor.
*
@@ -426,36 +381,4 @@ public class DataCommunicator<T> extends AbstractExtension {
protected DataRequestRpc createRpc() {
return new SimpleDataRequestRpc();
}
-
- /**
- * Creates a {@link DataChangeHandler} to use with the {@link DataSource}.
- * <p>
- * This method is called from the constructor.
- *
- * @return data change handler
- */
- protected DataChangeHandler<T> createDataChangeHandler() {
- return new DataChangeHandler<T>() {
-
- @Override
- public void onDataChange() {
- reset();
- }
-
- @Override
- public void onDataAppend(T data) {
- add(data);
- }
-
- @Override
- public void onDataRemove(T data) {
- remove(data);
- }
-
- @Override
- public void onDataUpdate(T data) {
- refresh(data);
- }
- };
- }
} \ No newline at end of file
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 ea851a04f7..01257bf755 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
@@ -18,6 +18,7 @@ package com.vaadin.tokka.server.communication.data;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
+import java.util.function.Function;
import java.util.stream.Stream;
import com.vaadin.tokka.event.Registration;
@@ -25,74 +26,40 @@ import com.vaadin.tokka.event.Registration;
/**
* Minimal DataSource API for communication between the DataProvider and a back
* end service.
+ * <p>
+ * FIXME: Missing Query class
*
* @since
* @param <T>
* data type
*/
-public interface DataSource<T> extends Serializable {
+public interface DataSource<T> extends Function<Object, Stream<T>>,
+ Serializable {
/**
- * Requests data from the back end.
- *
- * @return stream of results
- */
- Stream<T> request(/* Query query */);
-
- /**
- * Saves a data object to the back end. If it's a new object, it should be
- * created in the back end. Existing objects with changes should be stored.
- *
- * @param data
- * data object to save
- */
- void save(T data);
-
- /**
- * Removes the given data object from the back end.
- *
- * @param data
- * data object to remove
- */
- void remove(T data);
-
- /**
- * TODO: Decide the fate of the size method.
- *
- * @return size of the data source
- */
- int size();
-
- /**
- * Adds a new DataChangeHandler to this DataSource. DataChangeHandler is
- * called when changes occur in DataSource.
- *
- * @param handler
- * data change handler
- */
- Registration addDataChangeHandler(DataChangeHandler<T> handler);
-
- /**
- * This method creates a new {@link ListDataSource} from a given Collection.
- * The ListDataSource creates a protective List copy of all the contents in
- * the Collection.
+ * 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.
*
* @param data
* collection of data
- * @return list data source
+ * @return in-memory data source
*/
- public static <T> ListDataSource<T> create(Collection<T> data) {
- return new ListDataSource<>(data);
+ public static <T> InMemoryDataSource<T> create(Collection<T> data) {
+ return new InMemoryDataSource<>(data);
}
/**
- * This method creates a new {@link ListDataSource} from given objects.
+ * This method creates a new {@link InMemoryDataSource} from given
+ * objects.The InMemoryDataSource creates a protective List copy of all the
+ * contents in the array.
*
* @param data
* data objects
- * @return list data source
+ * @return in-memory data source
*/
- public static <T> ListDataSource<T> create(T... data) {
- return new ListDataSource<>(Arrays.asList(data));
+ @SafeVarargs
+ public static <T> InMemoryDataSource<T> create(T... data) {
+ return new InMemoryDataSource<>(Arrays.asList(data));
}
} \ No newline at end of file
diff --git a/server/src/main/java/com/vaadin/tokka/server/communication/data/ListDataSource.java b/server/src/main/java/com/vaadin/tokka/server/communication/data/InMemoryDataSource.java
index ab9f84940b..5f743e2ca1 100644
--- a/server/src/main/java/com/vaadin/tokka/server/communication/data/ListDataSource.java
+++ b/server/src/main/java/com/vaadin/tokka/server/communication/data/InMemoryDataSource.java
@@ -18,6 +18,7 @@ package com.vaadin.tokka.server.communication.data;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.function.Function;
import java.util.stream.Stream;
/**
@@ -26,9 +27,10 @@ import java.util.stream.Stream;
* @param <T>
* data type
*/
-public class ListDataSource<T> extends AbstractDataSource<T> {
+public class InMemoryDataSource<T> implements DataSource<T> {
- private List<T> backend;
+ // FIXME: Missing Query object
+ private Function<Object, Stream<T>> request;
/**
* Constructs a new ListDataSource. This method makes a protective copy of
@@ -37,35 +39,13 @@ public class ListDataSource<T> extends AbstractDataSource<T> {
* @param collection
* initial data
*/
- public ListDataSource(Collection<T> collection) {
- backend = new ArrayList<T>(collection);
+ public InMemoryDataSource(Collection<T> collection) {
+ final List<T> backend = new ArrayList<T>(collection);
+ request = query -> backend.stream();
}
@Override
- public void save(T data) {
- if (!backend.contains(data)) {
- backend.add(data);
- fireDataAppend(data);
- } else {
- fireDataUpdate(data);
- }
- }
-
- @Override
- public void remove(T data) {
- if (backend.contains(data)) {
- backend.remove(data);
- fireDataRemove(data);
- }
- }
-
- @Override
- public Stream<T> request() {
- return backend.stream();
- }
-
- @Override
- public int size() {
- return backend.size();
+ public Stream<T> apply(Object query) {
+ return request.apply(query);
}
}
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
new file mode 100644
index 0000000000..092f70b395
--- /dev/null
+++ b/server/src/test/java/com/vaadin/tokka/data/datasource/InMemoryDataSourceTest.java
@@ -0,0 +1,55 @@
+package com.vaadin.tokka.data.datasource;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.tokka.server.communication.data.DataSource;
+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();
+ dataSource = DataSource.create(data);
+ }
+
+ @Test
+ public void testListContainsAllData() {
+ 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;
+ }
+
+}
diff --git a/server/src/test/java/com/vaadin/tokka/data/datasource/ListDataSourceTest.java b/server/src/test/java/com/vaadin/tokka/data/datasource/ListDataSourceTest.java
deleted file mode 100644
index 58a3fa8b48..0000000000
--- a/server/src/test/java/com/vaadin/tokka/data/datasource/ListDataSourceTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.vaadin.tokka.data.datasource;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Stream;
-
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.vaadin.tokka.server.communication.data.DataChangeHandler;
-import com.vaadin.tokka.server.communication.data.DataSource;
-import com.vaadin.tokka.server.communication.data.ListDataSource;
-
-public class ListDataSourceTest {
-
- 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 ListDataSource<StrBean> dataSource;
- private List<StrBean> data;
- private DataChangeHandler<StrBean> handler;
-
- @Before
- public void setUp() {
- data = createData();
- dataSource = DataSource.create(data);
- handler = EasyMock.mock(DataChangeHandler.class);
- }
-
- @Test
- public void testListContainsAllData() {
- EasyMock.replay(handler);
- dataSource.request().forEach(str -> assertTrue(data.contains(str)));
- }
-
- @Test
- public void testListFiresDataAddEvent() {
- StrBean strBean = new StrBean("Spam");
- handler.onDataAppend(strBean);
- EasyMock.expectLastCall().times(1);
- EasyMock.replay(handler);
-
- dataSource.addDataChangeHandler(handler);
- dataSource.save(strBean);
- }
-
- @Test
- public void testListFiresDataRemoveEvent() {
- StrBean strBean = data.get(0);
- handler.onDataRemove(strBean);
- EasyMock.expectLastCall().times(1);
- EasyMock.replay(handler);
-
- dataSource.addDataChangeHandler(handler);
- dataSource.remove(strBean);
- }
-
- @Test
- public void testListFiresDataUpdateEvent() {
- StrBean strBean = data.get(0);
- handler.onDataUpdate(strBean);
- EasyMock.expectLastCall().times(1);
- EasyMock.replay(handler);
-
- dataSource.addDataChangeHandler(handler);
- strBean.setValue("Fuu");
- dataSource.save(strBean);
- }
-
- @After
- public void tearDown() {
- EasyMock.verify(handler);
- }
-
- private List<StrBean> createData() {
- List<StrBean> list = new ArrayList<>();
- Stream.of("Foo", "Bar", "Baz").map(StrBean::new).forEach(list::add);
- return list;
- }
-
-}
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 614e1aba72..242b5519df 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
@@ -2,15 +2,11 @@ package com.vaadin.tokka.ui.components;
import static org.junit.Assert.assertEquals;
-import java.util.stream.Stream;
-
import org.junit.Before;
import org.junit.Test;
-import com.vaadin.tokka.server.communication.data.AbstractDataSource;
import com.vaadin.tokka.server.communication.data.DataCommunicator;
import com.vaadin.tokka.server.communication.data.DataSource;
-import com.vaadin.tokka.ui.components.AbstractListing;
import com.vaadin.tokka.ui.components.AbstractListing.AbstractListingExtension;
import elemental.json.JsonObject;
@@ -49,26 +45,7 @@ public class AbstractListingTest {
@Before
public void setUp() {
- testComponent.setDataSource(new AbstractDataSource<String>() {
-
- @Override
- public void save(String data) {
- }
-
- @Override
- public void remove(String data) {
- }
-
- @Override
- public Stream<String> request() {
- return Stream.of("Foo");
- }
-
- @Override
- public int size() {
- return 1;
- }
- });
+ testComponent.setDataSource(DataSource.create("Foo"));
}
@Test
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 683be11e47..a66ab31fda 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
@@ -62,7 +62,6 @@ public class ListingTestUI extends AbstractTestUI {
.nextInt(100)));
}
return beans;
-
}
}
@@ -82,8 +81,8 @@ public class ListingTestUI extends AbstractTestUI {
.forEach(s -> Notification.show(s))));
hLayout.addComponent(new Button("Random select", e -> {
DataSource<String> ds = select.getDataSource();
- int skip = r.nextInt(ds.size());
- ds.request().skip(skip).findFirst()
+ int skip = r.nextInt((int) ds.apply(null).count());
+ ds.apply(null).skip(skip).findFirst()
.ifPresent(select.getSelectionModel()::select);
}));