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: I3f83144a6c84dda9812739ff2f2cb74cb5577d5cfeature/databinding
@@ -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"; | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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())); | |||
} | |||
} | |||
}); | |||
} | |||
} |