aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <teemusa@vaadin.com>2015-11-18 12:35:05 +0100
committerHenri Sara <hesara@vaadin.com>2016-01-15 14:48:52 +0200
commitf22eb521fb5d7778abccbec87d3996774a9ca752 (patch)
tree910913cf85498c8c7779e360012cb46a51bb9adf
parent029f3e59ef23625ef5171705e3fe1d54c7a531c7 (diff)
downloadvaadin-framework-f22eb521fb5d7778abccbec87d3996774a9ca752.tar.gz
vaadin-framework-f22eb521fb5d7778abccbec87d3996774a9ca752.zip
Make RpcDataProviderExtension more generic (#19266)
Change-Id: I3099f2568b70670248983f735aa6cbac46238b34
-rw-r--r--client/src/com/vaadin/client/connectors/GridConnector.java20
-rw-r--r--client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java15
-rw-r--r--client/src/com/vaadin/client/data/HasDataSource.java26
-rw-r--r--server/src/com/vaadin/server/communication/data/RpcDataProviderExtension.java123
-rw-r--r--server/src/com/vaadin/ui/Grid.java33
5 files changed, 99 insertions, 118 deletions
diff --git a/client/src/com/vaadin/client/connectors/GridConnector.java b/client/src/com/vaadin/client/connectors/GridConnector.java
index 90d9d71088..1a50b905de 100644
--- a/client/src/com/vaadin/client/connectors/GridConnector.java
+++ b/client/src/com/vaadin/client/connectors/GridConnector.java
@@ -49,6 +49,8 @@ import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler;
import com.vaadin.client.connectors.RpcDataSourceConnector.DetailsListener;
import com.vaadin.client.connectors.RpcDataSourceConnector.RpcDataSource;
import com.vaadin.client.ui.AbstractComponentConnector;
+import com.vaadin.client.data.DataSource;
+import com.vaadin.client.data.HasDataSource;
import com.vaadin.client.ui.AbstractHasComponentsConnector;
import com.vaadin.client.ui.ConnectorFocusAndBlurHandler;
import com.vaadin.client.ui.SimpleManagedLayout;
@@ -110,7 +112,7 @@ import elemental.json.JsonValue;
*/
@Connect(com.vaadin.ui.Grid.class)
public class GridConnector extends AbstractHasComponentsConnector implements
- SimpleManagedLayout, DeferredWorker {
+ SimpleManagedLayout, DeferredWorker, HasDataSource<JsonObject> {
private static final class CustomStyleGenerator implements
CellStyleGenerator<JsonObject>, RowStyleGenerator<JsonObject> {
@@ -1092,11 +1094,6 @@ public class GridConnector extends AbstractHasComponentsConnector implements
}
}
- public void setDataSource(RpcDataSource dataSource) {
- this.dataSource = dataSource;
- getWidget().setDataSource(this.dataSource);
- }
-
private void onSortStateChange() {
List<SortOrder> sortOrder = new ArrayList<SortOrder>();
@@ -1279,4 +1276,15 @@ public class GridConnector extends AbstractHasComponentsConnector implements
return result.isEmpty() ? null : result;
}
+ @Override
+ public void setDataSource(DataSource<JsonObject> ds) {
+ if (ds instanceof RpcDataSource) {
+ dataSource = (RpcDataSource) ds;
+ getWidget().setDataSource(dataSource);
+ } else {
+ throw new IllegalArgumentException(
+ "Given DataSource is not RpcDataSource");
+ }
+ }
+
}
diff --git a/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java b/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java
index d744bbc1c7..f9f10158ed 100644
--- a/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java
+++ b/client/src/com/vaadin/client/connectors/RpcDataSourceConnector.java
@@ -22,6 +22,7 @@ import java.util.List;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.data.AbstractRemoteDataSource;
+import com.vaadin.client.data.HasDataSource;
import com.vaadin.client.extensions.AbstractExtensionConnector;
import com.vaadin.shared.data.DataProviderRpc;
import com.vaadin.shared.data.DataRequestRpc;
@@ -246,8 +247,16 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector {
@Override
protected void extend(ServerConnector target) {
- GridConnector gridConnector = (GridConnector) target;
- dataSource.setDetailsListener(gridConnector.getDetailsListener());
- gridConnector.setDataSource(dataSource);
+ if (target instanceof HasDataSource) {
+ ((HasDataSource<JsonObject>) target).setDataSource(dataSource);
+ } else {
+ throw new IllegalArgumentException(
+ "Parent connector does not implement HasDataSource");
+ }
+
+ if (target instanceof GridConnector) {
+ dataSource.setDetailsListener(((GridConnector) target)
+ .getDetailsListener());
+ }
}
}
diff --git a/client/src/com/vaadin/client/data/HasDataSource.java b/client/src/com/vaadin/client/data/HasDataSource.java
new file mode 100644
index 0000000000..97e52b2d94
--- /dev/null
+++ b/client/src/com/vaadin/client/data/HasDataSource.java
@@ -0,0 +1,26 @@
+/*
+ * 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.client.data;
+
+/**
+ * Interface describing a class that supports setting a {@link DataSource}.
+ *
+ * @since
+ */
+public interface HasDataSource<T> {
+
+ public void setDataSource(DataSource<T> ds);
+}
diff --git a/server/src/com/vaadin/server/communication/data/RpcDataProviderExtension.java b/server/src/com/vaadin/server/communication/data/RpcDataProviderExtension.java
index 1b78ca4518..a6cecbb99d 100644
--- a/server/src/com/vaadin/server/communication/data/RpcDataProviderExtension.java
+++ b/server/src/com/vaadin/server/communication/data/RpcDataProviderExtension.java
@@ -26,7 +26,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import com.vaadin.data.Container;
import com.vaadin.data.Container.Indexed;
import com.vaadin.data.Container.Indexed.ItemAddEvent;
import com.vaadin.data.Container.Indexed.ItemRemoveEvent;
@@ -53,11 +52,8 @@ import elemental.json.JsonArray;
import elemental.json.JsonObject;
/**
- * Provides Vaadin server-side container data source to a
- * {@link com.vaadin.client.ui.grid.GridConnector}. This is currently
- * implemented as an Extension hardcoded to support a specific connector type.
- * This will be changed once framework support for something more flexible has
- * been implemented.
+ * Provides Vaadin server-side container data source to a connector implementing
+ * {@link com.vaadin.client.data.HasDataSource}.
*
* @since 7.4
* @author Vaadin Ltd
@@ -71,7 +67,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
*/
private class ActiveItemHandler implements Serializable, DataGenerator {
- private final Map<Object, GridValueChangeListener> activeItemMap = new HashMap<Object, GridValueChangeListener>();
+ private final Map<Object, DataProviderValueChangeListener> activeItemMap = new HashMap<Object, DataProviderValueChangeListener>();
private final KeyMapper<Object> keyMapper = new KeyMapper<Object>();
private final Set<Object> droppedItems = new HashSet<Object>();
@@ -87,8 +83,9 @@ public class RpcDataProviderExtension extends AbstractExtension {
public void addActiveItems(Collection<?> itemIds) {
for (Object itemId : itemIds) {
if (!activeItemMap.containsKey(itemId)) {
- activeItemMap.put(itemId, new GridValueChangeListener(
- itemId, container.getItem(itemId)));
+ activeItemMap.put(itemId,
+ new DataProviderValueChangeListener(itemId,
+ container.getItem(itemId)));
}
}
@@ -125,8 +122,9 @@ public class RpcDataProviderExtension extends AbstractExtension {
*
* @return collection of value change listeners
*/
- public Collection<GridValueChangeListener> getValueChangeListeners() {
- return new HashSet<GridValueChangeListener>(activeItemMap.values());
+ public Collection<DataProviderValueChangeListener> getValueChangeListeners() {
+ return new HashSet<DataProviderValueChangeListener>(
+ activeItemMap.values());
}
@Override
@@ -141,7 +139,8 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
private void removeListener(Object itemId) {
- GridValueChangeListener removed = activeItemMap.remove(itemId);
+ DataProviderValueChangeListener removed = activeItemMap
+ .remove(itemId);
if (removed != null) {
removed.removeListener();
@@ -150,10 +149,9 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
/**
- * A class to listen to changes in property values in the Container added
- * with {@link Grid#setContainerDatasource(Container.Indexed)}, and notifies
- * the data source to update the client-side representation of the modified
- * item.
+ * A class to listen to changes in property values in the Container, and
+ * notifies the data source to update the client-side representation of the
+ * modified item.
* <p>
* One instance of this class can (and should) be reused for all the
* properties in an item, since this class will inform that the entire row
@@ -163,15 +161,13 @@ public class RpcDataProviderExtension extends AbstractExtension {
* Since there's no Container-wide possibility to listen to any kind of
* value changes, an instance of this class needs to be attached to each and
* every Item's Property in the container.
- *
- * @see Grid#addValueChangeListener(Container, Object, Object)
- * @see Grid#valueChangeListeners
*/
- private class GridValueChangeListener implements ValueChangeListener {
+ private class DataProviderValueChangeListener implements
+ ValueChangeListener {
private final Object itemId;
private final Item item;
- public GridValueChangeListener(Object itemId, Item item) {
+ public DataProviderValueChangeListener(Object itemId, Item item) {
/*
* Using an assert instead of an exception throw, just to optimize
* prematurely
@@ -180,7 +176,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
this.itemId = itemId;
this.item = item;
- internalAddColumns(getGrid().getColumns());
+ internalAddProperties();
}
@Override
@@ -189,18 +185,22 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
public void removeListener() {
- removeColumns(getGrid().getColumns());
+ for (final Object propertyId : item.getItemPropertyIds()) {
+ Property<?> property = item.getItemProperty(propertyId);
+ if (property instanceof ValueChangeNotifier) {
+ ((ValueChangeNotifier) property)
+ .removeValueChangeListener(this);
+ }
+ }
}
public void addColumns(Collection<Column> addedColumns) {
- internalAddColumns(addedColumns);
updateRowData(itemId);
}
- private void internalAddColumns(Collection<Column> addedColumns) {
- for (final Column column : addedColumns) {
- final Property<?> property = item.getItemProperty(column
- .getPropertyId());
+ private void internalAddProperties() {
+ for (final Object propertyId : item.getItemPropertyIds()) {
+ Property<?> property = item.getItemProperty(propertyId);
if (property instanceof ValueChangeNotifier) {
((ValueChangeNotifier) property)
.addValueChangeListener(this);
@@ -209,14 +209,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
public void removeColumns(Collection<Column> removedColumns) {
- for (final Column column : removedColumns) {
- final Property<?> property = item.getItemProperty(column
- .getPropertyId());
- if (property instanceof ValueChangeNotifier) {
- ((ValueChangeNotifier) property)
- .removeValueChangeListener(this);
- }
- }
+
}
}
@@ -321,11 +314,10 @@ public class RpcDataProviderExtension extends AbstractExtension {
public void beforeClientResponse(boolean initial) {
if (initial || bareItemSetTriggeredSizeChange) {
/*
- * Push initial set of rows, assuming Grid will initially be
- * rendered scrolled to the top and with a decent amount of rows
- * visible. If this guess is right, initial data can be shown
- * without a round-trip and if it's wrong, the data will simply be
- * discarded.
+ * Push initial set of rows, assuming the component will initially
+ * be rendering the first items in DataSource. If this guess is
+ * right, initial data can be shown without a round-trip and if it's
+ * wrong, the data will simply be discarded.
*/
int size = container.size();
rpc.resetDataAndSize(size);
@@ -380,15 +372,14 @@ public class RpcDataProviderExtension extends AbstractExtension {
Item item = container.getItem(itemId);
- rows.set(i, getRowData(getGrid().getColumns(), itemId, item));
+ rows.set(i, getRowData(itemId, item));
}
rpc.setRowData(firstRowToPush, rows);
activeItemHandler.addActiveItems(itemIds);
}
- private JsonObject getRowData(Collection<Column> columns, Object itemId,
- Item item) {
+ private JsonObject getRowData(Object itemId, Item item) {
final JsonObject rowObject = Json.createObject();
for (DataGenerator dg : dataGenerators) {
@@ -511,14 +502,13 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
Collection<Object> activeItemIds = activeItemHandler.getActiveItemIds();
- List<Column> columns = getGrid().getColumns();
JsonArray rowData = Json.createArray();
int i = 0;
for (Object itemId : itemIds) {
if (activeItemIds.contains(itemId)) {
Item item = container.getItem(itemId);
if (item != null) {
- JsonObject row = getRowData(columns, itemId, item);
+ JsonObject row = getRowData(itemId, item);
rowData.set(i++, row);
}
}
@@ -547,10 +537,8 @@ public class RpcDataProviderExtension extends AbstractExtension {
.removeItemSetChangeListener(itemListener);
}
- } else if (!(parent instanceof Grid)) {
- throw new IllegalStateException(
- "Grid is the only accepted parent type");
}
+
super.setParent(parent);
}
@@ -568,44 +556,7 @@ public class RpcDataProviderExtension extends AbstractExtension {
}
}
- /**
- * Informs this data provider that given columns have been removed from
- * grid.
- *
- * @param removedColumns
- * a list of removed columns
- */
- public void columnsRemoved(List<Column> removedColumns) {
- for (GridValueChangeListener l : activeItemHandler
- .getValueChangeListeners()) {
- l.removeColumns(removedColumns);
- }
-
- // No need to resend unchanged data. Client will remember the old
- // columns until next set of rows is sent.
- }
-
- /**
- * Informs this data provider that given columns have been added to grid.
- *
- * @param addedColumns
- * a list of added columns
- */
- public void columnsAdded(List<Column> addedColumns) {
- for (GridValueChangeListener l : activeItemHandler
- .getValueChangeListeners()) {
- l.addColumns(addedColumns);
- }
-
- // Resend all rows to contain new data.
- refreshCache();
- }
-
public KeyMapper<Object> getKeyMapper() {
return activeItemHandler.keyMapper;
}
-
- protected Grid getGrid() {
- return (Grid) getParent();
- }
}
diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java
index 0774afd582..10b5e84150 100644
--- a/server/src/com/vaadin/ui/Grid.java
+++ b/server/src/com/vaadin/ui/Grid.java
@@ -4423,29 +4423,22 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
.getContainerPropertyIds());
// Find columns that need to be removed.
- List<Column> removedColumns = new LinkedList<Column>();
- for (Object propertyId : columns.keySet()) {
- if (!properties.contains(propertyId)) {
- removedColumns.add(getColumn(propertyId));
- }
- }
+ List<Object> removedProperties = new LinkedList<Object>(
+ columns.keySet());
+ removedProperties.removeAll(properties);
// Actually remove columns.
- for (Column column : removedColumns) {
- Object propertyId = column.getPropertyId();
+ for (Object propertyId : removedProperties) {
internalRemoveColumn(propertyId);
columnKeys.remove(propertyId);
}
- datasourceExtension.columnsRemoved(removedColumns);
// Add new columns
- List<Column> addedColumns = new LinkedList<Column>();
for (Object propertyId : properties) {
if (!columns.containsKey(propertyId)) {
- addedColumns.add(appendColumn(propertyId));
+ appendColumn(propertyId);
}
}
- datasourceExtension.columnsAdded(addedColumns);
if (getFrozenColumnCount() > columns.size()) {
setFrozenColumnCount(columns.size());
@@ -4462,6 +4455,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
}
}
+
+ // Update all rows.
+ datasourceExtension.refreshCache();
}
};
@@ -4480,13 +4476,6 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
*/
private SelectionModel selectionModel;
- /**
- * Used to know whether selection change events originate from the server or
- * the client so the selection change handler knows whether the changes
- * should be sent to the client.
- */
- private boolean applyingSelectionFromClient;
-
private final Header header = new Header(this);
private final Footer footer = new Footer(this);
@@ -5046,7 +5035,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
Column column = getColumn(propertyId);
List<Column> addedColumns = new ArrayList<Column>();
addedColumns.add(column);
- datasourceExtension.columnsAdded(addedColumns);
+
+ datasourceExtension.refreshCache();
return column;
}
@@ -5110,12 +5100,10 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
* Removes all columns from this Grid.
*/
public void removeAllColumns() {
- List<Column> removed = new ArrayList<Column>(columns.values());
Set<Object> properties = new HashSet<Object>(columns.keySet());
for (Object propertyId : properties) {
removeColumn(propertyId);
}
- datasourceExtension.columnsRemoved(removed);
}
/**
@@ -5236,7 +5224,6 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
List<Column> removed = new ArrayList<Column>();
removed.add(getColumn(propertyId));
internalRemoveColumn(propertyId);
- datasourceExtension.columnsRemoved(removed);
}
private void internalRemoveColumn(Object propertyId) {