aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2016-01-29 14:49:20 +0200
committerTeemu Suo-Anttila <teemusa@vaadin.com>2016-02-01 15:21:13 +0200
commit3b420bdeab5575765345dfdd3994a74a8cc999b2 (patch)
tree1408594ebb3587c9da93ba337c401a60666e5fb5
parent4274350c31bb7bf4c3a8b5672bdac877f75cc069 (diff)
downloadvaadin-framework-3b420bdeab5575765345dfdd3994a74a8cc999b2.tar.gz
vaadin-framework-3b420bdeab5575765345dfdd3994a74a8cc999b2.zip
Add data communication for DataProvider for Collections
After this patch, the object is passed to the client-side as a JsonObject containing a key "k" with value from object.toString() Change-Id: I3f83144a6c84dda9812739ff2f2cb74cb5577d5c
-rw-r--r--client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java31
-rw-r--r--server/src/com/vaadin/server/communication/data/typed/DataProvider.java99
-rw-r--r--shared/src/com/vaadin/shared/data/DataProviderClientRpc.java46
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/dataprovider/DummyDataConnector.java43
4 files changed, 195 insertions, 24 deletions
diff --git a/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java b/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java
index e122787851..bfd0a30ff1 100644
--- a/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java
+++ b/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java
@@ -15,14 +15,17 @@
*/
package com.vaadin.client.connectors.data.typed;
+import java.util.List;
+
import com.vaadin.client.ServerConnector;
-import com.vaadin.client.data.DataSource;
import com.vaadin.client.data.HasDataSource;
import com.vaadin.client.extensions.AbstractExtensionConnector;
import com.vaadin.client.widget.grid.datasources.ListDataSource;
import com.vaadin.server.communication.data.typed.DataProvider;
+import com.vaadin.shared.data.DataProviderClientRpc;
import com.vaadin.shared.ui.Connect;
+import elemental.json.JsonArray;
import elemental.json.JsonObject;
/**
@@ -33,10 +36,33 @@ import elemental.json.JsonObject;
@Connect(DataProvider.class)
public class DataSourceConnector extends AbstractExtensionConnector {
- DataSource<JsonObject> ds = new ListDataSource<JsonObject>();
+ ListDataSource<JsonObject> ds = new ListDataSource<JsonObject>();
@Override
protected void extend(ServerConnector target) {
+ registerRpc(DataProviderClientRpc.class, new DataProviderClientRpc() {
+
+ @Override
+ public void resetSize(long size) {
+ // Server will provide the data we need.
+ ds.asList().clear();
+ }
+
+ @Override
+ public void setData(long firstIndex, JsonArray data) {
+ List<JsonObject> l = ds.asList();
+ assert firstIndex <= l.size() : "Gap in data. First Index: "
+ + firstIndex + ", Size: " + l.size();
+ for (long i = 0; i < data.length(); ++i) {
+ if (i + firstIndex == l.size()) {
+ l.add(data.getObject((int) i));
+ } else if (i + firstIndex < l.size()) {
+ l.set((int) (i + firstIndex), data.getObject((int) i));
+ }
+ }
+ }
+ });
+
ServerConnector parent = getParent();
if (parent instanceof HasDataSource) {
((HasDataSource) parent).setDataSource(ds);
@@ -44,5 +70,4 @@ public class DataSourceConnector extends AbstractExtensionConnector {
assert false : "Parent not implementing HasDataSource";
}
}
-
}
diff --git a/server/src/com/vaadin/server/communication/data/typed/DataProvider.java b/server/src/com/vaadin/server/communication/data/typed/DataProvider.java
index 13755a5ce8..62d39d50ec 100644
--- a/server/src/com/vaadin/server/communication/data/typed/DataProvider.java
+++ b/server/src/com/vaadin/server/communication/data/typed/DataProvider.java
@@ -18,10 +18,13 @@ package com.vaadin.server.communication.data.typed;
import java.util.Collection;
import com.vaadin.server.AbstractExtension;
+import com.vaadin.shared.data.DataProviderClientRpc;
import com.vaadin.shared.data.DataRequestRpc;
import com.vaadin.ui.AbstractComponent;
+import elemental.json.Json;
import elemental.json.JsonArray;
+import elemental.json.JsonObject;
/**
* DataProvider for Collection "container".
@@ -30,6 +33,27 @@ import elemental.json.JsonArray;
*/
public class DataProvider<T> extends AbstractExtension {
+ /**
+ * Simple implementation of collection data provider communication. All data
+ * is sent by server automatically and no data is requested by client.
+ */
+ protected class DataRequestRpcImpl implements DataRequestRpc {
+
+ @Override
+ public void requestRows(int firstRowIndex, int numberOfRows,
+ int firstCachedRowIndex, int cacheSize) {
+ throw new UnsupportedOperationException(
+ "Collection data provider sends all data from server."
+ + " It does not expect client to request anything.");
+ }
+
+ @Override
+ public void dropRows(JsonArray rowKeys) {
+ // FIXME: What should I do with these?
+ }
+
+ }
+
private Collection<T> data;
/**
@@ -45,18 +69,69 @@ public class DataProvider<T> extends AbstractExtension {
this.data = data;
extend(component);
- registerRpc(new DataRequestRpc() {
- @Override
- public void requestRows(int firstRowIndex, int numberOfRows,
- int firstCachedRowIndex, int cacheSize) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- @Override
- public void dropRows(JsonArray rowKeys) {
- throw new UnsupportedOperationException("Not implemented");
- }
- });
+ registerRpc(createRpc());
+ }
+
+ /**
+ * Initially we need to push all the data to the client.
+ *
+ * TODO: The same is true for unknown size changes.
+ */
+ @Override
+ public void beforeClientResponse(boolean initial) {
+ super.beforeClientResponse(initial);
+
+ if (initial) {
+ getRpcProxy(DataProviderClientRpc.class).resetSize(data.size());
+ pushRows(0, data);
+ }
+ }
+
+ /**
+ * Sends given row range to the client.
+ *
+ * @param firstIndex
+ * first index
+ * @param items
+ * items to send as an iterable
+ */
+ protected void pushRows(long firstIndex, Iterable<T> items) {
+ JsonArray data = Json.createArray();
+
+ int i = 0;
+ for (T item : items) {
+ data.set(i++, getDataObject(item));
+ }
+
+ getRpcProxy(DataProviderClientRpc.class).setData(firstIndex, data);
+ }
+
+ /**
+ * Creates the JsonObject for given item. This method calls all data
+ * generators for this item.
+ *
+ * @param item
+ * item to be made into a json object
+ * @return json object representing the item
+ */
+ protected JsonObject getDataObject(T item) {
+ JsonObject dataObject = Json.createObject();
+
+ dataObject.put("k", item.toString());
+
+ // TODO: Add data generator stuff..
+
+ return dataObject;
+ }
+
+ /**
+ * Creates an instance of DataRequestRpc. By default it is
+ * {@link DataRequestRpcImpl}.
+ *
+ * @return data request rpc implementation
+ */
+ protected DataRequestRpc createRpc() {
+ return new DataRequestRpcImpl();
}
}
diff --git a/shared/src/com/vaadin/shared/data/DataProviderClientRpc.java b/shared/src/com/vaadin/shared/data/DataProviderClientRpc.java
new file mode 100644
index 0000000000..e734d4e818
--- /dev/null
+++ b/shared/src/com/vaadin/shared/data/DataProviderClientRpc.java
@@ -0,0 +1,46 @@
+/*
+ * 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.shared.data;
+
+import com.vaadin.shared.communication.ClientRpc;
+
+import elemental.json.JsonArray;
+
+public interface DataProviderClientRpc extends ClientRpc {
+
+ /**
+ * Sets the size of the client-side DataSource.
+ *
+ * @param size
+ * the new data set size
+ */
+ void resetSize(long size);
+
+ /**
+ * Sets the data of the client-side DataSource to match the given data
+ * starting from given index.
+ * <p>
+ * <strong>Note:</strong> This method will override any existing data in the
+ * range starting from first index with the length of the data array.
+ *
+ * @param firstIndex
+ * first index to update
+ * @param data
+ * array of new data
+ */
+ void setData(long firstIndex, JsonArray data);
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/dataprovider/DummyDataConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/dataprovider/DummyDataConnector.java
index fab7dbe75e..eae615a962 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/dataprovider/DummyDataConnector.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/dataprovider/DummyDataConnector.java
@@ -15,8 +15,8 @@
*/
package com.vaadin.tests.widgetset.client.dataprovider;
-import java.util.logging.Logger;
-
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.vaadin.client.data.DataChangeHandler;
import com.vaadin.client.data.DataSource;
import com.vaadin.client.data.HasDataSource;
import com.vaadin.client.ui.AbstractComponentConnector;
@@ -30,23 +30,48 @@ import elemental.json.JsonObject;
public class DummyDataConnector extends AbstractComponentConnector implements
HasDataSource {
+ private DataSource<JsonObject> dataSource;
+
@Override
- public VLabel getWidget() {
- return (VLabel) super.getWidget();
+ public FlowPanel getWidget() {
+ return (FlowPanel) super.getWidget();
}
@Override
protected void init() {
super.init();
-
- getWidget().setText("foo");
}
@Override
public void setDataSource(DataSource<JsonObject> ds) {
- Logger.getLogger("foo").warning(
- "I'm not using the data source for anything!");
- // TODO: implement access to data source
+ dataSource = ds;
+ dataSource.setDataChangeHandler(new DataChangeHandler() {
+
+ @Override
+ public void resetDataAndSize(int estimatedNewDataSize) {
+ }
+
+ @Override
+ public void dataUpdated(int firstRowIndex, int numberOfRows) {
+ }
+
+ @Override
+ public void dataRemoved(int firstRowIndex, int numberOfRows) {
+ }
+
+ @Override
+ public void dataAvailable(int firstRowIndex, int numberOfRows) {
+ }
+
+ @Override
+ public void dataAdded(int firstRowIndex, int numberOfRows) {
+ for (int i = 0; i < numberOfRows; ++i) {
+ getWidget().add(
+ new VLabel(dataSource.getRow(i + firstRowIndex)
+ .toJson()));
+ }
+ }
+ });
}
}