diff options
author | Teemu Suo-Anttila <teemusa@vaadin.com> | 2016-01-29 14:49:20 +0200 |
---|---|---|
committer | Teemu Suo-Anttila <teemusa@vaadin.com> | 2016-02-01 15:21:13 +0200 |
commit | 3b420bdeab5575765345dfdd3994a74a8cc999b2 (patch) | |
tree | 1408594ebb3587c9da93ba337c401a60666e5fb5 | |
parent | 4274350c31bb7bf4c3a8b5672bdac877f75cc069 (diff) | |
download | vaadin-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
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())); + } + } + }); } } |