aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java108
-rw-r--r--server/src/com/vaadin/server/communication/data/typed/DataProvider.java33
-rw-r--r--shared/src/com/vaadin/shared/data/DataProviderClientRpc.java8
3 files changed, 120 insertions, 29 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 a2fc1db8e6..59d72baa67 100644
--- a/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java
+++ b/client/src/com/vaadin/client/connectors/data/typed/DataSourceConnector.java
@@ -15,28 +15,41 @@
*/
package com.vaadin.client.connectors.data.typed;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.vaadin.client.ServerConnector;
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.data.DataProviderConstants;
+import com.vaadin.shared.data.DataRequestRpc;
import com.vaadin.shared.ui.Connect;
+import elemental.json.Json;
import elemental.json.JsonArray;
import elemental.json.JsonObject;
/**
- * A simple connector for DataProvider class.
+ * A simple connector for DataProvider class. Based on {@link ListDataSource}
+ * and does not support lazy loading or paging.
*
* @since
*/
@Connect(DataProvider.class)
public class DataSourceConnector extends AbstractExtensionConnector {
- ListDataSource<JsonObject> ds = new ListDataSource<JsonObject>();
+ private Map<String, JsonObject> keyToJson = new HashMap<String, JsonObject>();
+ private Set<String> droppedKeys = new HashSet<String>();
+ private ListDataSource<JsonObject> ds = new ListDataSource<JsonObject>();
+ private boolean pendingDrop = false;
@Override
protected void extend(ServerConnector target) {
@@ -44,8 +57,12 @@ public class DataSourceConnector extends AbstractExtensionConnector {
@Override
public void resetSize(long size) {
- // Server will provide the data we need.
ds.asList().clear();
+ // Inform the server-side that all keys are now dropped.
+ for (String key : keyToJson.keySet()) {
+ dropKey(key);
+ }
+ sendDroppedKeys();
}
@Override
@@ -54,12 +71,17 @@ public class DataSourceConnector extends AbstractExtensionConnector {
assert firstIndex <= l.size() : "Gap in data. First Index: "
+ firstIndex + ", Size: " + l.size();
for (long i = 0; i < data.length(); ++i) {
+ JsonObject object = data.getObject((int) i);
if (i + firstIndex == l.size()) {
- l.add(data.getObject((int) i));
+ l.add(object);
} else if (i + firstIndex < l.size()) {
- l.set((int) (i + firstIndex), data.getObject((int) i));
+ int index = (int) (i + firstIndex);
+ dropKey(getKey(l.get(index)));
+ l.set(index, object);
}
+ keyToJson.put(getKey(object), object);
}
+ sendDroppedKeys();
}
@Override
@@ -68,13 +90,11 @@ public class DataSourceConnector extends AbstractExtensionConnector {
}
@Override
- public void drop(JsonObject dataObject) {
- List<JsonObject> l = ds.asList();
- for (int i = 0; i < l.size(); ++i) {
- if (l.get(i).toJson().equals(dataObject.toJson())) {
- l.remove(i);
- return;
- }
+ public void drop(String key) {
+ if (keyToJson.containsKey(key)) {
+ ds.asList().remove(keyToJson.get(key));
+ dropKey(key);
+ sendDroppedKeys();
}
}
});
@@ -86,4 +106,68 @@ public class DataSourceConnector extends AbstractExtensionConnector {
assert false : "Parent not implementing HasDataSource";
}
}
+
+ /**
+ * Marks a key as dropped. Call to
+ * {@link DataSourceConnector#sendDroppedKeys()} should be called to make
+ * sure the information is sent to the server-side.
+ *
+ * @param key
+ * dropped key
+ */
+ private void dropKey(String key) {
+ if (keyToJson.containsKey(key)) {
+ droppedKeys.add(key);
+ keyToJson.remove(key);
+ }
+ }
+
+ /**
+ * Sends dropped keys to the server-side with a deferred scheduled command.
+ * Multiple calls to this method will only result to one command being
+ * executed.
+ */
+ private void sendDroppedKeys() {
+ if (pendingDrop) {
+ return;
+ }
+
+ pendingDrop = true;
+ Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+
+ @Override
+ public void execute() {
+ pendingDrop = false;
+ if (droppedKeys.isEmpty()) {
+ return;
+ }
+
+ JsonArray keyArray = Json.createArray();
+ int i = 0;
+ for (String key : droppedKeys) {
+ keyArray.set(i++, key);
+ }
+
+ getRpcProxy(DataRequestRpc.class).dropRows(keyArray);
+
+ // Force RPC since it's delayed.
+ getConnection().getServerRpcQueue().flush();
+
+ droppedKeys.clear();
+ }
+ });
+ }
+
+ /**
+ * Gets the mapping key from given {@link JsonObject}.
+ *
+ * @param jsonObject
+ * json object to get the key from
+ */
+ protected String getKey(JsonObject jsonObject) {
+ if (jsonObject.hasKey(DataProviderConstants.KEY)) {
+ return jsonObject.getString(DataProviderConstants.KEY);
+ }
+ return null;
+ }
}
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 a4e937cbdb..e975792713 100644
--- a/server/src/com/vaadin/server/communication/data/typed/DataProvider.java
+++ b/server/src/com/vaadin/server/communication/data/typed/DataProvider.java
@@ -187,8 +187,13 @@ public class DataProvider<T> extends AbstractExtension {
}
@Override
- public void dropRows(JsonArray rowKeys) {
- // FIXME: What should I do with these?
+ public void dropRows(JsonArray keys) {
+ for (int i = 0; i < keys.length(); ++i) {
+ handler.dropActiveData(keys.getString(i));
+ }
+
+ // Use the whole data as the ones sent to the client.
+ handler.cleanUp(data);
}
}
@@ -328,24 +333,26 @@ public class DataProvider<T> extends AbstractExtension {
}
/**
- * Informs the DataProvider that an item has been added. It is assumed to be
- * the last item in the collection.
+ * Informs the DataProvider that a data object has been added. It is assumed
+ * to be the last object in the collection.
*
- * @param item
- * item added to collection
+ * @param data
+ * data object added to collection
*/
- public void add(T item) {
- rpc.add(getDataObject(item));
+ public void add(T data) {
+ rpc.add(getDataObject(data));
}
/**
- * Informs the DataProvider that an item has been removed.
+ * Informs the DataProvider that a data object has been removed.
*
- * @param item
- * item removed from collection
+ * @param data
+ * data object removed from collection
*/
- public void remove(T item) {
- rpc.drop(getDataObject(item));
+ public void remove(T data) {
+ if (handler.getActiveData().contains(data)) {
+ rpc.drop(getKeyMapper().key(data));
+ }
}
}
diff --git a/shared/src/com/vaadin/shared/data/DataProviderClientRpc.java b/shared/src/com/vaadin/shared/data/DataProviderClientRpc.java
index de23e1c3ed..c96a2a64fa 100644
--- a/shared/src/com/vaadin/shared/data/DataProviderClientRpc.java
+++ b/shared/src/com/vaadin/shared/data/DataProviderClientRpc.java
@@ -59,11 +59,11 @@ public interface DataProviderClientRpc extends ClientRpc {
void add(JsonObject dataObject);
/**
- * Removes data from the client-side DataSource.
+ * Removes data identified by given key from the client-side DataSource.
*
- * @param dataObject
- * single removed data object
+ * @param key
+ * key identifying the object to be removed
*/
- void drop(JsonObject dataObject);
+ void drop(String key);
}