Browse Source

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
feature/databinding
Teemu Suo-Anttila 8 years ago
parent
commit
3b420bdeab

+ 28
- 3
client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java View File

@@ -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";
}
}

}

+ 87
- 12
server/src/com/vaadin/server/communication/data/typed/DataProvider.java View File

@@ -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();
}

}

+ 46
- 0
shared/src/com/vaadin/shared/data/DataProviderClientRpc.java View File

@@ -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);

}

+ 34
- 9
uitest/src/com/vaadin/tests/widgetset/client/dataprovider/DummyDataConnector.java View File

@@ -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()));
}
}
});
}

}

Loading…
Cancel
Save